#[cfg(target_arch = "aarch64")]
pub(crate) type BitMaskWord = u64;
#[cfg(not(target_arch = "aarch64"))]
pub(crate) type BitMaskWord = u16;
#[cfg(target_arch = "aarch64")]
pub(crate) const BITMASK_STRIDE: u32 = 4;
#[cfg(not(target_arch = "aarch64"))]
pub(crate) const BITMASK_STRIDE: u32 = 1;
pub(crate) struct BitMask(pub(crate) BitMaskWord);
impl BitMask {
#[inline]
pub(crate) fn any(self) -> bool {
self.0 != 0
}
#[inline]
pub(crate) fn lowest(self) -> Option<usize> {
if self.0 == 0 {
None
} else {
Some((self.0.trailing_zeros() / BITMASK_STRIDE) as usize)
}
}
#[inline]
pub(crate) fn truncate_to(self, n: usize) -> Self {
if n >= 16 {
return self;
}
#[allow(clippy::cast_possible_truncation)]
let bits = (n as u32) * BITMASK_STRIDE;
let mask = (1 as BitMaskWord).wrapping_shl(bits).wrapping_sub(1);
Self(self.0 & mask)
}
}
#[allow(clippy::copy_iterator)]
impl Iterator for BitMask {
type Item = usize;
#[inline]
fn next(&mut self) -> Option<usize> {
if self.0 == 0 {
return None;
}
let bit = self.0.trailing_zeros();
let slot = (bit / BITMASK_STRIDE) as usize;
#[cfg(target_arch = "aarch64")]
{
let nibble = (0xFu64).wrapping_shl(bit);
self.0 &= !nibble;
}
#[cfg(not(target_arch = "aarch64"))]
{
self.0 &= self.0.wrapping_sub(1);
}
Some(slot)
}
}