mago_allocator/copy.rs
1use crate::arena::Arena;
2
3/// A deep copy of a value into an arena, rebinding every internal reference.
4///
5/// Implementors copy all of their arena-resident data (byte slices, nested
6/// references, slices of children) into the given arena, so the output is
7/// self-contained: it stays valid after the arena the input lived in is
8/// dropped or reset.
9///
10/// ```
11/// use mago_allocator::prelude::*;
12///
13/// struct Name<'arena> {
14/// value: &'arena [u8],
15/// }
16///
17/// impl CopyInto for Name<'_> {
18/// type Output<'arena> = Name<'arena>;
19///
20/// fn copy_into<'arena, A>(&self, arena: &'arena A) -> Self::Output<'arena>
21/// where
22/// A: Arena,
23/// {
24/// Name { value: arena.alloc_slice_copy(self.value) }
25/// }
26/// }
27///
28/// let source = LocalArena::new();
29/// let target = LocalArena::new();
30///
31/// let name = Name { value: source.alloc_slice_copy(b"App\\Collection") };
32/// let copied = name.copy_into(&target);
33/// drop(source);
34///
35/// assert_eq!(copied.value, b"App\\Collection");
36/// ```
37pub trait CopyInto {
38 type Output<'arena>: 'arena;
39
40 fn copy_into<'arena, A>(&self, arena: &'arena A) -> Self::Output<'arena>
41 where
42 A: Arena;
43}
44
45/// Copies `value` into the arena and returns a reference to the copy.
46#[must_use]
47#[inline]
48pub fn copy_ref_into<'arena, T, A>(value: &T, arena: &'arena A) -> &'arena T::Output<'arena>
49where
50 T: CopyInto,
51 A: Arena,
52{
53 arena.alloc(value.copy_into(arena))
54}
55
56/// Copies every element of `values` into the arena as a new slice.
57#[must_use]
58#[inline]
59pub fn copy_slice_into<'arena, T, A>(values: &[T], arena: &'arena A) -> &'arena [T::Output<'arena>]
60where
61 T: CopyInto,
62 A: Arena,
63{
64 arena.alloc_slice_fill_iter(values.iter().map(|value| value.copy_into(arena)))
65}
66
67macro_rules! trivial_copy_into {
68 ($ty:ty) => {
69 impl CopyInto for $ty {
70 type Output<'arena> = $ty;
71
72 fn copy_into<'arena, A>(&self, _arena: &'arena A) -> Self::Output<'arena>
73 where
74 A: Arena,
75 {
76 *self
77 }
78 }
79 };
80 ($($ty:ty),+) => {
81 $(trivial_copy_into!($ty);)+
82 };
83}
84
85trivial_copy_into!((), bool, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);