1
2pub struct Arena {
3 container: Vec<u8>,
4 capacity: usize,
5 offset: usize,
6}
7
8impl<'a> Arena {
9 pub fn new(size: usize) -> Self {
10 Arena {
11 container: Vec::with_capacity(size),
12 capacity: size,
13 offset: 0,
14 }
15 }
16 pub fn alloc<T>(&mut self, value: T) -> Option<&'a mut T> {
17 let size = std::mem::size_of::<T>();
18 if self.offset + size > self.capacity {
19 return None;
20 }
21 for _ in 0..size {
22 self.container.push(0u8);
23 }
24 let ptr: *mut u8 = &mut self.container[self.offset];
25 let ptr = ptr.cast::<T>();
26 self.offset += size;
27 unsafe {
28 *ptr = value;
29 Some(&mut *ptr)
30 }
31 }
32}
33
34#[test]
35fn single_allocation() {
36 let mut arena = Arena::new(1024);
37 let value = arena.alloc(7).unwrap();
38 assert_eq!(*value, 7);
39}
40
41#[test]
42fn out_of_space() {
43 let mut arena = Arena::new(4);
44 arena.alloc(7).unwrap();
45 let value = arena.alloc(7);
46 assert_eq!(value, None);
47}
48
49#[test]
50fn multiple_allocations() {
51 let mut arena = Arena::new(1024);
52 let value_78 = arena.alloc(78).unwrap();
53 let value_42 = arena.alloc(42).unwrap();
54
55 {
56 let value_17 = arena.alloc(17).unwrap();
57 assert_eq!(*value_17, 17);
58 }
59 assert_eq!(*value_78, 78);
63 assert_eq!(*value_42, 42);
64 assert_eq!(*value_78 + *value_42, 78 + 42);
65
66 }