pub trait Bitmap
where
Self: Default + Copy,
{
const BITSIZE: usize;
fn set(&mut self, offset: usize);
fn unset(&mut self, offset: usize);
fn leading_zeros(&self) -> usize;
fn trailing_zeros(&self) -> usize;
fn count_ones(&self) -> usize;
fn find_nth_span(&self, n: usize) -> Option<(usize, usize)>;
}
macro_rules! impl_bitmap_for {
($t:ty, $bits:expr) => {
impl Bitmap for $t {
const BITSIZE: usize = $bits;
#[inline]
fn set(&mut self, offset: usize) {
*self |= 1 as $t << ($bits - 1 - offset);
}
#[inline]
fn unset(&mut self, offset: usize) {
*self &= !(1 as $t << ($bits - 1 - offset));
}
#[inline]
fn leading_zeros(&self) -> usize {
<$t>::leading_zeros(*self) as usize
}
#[inline]
fn trailing_zeros(&self) -> usize {
<$t>::trailing_zeros(*self) as usize
}
#[inline]
fn count_ones(&self) -> usize {
<$t>::count_ones(*self) as usize
}
fn find_nth_span(&self, n: usize) -> Option<(usize, usize)> {
let mut value = *self;
let mut start = 0;
let mut count = 0;
while value != 0 {
let end = value.leading_zeros();
if count == n {
return Some((start as usize, end as usize + 1));
}
value &= !(1 as $t << ($bits - 1 - end));
start = end + 1;
count += 1;
}
None
}
}
};
}
impl_bitmap_for!(u8, 8);
impl_bitmap_for!(u16, 16);
impl_bitmap_for!(u32, 32);
impl_bitmap_for!(u64, 64);
impl_bitmap_for!(u128, 128);