1#![warn(missing_docs)]
7
8use std::cell::Cell;
9
10pub use bumpalo::Bump;
11pub use typed_arena::Arena as TypedArena;
12
13#[derive(Debug)]
18pub struct Arena {
19 bump: Bump,
20 bytes_allocated: Cell<usize>,
21}
22
23impl Arena {
24 #[must_use]
26 pub fn new() -> Self {
27 Self {
28 bump: Bump::new(),
29 bytes_allocated: Cell::new(0),
30 }
31 }
32
33 #[must_use]
35 pub fn with_capacity(capacity: usize) -> Self {
36 Self {
37 bump: Bump::with_capacity(capacity),
38 bytes_allocated: Cell::new(0),
39 }
40 }
41
42 pub fn alloc<T>(&self, val: T) -> &mut T {
44 self.bytes_allocated
45 .set(self.bytes_allocated.get() + std::mem::size_of::<T>());
46 self.bump.alloc(val)
47 }
48
49 pub fn alloc_slice<T: Copy>(&self, slice: &[T]) -> &mut [T] {
51 self.bytes_allocated
52 .set(self.bytes_allocated.get() + std::mem::size_of_val(slice));
53 self.bump.alloc_slice_copy(slice)
54 }
55
56 pub fn alloc_str(&self, s: &str) -> &str {
58 self.bytes_allocated
59 .set(self.bytes_allocated.get() + s.len());
60 self.bump.alloc_str(s)
61 }
62
63 pub fn alloc_from_iter<T, I>(&self, iter: I) -> &mut [T]
65 where
66 I: IntoIterator<Item = T>,
67 I::IntoIter: ExactSizeIterator,
68 {
69 let result = self.bump.alloc_slice_fill_iter(iter);
70 self.bytes_allocated
71 .set(self.bytes_allocated.get() + std::mem::size_of_val(result));
72 result
73 }
74
75 #[must_use]
77 pub fn bytes_allocated(&self) -> usize {
78 self.bytes_allocated.get()
79 }
80
81 #[must_use]
83 pub fn allocated_bytes_including_metadata(&self) -> usize {
84 self.bump.allocated_bytes()
85 }
86
87 pub unsafe fn reset(&mut self) {
93 self.bump.reset();
94 self.bytes_allocated.set(0);
95 }
96}
97
98impl Default for Arena {
99 fn default() -> Self {
100 Self::new()
101 }
102}
103
104#[derive(Debug)]
109pub struct DroplessArena {
110 bump: Bump,
111}
112
113impl DroplessArena {
114 #[must_use]
116 pub fn new() -> Self {
117 Self { bump: Bump::new() }
118 }
119
120 pub fn alloc<T>(&self, val: T) -> &mut T {
124 self.bump.alloc(val)
125 }
126
127 pub fn alloc_from_iter<T, I>(&self, iter: I) -> &mut [T]
129 where
130 I: IntoIterator<Item = T>,
131 I::IntoIter: ExactSizeIterator,
132 {
133 self.bump.alloc_slice_fill_iter(iter)
134 }
135}
136
137impl Default for DroplessArena {
138 fn default() -> Self {
139 Self::new()
140 }
141}
142
143#[derive(Debug)]
145pub struct SyncArena {
146 bump: parking_lot::Mutex<Bump>,
147}
148
149impl SyncArena {
150 #[must_use]
152 pub fn new() -> Self {
153 Self {
154 bump: parking_lot::Mutex::new(Bump::new()),
155 }
156 }
157
158 pub fn alloc<T: Send>(&self, val: T) -> &T {
160 let bump = self.bump.lock();
163 let ptr = bump.alloc(val) as *const T;
164 unsafe { &*ptr }
165 }
166}
167
168impl Default for SyncArena {
169 fn default() -> Self {
170 Self::new()
171 }
172}
173
174unsafe impl Send for SyncArena {}
176unsafe impl Sync for SyncArena {}
177
178#[cfg(test)]
179mod tests {
180 use super::*;
181
182 #[test]
183 fn test_arena_allocation() {
184 let arena = Arena::new();
185 let x = arena.alloc(42);
186 let y = arena.alloc("hello");
187
188 assert_eq!(*x, 42);
189 assert_eq!(*y, "hello");
190 }
191
192 #[test]
193 fn test_arena_slice() {
194 let arena = Arena::new();
195 let slice = arena.alloc_slice(&[1, 2, 3, 4, 5]);
196
197 assert_eq!(slice, &[1, 2, 3, 4, 5]);
198 }
199
200 #[test]
201 fn test_arena_from_iter() {
202 let arena = Arena::new();
203 let slice = arena.alloc_from_iter(0..5);
204
205 assert_eq!(slice, &[0, 1, 2, 3, 4]);
206 }
207}