mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(allocator): introduce CloneIn trait. (#4726)
Introduce the trait discussed in #4284.
This commit is contained in:
parent
e0832f8e18
commit
23b0040c16
2 changed files with 93 additions and 0 deletions
91
crates/oxc_allocator/src/clone_in.rs
Normal file
91
crates/oxc_allocator/src/clone_in.rs
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
use crate::{Allocator, Box, Vec};
|
||||||
|
|
||||||
|
/// A trait to explicitly clone an object into an arena allocator.
|
||||||
|
///
|
||||||
|
/// As a convention `Cloned` associated type should always be the same as `Self`,
|
||||||
|
/// It'd only differ in the lifetime, Here's an example:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Struct<'old_alloc> {
|
||||||
|
/// type Cloned = Struct<'new_alloc>;
|
||||||
|
/// fn clone_in(&self, alloc: &'new_alloc Allocator) -> Self::Cloned {
|
||||||
|
/// Struct { a: self.a.clone_in(alloc), b: self.b.clone_in(alloc) }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Implementations of this trait on non-allocated items usually short-circuit to `Clone::clone`;
|
||||||
|
/// However, it **isn't** guaranteed.
|
||||||
|
///
|
||||||
|
pub trait CloneIn<'new_alloc>: Sized {
|
||||||
|
type Cloned;
|
||||||
|
|
||||||
|
fn clone_in(&self, alloc: &'new_alloc Allocator) -> Self::Cloned;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'alloc, T, C> CloneIn<'alloc> for Option<T>
|
||||||
|
where
|
||||||
|
T: CloneIn<'alloc, Cloned = C>,
|
||||||
|
{
|
||||||
|
type Cloned = Option<C>;
|
||||||
|
fn clone_in(&self, alloc: &'alloc Allocator) -> Self::Cloned {
|
||||||
|
self.as_ref().map(|it| it.clone_in(alloc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'old_alloc, 'new_alloc, T, C> CloneIn<'new_alloc> for Box<'old_alloc, T>
|
||||||
|
where
|
||||||
|
T: CloneIn<'new_alloc, Cloned = C>,
|
||||||
|
{
|
||||||
|
type Cloned = Box<'new_alloc, C>;
|
||||||
|
fn clone_in(&self, alloc: &'new_alloc Allocator) -> Self::Cloned {
|
||||||
|
Box::new_in(self.as_ref().clone_in(alloc), alloc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'old_alloc, 'new_alloc, T, C> CloneIn<'new_alloc> for Vec<'old_alloc, T>
|
||||||
|
where
|
||||||
|
T: CloneIn<'new_alloc, Cloned = C>,
|
||||||
|
{
|
||||||
|
type Cloned = Vec<'new_alloc, C>;
|
||||||
|
fn clone_in(&self, alloc: &'new_alloc Allocator) -> Self::Cloned {
|
||||||
|
Vec::from_iter_in(self.iter().map(|it| it.clone_in(alloc)), alloc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'alloc, T: Copy> CloneIn<'alloc> for Cell<T> {
|
||||||
|
type Cloned = Cell<T>;
|
||||||
|
fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned {
|
||||||
|
Cell::new(self.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for &'old_alloc str {
|
||||||
|
type Cloned = &'new_alloc str;
|
||||||
|
fn clone_in(&self, alloc: &'new_alloc Allocator) -> Self::Cloned {
|
||||||
|
alloc.alloc_str(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_clone_in {
|
||||||
|
($($t:ty)*) => {
|
||||||
|
$(
|
||||||
|
impl<'alloc> CloneIn<'alloc> for $t {
|
||||||
|
type Cloned = Self;
|
||||||
|
#[inline(always)]
|
||||||
|
fn clone_in(&self, _: &'alloc Allocator) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_clone_in! {
|
||||||
|
usize u8 u16 u32 u64 u128
|
||||||
|
isize i8 i16 i32 i64 i128
|
||||||
|
f32 f64
|
||||||
|
bool char
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,13 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
mod arena;
|
mod arena;
|
||||||
|
mod clone_in;
|
||||||
mod convert;
|
mod convert;
|
||||||
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
||||||
pub use arena::{Box, String, Vec};
|
pub use arena::{Box, String, Vec};
|
||||||
|
pub use clone_in::CloneIn;
|
||||||
pub use convert::{FromIn, IntoIn};
|
pub use convert::{FromIn, IntoIn};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue