flex_alloc/vec/
into_iter.rs

1use core::iter::FusedIterator;
2use core::ops::Range;
3use core::ptr;
4use core::slice;
5
6use crate::capacity::Index;
7
8use super::buffer::VecBuffer;
9
10/// A struct used for extracting all items from a Vec as an iterator.
11#[derive(Debug)]
12pub struct IntoIter<B: VecBuffer> {
13    remain: Range<usize>,
14    buf: B,
15}
16
17impl<B: VecBuffer> IntoIter<B> {
18    pub(super) fn new(mut buf: B) -> Self {
19        let end = buf.length().to_usize();
20        if end > 0 {
21            // SAFETY: buffer capacity is established as > 0
22            unsafe { buf.set_length(B::Index::ZERO) };
23        }
24        Self {
25            remain: Range { start: 0, end },
26            buf,
27        }
28    }
29
30    /// Access the remaining items as a slice reference.
31    pub fn as_slice(&self) -> &[B::Item] {
32        unsafe {
33            slice::from_raw_parts(
34                self.buf.data_ptr().add(self.remain.start),
35                self.remain.len(),
36            )
37        }
38    }
39
40    /// Access the remaining items as a mutable slice reference.
41    pub fn as_mut_slice(&mut self) -> &mut [B::Item] {
42        unsafe {
43            slice::from_raw_parts_mut(
44                self.buf.data_ptr_mut().add(self.remain.start),
45                self.remain.len(),
46            )
47        }
48    }
49
50    /// Check if there are remaining items in the iterator.
51    pub const fn is_empty(&self) -> bool {
52        self.len() == 0
53    }
54
55    /// Get the number of remaining items in the iterator.
56    pub const fn len(&self) -> usize {
57        self.remain.end - self.remain.start
58    }
59
60    /// Drop any remaining items and set the remaining item count to zero.
61    fn clear(&mut self) {
62        let remain_len = self.len();
63        if remain_len > 0 {
64            unsafe {
65                ptr::drop_in_place(self.as_mut_slice().as_mut_ptr());
66            }
67            self.remain.start = self.remain.end;
68        }
69    }
70}
71
72impl<B: VecBuffer> AsRef<[B::Item]> for IntoIter<B> {
73    fn as_ref(&self) -> &[B::Item] {
74        self.as_slice()
75    }
76}
77
78impl<B: VecBuffer> AsMut<[B::Item]> for IntoIter<B> {
79    fn as_mut(&mut self) -> &mut [B::Item] {
80        self.as_mut_slice()
81    }
82}
83
84impl<B: VecBuffer> Iterator for IntoIter<B> {
85    type Item = B::Item;
86
87    fn next(&mut self) -> Option<Self::Item> {
88        let index = self.remain.start;
89        if index != self.remain.end {
90            self.remain.start = index + 1;
91            unsafe {
92                let read = self.buf.data_ptr().add(index);
93                Some(ptr::read(read))
94            }
95        } else {
96            None
97        }
98    }
99
100    #[inline]
101    fn count(self) -> usize
102    where
103        Self: Sized,
104    {
105        self.len()
106    }
107
108    #[inline]
109    fn size_hint(&self) -> (usize, Option<usize>) {
110        let len = self.len();
111        (len, Some(len))
112    }
113}
114
115impl<B: VecBuffer> DoubleEndedIterator for IntoIter<B> {
116    #[inline]
117    fn next_back(&mut self) -> Option<Self::Item> {
118        let mut index = self.remain.end;
119        if index != self.remain.start {
120            index -= 1;
121            self.remain.end = index;
122            unsafe {
123                let read = self.buf.data_ptr().add(index);
124                Some(ptr::read(read))
125            }
126        } else {
127            None
128        }
129    }
130}
131
132impl<B: VecBuffer> ExactSizeIterator for IntoIter<B> {}
133
134impl<B: VecBuffer> FusedIterator for IntoIter<B> {}
135
136impl<B: VecBuffer> Drop for IntoIter<B> {
137    fn drop(&mut self) {
138        self.clear();
139    }
140}