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}