Skip to main content

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    #[inline]
56    fn next(&mut self) -> Option<Self::Item> {
57        let position = self.n.lowest_one()?;
58        let value = self.n.isolate_lowest_one();
59        self.n ^= value;
60        Some((position, value))
61    }
62}
63
64/// Computes the population count for each bit position across 4 input masks.
65///
66/// Returns three masks `[bit0, bit1, bit2]` that encode, per bit position, the 3-bit count
67/// of how many of the 4 inputs have that bit set.
68///
69/// For example, if a given bit is set in 3 inputs, then that bit would be set in `bit0` and `bit1`.
70/// If a given bit is set in all 4 inputs, then that bit would only be set in `bit2`.
71///
72/// # Examples
73/// ```
74/// # use utils::bit::bitwise_count4;
75/// let [bit0, bit1, bit2] = bitwise_count4::<u8>(&[
76///     0b10000,
77///     0b11000,
78///     0b11100,
79///     0b11110,
80/// ]);
81/// assert_eq!(bit0, 0b01010);
82/// assert_eq!(bit1, 0b01100);
83/// assert_eq!(bit2, 0b10000);
84/// ```
85#[inline]
86#[must_use]
87pub fn bitwise_count4<T: UnsignedInteger>(m: &[T; 4]) -> [T; 3] {
88    let (sum, carry1) = carry_save_adder(m[0], m[1], m[2]);
89    let (bit0, carry2) = carry_save_adder(sum, m[3], T::ZERO);
90    let (bit1, bit2) = carry_save_adder(carry1, carry2, T::ZERO);
91    [bit0, bit1, bit2]
92}
93
94/// Computes the population count for each bit position across 8 input masks.
95///
96/// Returns four masks `[bit0, bit1, bit2, bit3]` that encode, per bit position, the 4-bit count
97/// of how many of the 8 inputs have that bit set.
98///
99/// For example, if a given bit is set in 5 inputs, then that bit would be set in `bit0` and `bit2`.
100/// If a given bit is set in all 8 inputs, then that bit would only be set in `bit3`.
101///
102/// # Examples
103/// ```
104/// # use utils::bit::bitwise_count8;
105/// let [bit0, bit1, bit2, bit3] = bitwise_count8::<u16>(&[
106///                  0b100000000,
107///                  0b110000000,
108///                  0b111000000,
109///                  0b111100000,
110///                  0b111110000,
111///                  0b111111000,
112///                  0b111111100,
113///                  0b111111110,
114/// ]);
115/// assert_eq!(bit0, 0b010101010);
116/// assert_eq!(bit1, 0b011001100);
117/// assert_eq!(bit2, 0b011110000);
118/// assert_eq!(bit3, 0b100000000);
119/// ```
120///
121/// ```
122/// # use utils::bit::bitwise_count8;
123/// let [bit0, bit1, bit2, bit3] = bitwise_count8::<u64>(&[
124///                  0b00111000_01001000_10000111_11111111_10111000_11100010_00110010_01010011,
125///                  0b01110000_00100111_01011101_11011000_10001100_00011000_10100101_00110010,
126///                  0b00000101_11010011_10110011_10000000_00000000_11110110_00000101_11111010,
127///                  0b01101001_01001100_00111001_01101100_00110111_00101011_00010101_10011101,
128///                  0b00011100_11101111_00111111_01101011_00011101_01011110_11101101_10101101,
129///                  0b10111100_11101111_00001001_10100100_01010110_10101011_01011000_11111100,
130///                  0b11110110_00010001_11101111_00101101_01110111_10000011_11110110_10101011,
131///                  0b01110001_01100010_01111101_01001000_01011001_10110100_11100110_11100000,
132/// ]);
133/// assert_eq!(bit0, 0b00000011_10000011_11110100_01100001_01100110_11100101_00100010_00011100);
134/// assert_eq!(bit1, 0b10110001_11010000_11001000_00011011_11110010_01000111_00001110_10100100);
135/// assert_eq!(bit2, 0b01111100_01101111_00111110_11101100_00011101_10111010_11110101_11111011);
136/// assert_eq!(bit3, 0b00000000_00000000_00000001_00000000_00000000_00000000_00000000_00000000);
137/// ```
138#[inline]
139#[must_use]
140pub fn bitwise_count8<T: UnsignedInteger>(m: &[T; 8]) -> [T; 4] {
141    let (s1, c1) = carry_save_adder(m[0], m[1], m[2]);
142    let (s2, c2) = carry_save_adder(m[3], m[4], m[5]);
143    let (s3, c3) = carry_save_adder(m[6], m[7], T::ZERO);
144    let (s4, c4) = carry_save_adder(c1, c2, c3);
145    let (bit0, c5) = carry_save_adder(s1, s2, s3);
146    let (bit1, c6) = carry_save_adder(s4, c5, T::ZERO);
147    let (bit2, bit3) = carry_save_adder(c4, c6, T::ZERO);
148    [bit0, bit1, bit2, bit3]
149}
150
151#[inline]
152#[must_use]
153fn carry_save_adder<T: UnsignedInteger>(a: T, b: T, c: T) -> (T, T) {
154    let sum_ab = a ^ b;
155    let carry_ab = a & b;
156    let sum_abc = sum_ab ^ c;
157    let carry_abc = carry_ab | (sum_ab & c);
158    (sum_abc, carry_abc)
159}