Skip to main content

cotton_usb_host/
bitset.rs

1/// A compact representation of a set of integers, 0-31 inclusive
2#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3#[cfg_attr(feature = "std", derive(Debug))]
4#[derive(Clone, Copy, PartialEq, Eq, Default)]
5pub struct BitSet(
6    /// A bitfield, with a 1 in bit N signifying that N is present in the BitSet
7    pub u32,
8);
9
10impl BitSet {
11    /// Create a new, empty BitSet
12    pub const fn new() -> Self {
13        Self(0)
14    }
15
16    /// An iterator over the integers currently in the set
17    ///
18    /// Note this is not a "live" representation: a snapshot of set membership
19    /// is taken when you call iter().
20    pub fn iter(&self) -> impl Iterator<Item = u8> {
21        BitIterator::new(self.0)
22    }
23
24    /// Add n to the set
25    pub fn set(&mut self, n: u8) {
26        assert!(n < 32);
27        self.0 |= 1 << n;
28    }
29
30    /// Remove n from the set, if present
31    pub fn clear(&mut self, n: u8) {
32        assert!(n < 32);
33        self.0 &= !(1 << n);
34    }
35
36    /// Add to the set the smallest integer not already present
37    ///
38    /// And return it. Or if the set is "full" (integers 0-31 are all
39    /// present), return None.
40    pub fn set_any(&mut self) -> Option<u8> {
41        let next = self.0.trailing_ones() as u8;
42        if next >= 32 {
43            None
44        } else {
45            self.set(next);
46            Some(next)
47        }
48    }
49
50    /// Is n present in the set?
51    pub fn contains(&self, n: u8) -> bool {
52        assert!(n < 32);
53        (self.0 & (1 << n)) != 0
54    }
55}
56
57struct BitIterator(u32);
58
59impl BitIterator {
60    pub const fn new(n: u32) -> Self {
61        Self(n)
62    }
63}
64
65impl Iterator for BitIterator {
66    type Item = u8;
67
68    fn next(&mut self) -> Option<Self::Item> {
69        if self.0 == 0 {
70            None
71        } else {
72            let n = self.0.trailing_zeros();
73            self.0 &= !(1 << n);
74            Some(n as u8)
75        }
76    }
77}
78
79#[cfg(all(test, feature = "std"))]
80#[path = "tests/bitset.rs"]
81mod tests;