utils/
bit.rs

1//! Bit manipulation helpers.
2
3use crate::number::UnsignedInteger;
4
5/// Iterator which yields all the set or unset bits in a provided number.
6pub struct BitIterator<T: UnsignedInteger> {
7    n: T,
8}
9
10impl<T: UnsignedInteger> BitIterator<T> {
11    /// Returns an iterator that yields the positions and values of all the set bits in the provided
12    /// number.
13    ///
14    /// # Examples
15    /// ```
16    /// # use utils::bit::BitIterator;
17    /// assert_eq!(
18    ///     BitIterator::ones(0b1001_1101u8).collect::<Vec<(u32, u8)>>(),
19    ///     vec![
20    ///         (0, 1),
21    ///         (2, 4),
22    ///         (3, 8),
23    ///         (4, 16),
24    ///         (7, 128),
25    ///     ],
26    /// );
27    /// ```
28    pub fn ones(n: T) -> Self {
29        BitIterator { n }
30    }
31
32    /// Returns an iterator that yields the positions and values of all the unset bits in the
33    /// provided number.
34    ///
35    /// # Examples
36    /// ```
37    /// # use utils::bit::BitIterator;
38    /// assert_eq!(
39    ///     BitIterator::zeroes(0b1001_1101u8).collect::<Vec<(u32, u8)>>(),
40    ///     vec![
41    ///         (1, 2),
42    ///         (5, 32),
43    ///         (6, 64),
44    ///     ],
45    /// );
46    /// ```
47    pub fn zeroes(n: T) -> Self {
48        BitIterator { n: !n }
49    }
50}
51
52impl<T: UnsignedInteger> Iterator for BitIterator<T> {
53    type Item = (u32, T);
54
55    fn next(&mut self) -> Option<Self::Item> {
56        if self.n == T::ZERO {
57            None
58        } else {
59            let position = self.n.trailing_zeros();
60            let value = T::ONE << position;
61            self.n &= !value;
62            Some((position, value))
63        }
64    }
65}