// Eryn Wells pub(crate) struct BitScanner { bits: u64, shift: usize, } impl BitScanner { pub(crate) fn new(bits: u64) -> BitScanner { BitScanner { bits, shift: 0 } } } impl Iterator for BitScanner { type Item = usize; fn next(&mut self) -> Option { let u64bits = u64::BITS as usize; if self.shift == u64bits { return None; } let shifted_bits = self.bits << self.shift; let leading_zeros = shifted_bits.leading_zeros() as usize; if leading_zeros == u64bits { self.shift = leading_zeros; return None; } let position = u64bits - (self.shift + leading_zeros + 1); // Shift 1 additional place to account for the 1 that `leading_zeros` found. self.shift += leading_zeros + 1; Some(position) } } #[cfg(test)] mod tests { use super::*; #[test] fn zero() { let mut scanner = BitScanner::new(0); assert_eq!(scanner.next(), None); } #[test] fn one() { let mut scanner = BitScanner::new(1); assert_eq!(scanner.next(), Some(0)); assert_eq!(scanner.next(), None); } #[test] fn complex() { let mut scanner = BitScanner::new(0b11000101); assert_eq!(scanner.next(), Some(7)); assert_eq!(scanner.next(), Some(6)); assert_eq!(scanner.next(), Some(2)); assert_eq!(scanner.next(), Some(0)); assert_eq!(scanner.next(), None); } }