alloc_from_pool/
pool.rs

1use std::cell::UnsafeCell;
2
3use crate::{alloc_in::alloc_in, allocations_ptr::allocations_ptr, Factory, PoolValue};
4
5pub struct Pool<T: 'static> {
6    slots: *const UnsafeCell<Vec<Box<T>>>,
7    #[cfg(test)]
8    allocations: *mut usize,
9}
10
11impl<T> Pool<T> {
12    pub fn new() -> Self {
13        Self::default()
14    }
15
16    pub fn alloc(&self, value: T) -> PoolValue<T> {
17        alloc_in(self.slots, allocations_ptr!(self), value)
18    }
19
20    pub fn factory(&self) -> Factory<T> {
21        Factory {
22            slots: self.slots,
23            #[cfg(test)]
24            allocations: self.allocations,
25        }
26    }
27
28    pub fn len(&self) -> usize {
29        unsafe {
30            UnsafeCell::raw_get(self.slots)
31                .as_ref()
32                .unwrap_unchecked()
33                .len()
34        }
35    }
36
37    pub fn is_empty(&self) -> bool {
38        self.len() == 0
39    }
40}
41
42impl<T> Default for Pool<T> {
43    fn default() -> Self {
44        Self {
45            slots: Box::leak(Box::new(UnsafeCell::new(vec![]))),
46            #[cfg(test)]
47            allocations: Box::leak(Box::new(0)),
48        }
49    }
50}
51
52#[cfg(test)]
53impl<T> Pool<T> {
54    pub(crate) fn total_allocations(&self) -> usize {
55        unsafe { *self.allocations }
56    }
57}
58
59impl<T> std::fmt::Debug for Pool<T> {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        write!(f, "Pool",)
62    }
63}
64
65impl<T> Drop for Pool<T> {
66    fn drop(&mut self) {
67        unsafe {
68            drop(Box::from_raw(self.slots as *mut UnsafeCell<Vec<Box<T>>>));
69            #[cfg(test)]
70            drop(Box::from_raw(self.allocations));
71        }
72    }
73}