alloc_from_pool/
pool_value.rs1use std::cell::UnsafeCell;
2use std::ops::Deref;
3
4use crate::{alloc_in::alloc_in, allocations_ptr::allocations_ptr};
5
6pub struct PoolValue<T: 'static> {
7 pub(crate) ptr: *mut T,
8 pub(crate) slots: *const UnsafeCell<Vec<Box<T>>>,
9 #[cfg(test)]
10 pub(crate) allocations: *mut usize,
11}
12
13impl<T> PoolValue<T> {
14 pub fn take_value(&mut self) -> T {
15 let value = *unsafe { Box::from_raw(self.ptr) };
16 self.ptr = std::ptr::null_mut();
17 value
18 }
19}
20
21impl<T> Deref for PoolValue<T> {
22 type Target = T;
23
24 fn deref(&self) -> &Self::Target {
25 unsafe { self.ptr.as_ref().unwrap_unchecked() }
26 }
27}
28
29impl<T> Clone for PoolValue<T>
30where
31 T: Clone,
32{
33 fn clone(&self) -> Self {
34 alloc_in(self.slots, allocations_ptr!(self), self.deref().clone())
35 }
36}
37
38impl<T> PartialEq for PoolValue<T>
39where
40 T: PartialEq,
41{
42 fn eq(&self, other: &Self) -> bool {
43 self.deref() == other.deref()
44 }
45}
46
47impl<T> PartialEq<T> for PoolValue<T>
48where
49 T: PartialEq,
50{
51 fn eq(&self, other: &T) -> bool {
52 self.deref() == other
53 }
54}
55
56impl<T> PartialEq<&T> for PoolValue<T>
57where
58 T: PartialEq + std::fmt::Debug,
59{
60 fn eq(&self, other: &&T) -> bool {
61 self.deref() == *other
62 }
63}
64
65impl<T> Drop for PoolValue<T> {
66 fn drop(&mut self) {
67 if !self.ptr.is_null() {
68 let ptr = self.ptr;
69 self.ptr = std::ptr::null_mut();
70 unsafe {
71 UnsafeCell::raw_get(self.slots)
72 .as_mut()
73 .unwrap_unchecked()
74 .push(Box::from_raw(ptr))
75 }
76 }
77 }
78}
79
80impl<T> std::fmt::Debug for PoolValue<T>
81where
82 T: std::fmt::Debug,
83{
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 write!(f, "{:?}", self.deref())
86 }
87}