alloc_from_pool/
pool_value.rs

1use 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}