Skip to main content

mnemosyne_arena/scratch/aligned_vec/
iter.rs

1//! Iterator traits for [`AlignedVec`].
2
3use super::AlignedVec;
4use super::ScratchElement;
5
6/// Consuming iterator that moves elements out of an `AlignedVec<T>`.
7///
8/// Created by [`AlignedVec::into_iter`] via the [`IntoIterator`] impl.
9/// Iterates the initialized elements in order; the remaining tail is freed
10/// when the iterator is dropped.
11pub struct IntoIter<T: ScratchElement> {
12    vec: AlignedVec<T>,
13    pos: usize,
14}
15
16impl<T: ScratchElement> Iterator for IntoIter<T> {
17    type Item = T;
18
19    #[inline]
20    fn next(&mut self) -> Option<T> {
21        if self.pos < self.vec.len() {
22            // SAFETY: `pos < len` guarantees the element at `pos` is
23            // initialized. `T: ScratchElement: Copy` means reading (and
24            // logically moving) it by copy is sound; no destructor runs.
25            let value = unsafe { *self.vec.ptr.add(self.pos) };
26            self.pos += 1;
27            Some(value)
28        } else {
29            None
30        }
31    }
32
33    #[inline]
34    fn size_hint(&self) -> (usize, Option<usize>) {
35        let remaining = self.vec.len() - self.pos;
36        (remaining, Some(remaining))
37    }
38}
39
40impl<T: ScratchElement> ExactSizeIterator for IntoIter<T> {}
41impl<T: ScratchElement> core::iter::FusedIterator for IntoIter<T> {}
42
43impl<T: ScratchElement> core::iter::DoubleEndedIterator for IntoIter<T> {
44    #[inline]
45    fn next_back(&mut self) -> Option<T> {
46        let end = self.vec.len();
47        if self.pos < end {
48            // Logically pop from the back by reducing len.
49            // SAFETY: `end - 1 < self.vec.len()` — initialized; T: Copy.
50            let new_end = end - 1;
51            // SAFETY: `new_end <= capacity`; element at `new_end` is initialized.
52            unsafe { self.vec.set_len_unchecked(new_end) };
53            let val = unsafe { core::ptr::read(self.vec.ptr.add(new_end)) };
54            Some(val)
55        } else {
56            None
57        }
58    }
59}
60
61impl<T: ScratchElement> IntoIterator for AlignedVec<T> {
62    type Item = T;
63    type IntoIter = IntoIter<T>;
64
65    #[inline]
66    fn into_iter(self) -> IntoIter<T> {
67        IntoIter { vec: self, pos: 0 }
68    }
69}
70
71impl<'a, T: ScratchElement> IntoIterator for &'a AlignedVec<T> {
72    type Item = &'a T;
73    type IntoIter = core::slice::Iter<'a, T>;
74
75    #[inline]
76    fn into_iter(self) -> core::slice::Iter<'a, T> {
77        self.as_slice().iter()
78    }
79}
80
81impl<'a, T: ScratchElement> IntoIterator for &'a mut AlignedVec<T> {
82    type Item = &'a mut T;
83    type IntoIter = core::slice::IterMut<'a, T>;
84
85    #[inline]
86    fn into_iter(self) -> core::slice::IterMut<'a, T> {
87        self.as_mut_slice().iter_mut()
88    }
89}