dynvec/region/
mod.rs

1pub mod block;
2pub mod chunks;
3pub mod global;
4
5use std::alloc::Layout;
6
7/// Represents the location of an object allocated in a region.
8pub struct Location<H> {
9    /// The pointer to allocated memory for the object.
10    pub(crate) ptr: *mut u8,
11    /// The header of the location, defined by the user.
12    pub(crate) header: H,
13    /// The layout that was used to allocate the object.
14    pub(crate) layout: Layout,
15}
16
17/// Represents a region of the memory. Objects can be allocated into this region.
18/// Regions can carry additional data with each allocation.
19pub trait Region<H> {
20    /// An iterator over all the allocations of this region.
21    type Pointers: Iterator<Item = *mut u8>;
22
23    /// Finds a free location within this region that is:
24    /// * Properly aligned to `layout.align`
25    /// * `layout.size` bytes long
26    ///
27    /// # Returns
28    /// The pointer is returned if the allocation is successful and the provided
29    /// header is given back in the error if the allocation could not be done.
30    fn allocate(&mut self, layout: Layout, header: H) -> Result<*mut u8, H>;
31
32    /// Deallocates the memory allocated at the given pointer.
33    ///
34    /// # Returns
35    /// If the given pointer was not allocated in this region, `None`
36    /// is returned. Otherwise, the header is returned.
37    ///
38    /// # Safety
39    /// * The old value must've been properly dropped.
40    fn deallocate(&mut self, ptr: *mut u8) -> Option<H>;
41
42    /// Checks whether the given pointer is allocated in this region.
43    fn has_allocated(&self, ptr: *mut u8) -> bool;
44
45    /// Returns an iterator over all the allocations of this region.
46    fn allocations(&self) -> Self::Pointers;
47
48    /// Returns the number of allocations this region has.
49    fn count(&self) -> usize;
50
51    /// Returns an iterator that causes all allocations to be deallocated.
52    /// The iterator yield the headers.
53    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
64/// An iterator that causes a region to deallocate all its allocations.
65pub 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}