1#![doc = include_str!("../../doc/array/iter.md")]
2
3use core::{
4 fmt::{
5 self,
6 Debug,
7 Formatter,
8 },
9 iter::FusedIterator,
10 ops::Range,
11};
12
13use tap::Pipe;
14use wyz::comu::Const;
15
16use super::BitArray;
17use crate::{
18 mem,
19 order::BitOrder,
20 ptr::BitPtr,
21 slice::BitSlice,
22 view::BitViewSized,
23};
24
25impl<A, O> IntoIterator for BitArray<A, O>
27where
28 A: BitViewSized,
29 O: BitOrder,
30{
31 type IntoIter = IntoIter<A, O>;
32 type Item = <IntoIter<A, O> as Iterator>::Item;
33
34 #[inline]
35 fn into_iter(self) -> Self::IntoIter {
36 IntoIter::new(self)
37 }
38}
39
40#[cfg(not(tarpaulin_include))]
42impl<'a, A, O> IntoIterator for &'a BitArray<A, O>
43where
44 O: BitOrder,
45 A: 'a + BitViewSized,
46{
47 type IntoIter = <&'a BitSlice<A::Store, O> as IntoIterator>::IntoIter;
48 type Item = <&'a BitSlice<A::Store, O> as IntoIterator>::Item;
49
50 #[inline]
51 fn into_iter(self) -> Self::IntoIter {
52 self.as_bitslice().into_iter()
53 }
54}
55
56#[cfg(not(tarpaulin_include))]
58impl<'a, A, O> IntoIterator for &'a mut BitArray<A, O>
59where
60 O: BitOrder,
61 A: 'a + BitViewSized,
62{
63 type IntoIter = <&'a mut BitSlice<A::Store, O> as IntoIterator>::IntoIter;
64 type Item = <&'a mut BitSlice<A::Store, O> as IntoIterator>::Item;
65
66 #[inline]
67 fn into_iter(self) -> Self::IntoIter {
68 self.as_mut_bitslice().into_iter()
69 }
70}
71
72#[derive(Clone)]
73#[doc = include_str!("../../doc/array/IntoIter.md")]
74pub struct IntoIter<A, O>
75where
76 A: BitViewSized,
77 O: BitOrder,
78{
79 array: BitArray<A, O>,
81 alive: Range<usize>,
85}
86
87impl<A, O> IntoIter<A, O>
88where
89 A: BitViewSized,
90 O: BitOrder,
91{
92 #[inline]
103 pub fn new(array: BitArray<A, O>) -> Self {
104 Self {
105 array,
106 alive: 0 .. mem::bits_of::<A>(),
107 }
108 }
109
110 #[inline]
116 pub fn as_bitslice(&self) -> &BitSlice<A::Store, O> {
117 unsafe { self.array.as_bitslice().get_unchecked(self.alive.clone()) }
118 }
119
120 #[inline]
121 #[cfg(not(tarpaulin_include))]
122 #[deprecated = "use `.as_bitslice()` instead"]
123 #[allow(missing_docs, clippy::missing_docs_in_private_items)]
124 pub fn as_slice(&self) -> &BitSlice<A::Store, O> {
125 self.as_bitslice()
126 }
127
128 #[inline]
134 pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<A::Store, O> {
135 unsafe {
136 self.array
137 .as_mut_bitslice()
138 .get_unchecked_mut(self.alive.clone())
139 }
140 }
141
142 #[inline]
143 #[cfg(not(tarpaulin_include))]
144 #[deprecated = "use `.as_bitslice_mut()` instead"]
145 #[allow(missing_docs, clippy::missing_docs_in_private_items)]
146 pub fn as_mut_slice(&mut self) -> &mut BitSlice<A::Store, O> {
147 self.as_mut_bitslice()
148 }
149
150 #[inline]
152 fn get(&self, index: usize) -> bool {
153 unsafe {
154 self.array
155 .as_raw_slice()
156 .pipe(BitPtr::<Const, A::Store, O>::from_slice)
157 .add(index)
158 .read()
159 }
160 }
161}
162
163#[cfg(not(tarpaulin_include))]
164impl<A, O> Debug for IntoIter<A, O>
165where
166 A: BitViewSized,
167 O: BitOrder,
168{
169 #[inline]
170 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
171 fmt.debug_tuple("IntoIter")
172 .field(&self.as_bitslice())
173 .finish()
174 }
175}
176
177impl<A, O> Iterator for IntoIter<A, O>
178where
179 A: BitViewSized,
180 O: BitOrder,
181{
182 type Item = bool;
183
184 easy_iter!();
185
186 #[inline]
187 fn next(&mut self) -> Option<Self::Item> {
188 self.alive.next().map(|idx| self.get(idx))
189 }
190
191 #[inline]
192 fn nth(&mut self, n: usize) -> Option<Self::Item> {
193 self.alive.nth(n).map(|idx| self.get(idx))
194 }
195}
196
197impl<A, O> DoubleEndedIterator for IntoIter<A, O>
198where
199 A: BitViewSized,
200 O: BitOrder,
201{
202 #[inline]
203 fn next_back(&mut self) -> Option<Self::Item> {
204 self.alive.next_back().map(|idx| self.get(idx))
205 }
206
207 #[inline]
208 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
209 self.alive.nth_back(n).map(|idx| self.get(idx))
210 }
211}
212
213impl<A, O> ExactSizeIterator for IntoIter<A, O>
214where
215 A: BitViewSized,
216 O: BitOrder,
217{
218 #[inline]
219 fn len(&self) -> usize {
220 self.alive.len()
221 }
222}
223
224impl<A, O> FusedIterator for IntoIter<A, O>
225where
226 A: BitViewSized,
227 O: BitOrder,
228{
229}