1use std::marker::PhantomData;
7use std::ptr;
8
9use crate::arena::Arena;
10
11pub struct ArenaRef<T> {
12 offset: usize,
13 _phantom: PhantomData<T>,
14}
15
16unsafe impl<T: Send> Send for ArenaRef<T> {}
17unsafe impl<T: Sync> Sync for ArenaRef<T> {}
18
19impl<T> ArenaRef<T> {
20 pub fn new(arena: &Arena, value: T) -> Option<Self> {
21 let slot = arena.alloc_with(value)?;
22 let offset = unsafe {
23 (slot as *const T as *const u8)
24 .offset_from(arena.base_ptr() as *const u8) as usize
25 };
26
27 Some(ArenaRef {
28 offset,
29 _phantom: PhantomData,
30 })
31 }
32
33 pub unsafe fn from_offset(offset: usize) -> Self {
34 ArenaRef {
35 offset,
36 _phantom: PhantomData,
37 }
38 }
39
40 pub fn offset(&self) -> usize {
41 self.offset
42 }
43
44 pub unsafe fn get<'a>(&self, arena: &'a Arena) -> &'a T {
45 &*(arena.base_ptr().add(self.offset) as *const T)
46 }
47
48 #[allow(clippy::mut_from_ref)]
49 pub unsafe fn get_mut<'a>(&self, arena: &'a Arena) -> &'a mut T {
50 &mut *(arena.base_ptr().add(self.offset) as *mut T)
51 }
52
53 pub unsafe fn write(&self, arena: &Arena, value: T) {
54 ptr::write(self.get_mut(arena), value);
55 }
56
57 pub unsafe fn read(&self, arena: &Arena) -> T
58 where
59 T: Copy,
60 {
61 ptr::read(self.get(arena))
62 }
63}
64
65impl<T> Clone for ArenaRef<T> {
66 fn clone(&self) -> Self {
67 *self
68 }
69}
70
71impl<T> Copy for ArenaRef<T> {}