1#[cfg(not(feature = "unsafe-maybe-uninit"))]
11mod array;
12#[cfg(feature = "unsafe-maybe-uninit")]
13mod maybe_uninit;
14
15use crate::vec::CopyStackVec;
17
18use core::iter::FusedIterator;
20
21pub struct IntoIter<T: Copy, const N: usize> {
26 pub(crate) v: CopyStackVec<T, N>,
27 pub(crate) front: usize,
28 pub(crate) back: usize, }
30
31impl<T: Copy, const N: usize> Iterator for IntoIter<T, N> {
32 type Item = T;
33 fn next(&mut self) -> Option<T> {
34 if self.front < self.back {
35 let i = self.front;
36 self.front += 1;
37 Some(self.v.as_slice()[i])
38 } else {
39 None
40 }
41 }
42 fn size_hint(&self) -> (usize, Option<usize>) {
43 let rem = self.back - self.front;
44 (rem, Some(rem))
45 }
46 fn nth(&mut self, n: usize) -> Option<T> {
47 let rem = self.back - self.front;
48 if n >= rem {
49 self.front = self.back;
50 return None;
51 }
52 let i = self.front + n; self.front = i + 1;
54 Some(self.v.as_slice()[i])
55 }
56}
57
58impl<T: Copy, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
59 fn next_back(&mut self) -> Option<T> {
60 if self.front < self.back {
61 self.back -= 1;
62 Some(self.v.as_slice()[self.back])
63 } else {
64 None
65 }
66 }
67 fn nth_back(&mut self, n: usize) -> Option<T> {
68 let rem = self.back - self.front;
69 if n >= rem {
70 self.front = self.back;
71 None
72 } else {
73 self.back -= n + 1;
74 Some(self.v.as_slice()[self.back])
75 }
76 }
77}
78impl<T: Copy, const N: usize> FusedIterator for IntoIter<T, N> {}
79impl<T: Copy, const N: usize> ExactSizeIterator for IntoIter<T, N> {}
80
81impl<'a, T: Copy, const N: usize> IntoIterator for &'a CopyStackVec<T, N> {
82 type Item = &'a T;
83 type IntoIter = core::slice::Iter<'a, T>;
84 fn into_iter(self) -> Self::IntoIter {
85 self.as_slice().iter()
86 }
87}
88impl<'a, T: Copy, const N: usize> IntoIterator for &'a mut CopyStackVec<T, N> {
89 type Item = &'a mut T;
90 type IntoIter = core::slice::IterMut<'a, T>;
91 fn into_iter(self) -> Self::IntoIter {
92 self.as_mut_slice().iter_mut()
93 }
94}
95impl<T: Copy, const N: usize> IntoIterator for CopyStackVec<T, N> {
96 type Item = T;
97 type IntoIter = IntoIter<T, N>;
98 fn into_iter(self) -> Self::IntoIter {
99 IntoIter {
100 front: 0,
101 back: self.len,
102 v: self,
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::CopyStackVec;
111
112 #[test]
113 fn test_double_ended_and_nth() {
114 let v: CopyStackVec<i32, 6> = CopyStackVec::try_from(&[10, 20, 30, 40][..]).unwrap();
115 let mut it = v.into_iter();
116 assert_eq!(it.next(), Some(10));
117 assert_eq!(it.next_back(), Some(40));
118 assert_eq!(it.nth(1), Some(30));
119 assert_eq!(it.next(), None);
120 }
121
122 #[test]
123 fn test_into_iter_nth_back_sequence() {
124 let v: CopyStackVec<i32, 6> = CopyStackVec::try_from(&[1, 2, 3, 4, 5][..]).unwrap();
125 let mut it = v.into_iter();
126 assert_eq!(it.nth_back(0), Some(5));
127 assert_eq!(it.nth_back(1), Some(3)); assert_eq!(it.next_back(), Some(2));
129 assert_eq!(it.next(), Some(1));
130 assert_eq!(it.next(), None);
131 }
132
133 #[test]
134 #[allow(clippy::iter_nth_zero)]
135 fn test_size_hint_tracks_consumption() {
136 let v: CopyStackVec<i32, 6> = CopyStackVec::try_from(&[10, 20, 30, 40][..]).unwrap();
137 let mut it = v.into_iter();
138 assert_eq!(it.size_hint(), (4, Some(4)));
139 assert_eq!(it.next(), Some(10));
140 assert_eq!(it.size_hint(), (3, Some(3)));
141 assert_eq!(it.next_back(), Some(40));
142 assert_eq!(it.size_hint(), (2, Some(2)));
143 assert_eq!(it.nth(0), Some(20));
144 assert_eq!(it.size_hint(), (1, Some(1)));
145 assert_eq!(it.next(), Some(30));
146 assert_eq!(it.size_hint(), (0, Some(0)));
147 assert_eq!(it.next(), None);
148 }
149
150 #[test]
151 #[allow(clippy::iter_nth_zero)]
152 fn test_nth_and_nth_back_boundary_conditions() {
153 let v: CopyStackVec<i32, 5> = CopyStackVec::try_from(&[1, 2, 3, 4, 5][..]).unwrap();
154 let mut it = v.into_iter();
155
156 assert_eq!(it.nth(3), Some(4)); assert_eq!(it.nth(0), Some(5));
159 assert_eq!(it.nth(0), None);
160
161 let v2: CopyStackVec<i32, 5> = CopyStackVec::try_from(&[1, 2, 3, 4, 5][..]).unwrap();
162 let mut it2 = v2.into_iter();
163 assert_eq!(it2.nth_back(4), Some(1)); assert_eq!(it2.next(), None);
165 }
166
167 #[test]
168 fn test_into_iter_zero_sized_type() {
169 let v: CopyStackVec<(), 3> = CopyStackVec::from([(); 3]);
170 let it = v.into_iter();
171 assert_eq!(it.size_hint(), (3, Some(3)));
172 assert_eq!(it.count(), 3);
173 }
174
175 #[test]
176 fn test_into_iter_zero_capacity() {
177 let v: CopyStackVec<u8, 0> = CopyStackVec::default();
178 let mut it = v.into_iter();
179 assert_eq!(it.next(), None);
180 assert_eq!(it.size_hint(), (0, Some(0)));
181 }
182
183 #[test]
184 fn test_nth_back_overflow_branch() {
185 let v: CopyStackVec<i32, 5> = CopyStackVec::try_from(&[10, 20, 30][..]).unwrap();
186 let mut it = v.into_iter();
187
188 assert_eq!(it.nth_back(3), None);
190
191 assert_eq!(it.next(), None);
193 assert_eq!(it.next_back(), None);
194
195 assert_eq!(it.size_hint(), (0, Some(0)));
197 }
198
199 #[test]
200 fn test_nth_back_exactly_remaining_branch() {
201 let v: CopyStackVec<i32, 4> = CopyStackVec::try_from(&[1, 2][..]).unwrap();
202 let mut it = v.into_iter();
203
204 assert_eq!(it.nth_back(2), None);
206
207 assert_eq!(it.next(), None);
209 assert_eq!(it.next_back(), None);
210 }
211}