1#![doc = include_str!("../examples/friends.rs")]
11mod chunk;
14mod dropless;
15mod typed;
16
17pub use dropless::DroplessArena;
18pub use typed::TypedArena;
19
20#[doc(hidden)]
21pub mod markers {
22 pub struct Copy;
23 pub struct NoCopy;
24}
25
26const PAGE_SIZE: usize = 4096;
27const HUGE_PAGE: usize = 2 * 1024 * 1024;
28
29#[macro_export]
30macro_rules! define_arenas {
31 ( $([visibility = $vis:vis ])? $(
32 $name:ident : $ty:ty
33 ),* $(,)?) => {
34
35 $($vis)? struct Arena<'ctx> {
36 dropless: $crate::DroplessArena<'ctx>,
37 $( $name: $crate::TypedArena<'ctx, $ty>,)*
38 }
39
40 impl<'ctx> Arena<'ctx> {
41 $($vis)? fn new() -> Self {
42 Self {
43 dropless: $crate::DroplessArena::default(),
44 $(
45 $name : $crate::TypedArena::default(),
46 )*
47 }
48 }
49
50 $($vis)? fn alloc<T,C>(&self, val: T) -> &'ctx mut T
51 where
52 T: ArenaAllocable<'ctx, C>
53 {
54 val.alloc_into(self)
55 }
56
57 $($vis)? fn alloc_iter<T, I, C>(&self, val: I) -> &'ctx mut [T]
58 where
59 T: ArenaAllocable<'ctx, C>,
60 I: IntoIterator<Item = T>,
61 <I as IntoIterator>::IntoIter: ExactSizeIterator
62 {
63 T::alloc_iter(val, self)
64 }
65 }
66
67 $($vis)? trait ArenaAllocable<'ctx, C = $crate::markers::Copy> : Sized {
68 #[allow(clippy::mut_from_ref)]
69 fn alloc_into(self, arena: &Arena<'ctx>) -> &'ctx mut Self;
70
71 #[allow(clippy::mut_from_ref)]
72 fn alloc_iter<I>(it: I, arena: &Arena<'ctx>) -> &'ctx mut [Self]
73 where
74 I: IntoIterator<Item = Self>,
75 <I as IntoIterator>::IntoIter: ExactSizeIterator;
76 }
77
78 impl<'ctx, T: Copy> ArenaAllocable<'ctx> for T {
79 #[allow(clippy::mut_from_ref)]
80 fn alloc_into(self, arena: &Arena<'ctx>) -> &'ctx mut Self {
81 arena.dropless.alloc(self)
82 }
83
84 #[allow(clippy::mut_from_ref)]
85 fn alloc_iter<I>(it:I, arena: &Arena<'ctx>) -> &'ctx mut [Self]
86 where
87 I:IntoIterator<Item = Self>,
88 <I as IntoIterator>::IntoIter:ExactSizeIterator
89 {
90 arena.dropless.alloc_iter(it)
91 }
92 }
93
94 $(
95 impl<'ctx> ArenaAllocable<'ctx, $crate::markers::NoCopy> for $ty {
96 fn alloc_into(self, arena: &Arena<'ctx>) -> &'ctx mut Self {
97 if !::core::mem::needs_drop::<Self>() {
98 arena.dropless.alloc(self)
99 } else {
100 arena . $name .alloc(self)
101 }
102 }
103
104 fn alloc_iter<I>(it: I, arena: &Arena<'ctx>) -> &'ctx mut [Self]
105 where
106 I: IntoIterator<Item = Self>,
107 <I as IntoIterator>::IntoIter: ExactSizeIterator
108 {
109 if !::core::mem::needs_drop::<Self>() {
110 arena.dropless.alloc_iter(it)
111 } else {
112 arena . $name .alloc_iter(it)
113 }
114 }
115 }
116 )*
117 };
118}
119
120#[cfg(test)]
121mod test;