bitvec/boxed/
iter.rs

1#![doc = include_str!("../../doc/boxed/iter.md")]
2
3use core::{
4	fmt::{
5		self,
6		Debug,
7		Formatter,
8	},
9	iter::FusedIterator,
10	ops::Range,
11};
12
13use super::BitBox;
14use crate::{
15	order::{
16		BitOrder,
17		Lsb0,
18	},
19	slice::BitSlice,
20	store::BitStore,
21};
22
23/// [Original](alloc::vec::IntoIter)
24impl<T, O> IntoIterator for BitBox<T, O>
25where
26	T: BitStore,
27	O: BitOrder,
28{
29	type IntoIter = IntoIter<T, O>;
30	type Item = bool;
31
32	#[inline]
33	fn into_iter(self) -> Self::IntoIter {
34		IntoIter::new(self)
35	}
36}
37
38/** An iterator over a `BitBox`.
39
40## Original
41
42[`vec::IntoIter`](alloc::vec::IntoIter)
43**/
44pub struct IntoIter<T = usize, O = Lsb0>
45where
46	T: BitStore,
47	O: BitOrder,
48{
49	/// The original `BitBox`, kept so it can correctly drop.
50	_buf: BitBox<T, O>,
51	/// A range of indices yet to be iterated.
52	//  TODO(myrrlyn): Race this against `BitPtrRange<Mut, T, O>`.
53	iter: Range<usize>,
54}
55
56impl<T, O> IntoIter<T, O>
57where
58	T: BitStore,
59	O: BitOrder,
60{
61	/// Wraps a bit-array in an iterator view. This is irreversible.
62	#[inline]
63	fn new(this: BitBox<T, O>) -> Self {
64		let iter = 0 .. this.len();
65		Self { _buf: this, iter }
66	}
67
68	/// Views the remaining unyielded bits as a bit-slice.
69	///
70	/// ## Original
71	///
72	/// [`IntoIter::as_slice`](alloc::vec::IntoIter::as_slice)
73	#[inline]
74	pub fn as_bitslice(&self) -> &BitSlice<T, O> {
75		//  While the memory is never actually deïnitialized, this is still a
76		//  good habit to do.
77		unsafe {
78			self._buf
79				.as_bitptr()
80				.add(self.iter.start)
81				.span_unchecked(self.iter.len())
82				.into_bitslice_ref()
83		}
84	}
85
86	#[inline]
87	#[doc(hidden)]
88	#[cfg(not(tarpaulin_include))]
89	#[deprecated = "use `.as_bitslice()` instead"]
90	#[allow(missing_docs, clippy::missing_docs_in_private_items)]
91	pub fn as_slice(&self) -> &BitSlice<T, O> {
92		self.as_bitslice()
93	}
94
95	/// Views the remaining unyielded bits as a mutable bit-slice.
96	///
97	/// ## Original
98	///
99	/// [`IntoIter::as_mut_slice`](alloc::vec::IntoIter::as_mut_slice)
100	#[inline]
101	pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<T, O> {
102		unsafe {
103			self._buf
104				.as_mut_bitptr()
105				.add(self.iter.start)
106				.span_unchecked(self.iter.len())
107				.into_bitslice_mut()
108		}
109	}
110
111	#[inline]
112	#[doc(hidden)]
113	#[cfg(not(tarpaulin_include))]
114	#[deprecated = "use `.as_mut_bitslice()` instead"]
115	#[allow(missing_docs, clippy::missing_docs_in_private_items)]
116	pub fn as_mut_slice(&mut self) -> &mut BitSlice<T, O> {
117		self.as_mut_bitslice()
118	}
119}
120
121/// [Original](https://doc.rust-lang.org/alloc/vec/struct.IntoIter.html#impl-AsRef%3C%5BT%5D%3E)
122#[cfg(not(tarpaulin_include))]
123impl<T, O> AsRef<BitSlice<T, O>> for IntoIter<T, O>
124where
125	T: BitStore,
126	O: BitOrder,
127{
128	#[inline]
129	fn as_ref(&self) -> &BitSlice<T, O> {
130		self.as_bitslice()
131	}
132}
133
134#[cfg(not(tarpaulin_include))]
135impl<T, O> Clone for IntoIter<T, O>
136where
137	T: BitStore,
138	O: BitOrder,
139{
140	#[inline]
141	fn clone(&self) -> Self {
142		Self {
143			_buf: self._buf.clone(),
144			iter: self.iter.clone(),
145		}
146	}
147}
148
149/// [Original](https://doc.rust-lang.org/alloc/vec/struct.IntoIter.html#impl-Debug)
150#[cfg(not(tarpaulin_include))]
151impl<T, O> Debug for IntoIter<T, O>
152where
153	T: BitStore,
154	O: BitOrder,
155{
156	#[inline]
157	fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
158		fmt.debug_tuple("IntoIter")
159			.field(&self.as_bitslice())
160			.finish()
161	}
162}
163
164impl<T, O> Iterator for IntoIter<T, O>
165where
166	T: BitStore,
167	O: BitOrder,
168{
169	type Item = bool;
170
171	easy_iter!();
172
173	#[inline]
174	fn next(&mut self) -> Option<Self::Item> {
175		self.iter
176			.next()
177			.map(|idx| unsafe { self._buf.as_bitptr().add(idx).read() })
178	}
179
180	#[inline]
181	fn nth(&mut self, n: usize) -> Option<Self::Item> {
182		self.iter
183			.nth(n)
184			.map(|idx| unsafe { self._buf.as_bitptr().add(idx).read() })
185	}
186}
187
188impl<T, O> DoubleEndedIterator for IntoIter<T, O>
189where
190	T: BitStore,
191	O: BitOrder,
192{
193	#[inline]
194	fn next_back(&mut self) -> Option<Self::Item> {
195		self.iter
196			.next_back()
197			.map(|idx| unsafe { self._buf.as_bitptr().add(idx).read() })
198	}
199
200	#[inline]
201	fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
202		self.iter
203			.nth_back(n)
204			.map(|idx| unsafe { self._buf.as_bitptr().add(idx).read() })
205	}
206}
207
208impl<T, O> ExactSizeIterator for IntoIter<T, O>
209where
210	T: BitStore,
211	O: BitOrder,
212{
213	#[inline]
214	fn len(&self) -> usize {
215		self.iter.len()
216	}
217}
218
219impl<T, O> FusedIterator for IntoIter<T, O>
220where
221	T: BitStore,
222	O: BitOrder,
223{
224}
225
226/// [Original](https://doc.rust-lang.org/alloc/vec/struct.IntoIter.html#impl-Send)
227// #[allow(clippy::non_send_fields_in_send_ty)]
228unsafe impl<T, O> Send for IntoIter<T, O>
229where
230	T: BitStore + Sync,
231	O: BitOrder,
232{
233}
234
235/// [Original](https://doc.rust-lang.org/alloc/vec/struct.IntoIter.html#impl-Sync)
236unsafe impl<T, O> Sync for IntoIter<T, O>
237where
238	T: BitStore + Sync,
239	O: BitOrder,
240{
241}