bitarr/
iter.rs

1use crate::store::BitStore;
2use core::ops;
3
4#[derive(Debug, Clone)]
5pub struct Bits<S: BitStore> {
6	bits: S,
7	range: ops::Range<u32>,
8}
9
10impl<S: BitStore> From<S> for Bits<S> {
11	#[inline]
12	fn from(bits: S) -> Self {
13		Self::new(bits)
14	}
15}
16
17impl<S: BitStore> Bits<S> {
18	#[inline]
19	pub const fn new(bits: S) -> Self {
20		Self {
21			bits,
22			range: 0..S::BITS,
23		}
24	}
25
26	#[inline]
27	pub const fn with_range(bits: S, range: ops::Range<u32>) -> Self {
28		if range.end > S::BITS {
29			panic!("Range end is out of bounds");
30		}
31
32		Self { bits, range }
33	}
34
35	/// # Safety
36	/// Range parameter must be in bounds for the bit store.
37	#[inline]
38	pub const unsafe fn with_range_unchecked(bits: S, range: ops::Range<u32>) -> Self {
39		Self { bits, range }
40	}
41}
42
43impl<S: BitStore> Iterator for Bits<S> {
44	type Item = bool;
45
46	fn next(&mut self) -> Option<Self::Item> {
47		self.range.next().map(|i| {
48			// SAFETY: `range` is in bounds.
49			unsafe { self.bits.get(i) }
50		})
51	}
52
53	fn size_hint(&self) -> (usize, Option<usize>) {
54		self.range.size_hint()
55	}
56}
57
58impl<S: BitStore> DoubleEndedIterator for Bits<S> {
59	fn next_back(&mut self) -> Option<Self::Item> {
60		self.range.next_back().map(|i| {
61			// SAFETY: `range` is in bounds.
62			unsafe { self.bits.get(i) }
63		})
64	}
65}
66
67impl<S: BitStore> ExactSizeIterator for Bits<S> {
68	#[inline]
69	fn len(&self) -> usize {
70		self.range.len()
71	}
72}
73
74impl<S: BitStore> core::iter::FusedIterator for Bits<S> {}