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}