bitit 0.1.2

Bitwise iteration over integers.
Documentation
use crate::binary::Binary;

/// An iterator over the indices of the 0-bits in a binary value.
///
/// # Examples
/// ```
/// use bitit::BitIter;
///
/// let x = 0b10101100u8;
/// let mut iter = x.zero_indices();
///
/// assert_eq!(iter.next(), Some(0));
/// assert_eq!(iter.next_back(), Some(6));
/// assert_eq!(iter.next(), Some(1));
/// assert_eq!(iter.next(), Some(4));
/// assert_eq!(iter.next(), None);
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ZeroIndices<T: Binary> {
    n: T,
}

impl<T: Binary> ZeroIndices<T> {
    pub const fn new(n: T) -> Self {
        Self { n }
    }
}

impl<T: Binary> Iterator for ZeroIndices<T> {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        self.n.has_zero().then(|| {
            // Get the index of the least significant 0 and toggle it to 1.
            let i = self.n.trailing_ones();
            self.n ^= T::ONE << i;

            i
        })
    }
}

impl<T: Binary> DoubleEndedIterator for ZeroIndices<T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.n.has_zero().then(|| {
            // Get the index of the most significant 0 and toggle it to 1.
            let i = T::MAX_BIT_IDX - self.n.leading_ones();
            self.n ^= T::ONE << i;

            i
        })
    }
}