miden-crypto/src/merkle/mmr/bit.rs
src/merkle/mmr/bit.rsRaw
1/// Iterate over the bits of a `usize` and yields the bit positions for the true bits.
2pub struct TrueBitPositionIterator {
3 value: usize,
4}
5
6impl TrueBitPositionIterator {
7 pub fn new(value: usize) -> TrueBitPositionIterator {
8 TrueBitPositionIterator { value }
9 }
10}
11
12impl Iterator for TrueBitPositionIterator {
13 type Item = u32;
14
15 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
16 // trailing_zeros is computed with the intrinsic cttz. [Rust 1.67.0] x86 uses the `bsf`
17 // instruction. AArch64 uses the `rbit clz` instructions.
18 let zeros = self.value.trailing_zeros();
19
20 if zeros == usize::BITS {
21 None
22 } else {
23 let bit_position = zeros;
24 let mask = 1 << bit_position;
25 self.value ^= mask;
26 Some(bit_position)
27 }
28 }
29}
30
31impl DoubleEndedIterator for TrueBitPositionIterator {
32 fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
33 // trailing_zeros is computed with the intrinsic ctlz. [Rust 1.67.0] x86 uses the `bsr`
34 // instruction. AArch64 uses the `clz` instruction.
35 let zeros = self.value.leading_zeros();
36
37 if zeros == usize::BITS {
38 None
39 } else {
40 let bit_position = usize::BITS - zeros - 1;
41 let mask = 1 << bit_position;
42 self.value ^= mask;
43 Some(bit_position)
44 }
45 }
46}