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 #[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 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 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> {}