use raw::imp::{BitMaskWord, BITMASK_MASK, BITMASK_SHIFT};
#[derive(Copy, Clone)]
pub struct BitMask(pub BitMaskWord);
impl BitMask {
#[inline]
#[must_use]
pub fn invert(self) -> BitMask {
BitMask(self.0 ^ BITMASK_MASK)
}
#[inline]
#[must_use]
pub fn remove_lowest_bit(self) -> BitMask {
BitMask(self.0 & (self.0 - 1))
}
#[inline]
pub fn any_bit_set(self) -> bool {
self.0 != 0
}
#[inline]
pub fn lowest_set_bit(self) -> Option<usize> {
if self.0 == 0 {
None
} else {
Some(self.trailing_zeros())
}
}
#[inline]
pub fn trailing_zeros(self) -> usize {
if cfg!(target_arch = "arm") && BITMASK_SHIFT >= 3 {
self.0.swap_bytes().leading_zeros() as usize >> BITMASK_SHIFT
} else {
self.0.trailing_zeros() as usize >> BITMASK_SHIFT
}
}
#[inline]
pub fn leading_zeros(self) -> usize {
self.0.leading_zeros() as usize >> BITMASK_SHIFT
}
}
impl IntoIterator for BitMask {
type Item = usize;
type IntoIter = BitMaskIter;
#[inline]
fn into_iter(self) -> BitMaskIter {
BitMaskIter(self)
}
}
pub struct BitMaskIter(BitMask);
impl Iterator for BitMaskIter {
type Item = usize;
#[inline]
fn next(&mut self) -> Option<usize> {
let bit = self.0.lowest_set_bit()?;
self.0 = self.0.remove_lowest_bit();
Some(bit)
}
}