pub(crate) const USIZE_BITS: usize = std::mem::size_of::<usize>() * 8;
macro_rules! bitmask {
( $len:expr, $off:expr ) => {
usize::MAX
.checked_shr((crate::util::USIZE_BITS - $len) as u32)
.unwrap_or(0)
<< $off
};
}
macro_rules! getbits {
( $val: expr, $len:expr, $off:expr ) => {
($val & $crate::util::bitmask!($len, $off)) >> $off
};
}
macro_rules! setbits {
( $var: expr, $len:expr, $off:expr, $val: expr ) => {
$var = ($var & !$crate::util::bitmask!($len, $off))
| (($val << $off) & $crate::util::bitmask!($len, $off))
};
}
pub trait BitsRequired {
fn bits_required(&self) -> u32;
}
macro_rules! impl_bits_required_for {
($($t:ty),*) => {
$(
impl BitsRequired for $t {
fn bits_required(&self) -> u32 {
self.checked_ilog2().map(|v| v + 1).unwrap_or(0)
}
}
)*
};
}
impl_bits_required_for!(u8, u16, usize, u32, u64, u128);
pub(crate) fn ceil_div(a: usize, b: usize) -> usize {
(a + b - 1) / b
}
pub(crate) use bitmask;
pub(crate) use getbits;
pub(crate) use setbits;