pub(crate) trait BitWord: Copy + Eq {
const ZERO: Self;
fn trailing_zeros_usize(self) -> usize;
fn clear_lowest(self) -> Self;
}
macro_rules! impl_bit_word {
($($t:ty),+) => {
$(
impl BitWord for $t {
const ZERO: Self = 0;
#[inline]
fn trailing_zeros_usize(self) -> usize {
self.trailing_zeros() as usize
}
#[inline]
fn clear_lowest(self) -> Self {
self & self.wrapping_sub(1)
}
}
)+
};
}
impl_bit_word!(u64, u128);
#[inline]
pub(crate) fn pop_lowest_bit<W: BitWord>(word: &mut W) -> Option<usize> {
if *word == W::ZERO {
None
} else {
let idx = word.trailing_zeros_usize();
*word = word.clear_lowest();
Some(idx)
}
}