1pub mod block;
2pub mod chunks;
3pub mod global;
4
5use std::alloc::Layout;
6
7pub struct Location<H> {
9 pub(crate) ptr: *mut u8,
11 pub(crate) header: H,
13 pub(crate) layout: Layout,
15}
16
17pub trait Region<H> {
20 type Pointers: Iterator<Item = *mut u8>;
22
23 fn allocate(&mut self, layout: Layout, header: H) -> Result<*mut u8, H>;
31
32 fn deallocate(&mut self, ptr: *mut u8) -> Option<H>;
41
42 fn has_allocated(&self, ptr: *mut u8) -> bool;
44
45 fn allocations(&self) -> Self::Pointers;
47
48 fn count(&self) -> usize;
50
51 fn deallocate_all(&mut self) -> DeallocateAll<'_, H, Self>
54 where
55 Self: Sized,
56 {
57 DeallocateAll {
58 iter: self.allocations(),
59 region: self,
60 }
61 }
62}
63
64pub struct DeallocateAll<'a, H, R: Region<H>> {
66 region: &'a mut R,
67 iter: R::Pointers,
68}
69
70impl<'a, H, R: Region<H>> Iterator for DeallocateAll<'a, H, R> {
71 type Item = (*mut u8, H);
72
73 fn next(&mut self) -> Option<Self::Item> {
74 let ptr = self.iter.next()?;
75 Some((ptr, self.region.deallocate(ptr).unwrap()))
76 }
77
78 fn size_hint(&self) -> (usize, Option<usize>) {
79 self.iter.size_hint()
80 }
81}
82
83impl<'a, H, R> ExactSizeIterator for DeallocateAll<'a, H, R>
84where
85 R: Region<H>,
86 R::Pointers: ExactSizeIterator,
87{
88 fn len(&self) -> usize {
89 self.iter.len()
90 }
91}
92
93impl<'a, H, R> std::iter::FusedIterator for DeallocateAll<'a, H, R>
94where
95 R: Region<H>,
96 R::Pointers: std::iter::FusedIterator,
97{
98}
99
100impl<'a, H, R> std::iter::DoubleEndedIterator for DeallocateAll<'a, H, R>
101where
102 R: Region<H>,
103 R::Pointers: std::iter::DoubleEndedIterator,
104{
105 fn next_back(&mut self) -> Option<Self::Item> {
106 let ptr = self.iter.next_back()?;
107 Some((ptr, self.region.deallocate(ptr).unwrap()))
108 }
109}
110
111#[cfg(test)]
112#[test]
113fn deallocate_all() {
114 let mut chunks = chunks::Chunks::new(4);
115
116 let vec: Vec<*mut u8> = (0..100)
117 .map(|_| chunks.allocate(Layout::new::<u8>(), ()).unwrap())
118 .collect();
119
120 for _ in chunks.deallocate_all() {}
121
122 for ptr in vec {
123 assert_eq!(chunks.deallocate(ptr), None);
124 }
125}