pub trait CLZ {
type L;
fn clz(self) -> Self::L;
}
pub trait CTZ {
type L;
fn ctz(self) -> Self::L;
}
pub trait CountLeadingOnes {
type L;
fn leading_ones(self) -> Self::L;
}
pub trait CountTrailingOnes {
type L;
fn trailing_ones(self) -> Self::L;
}
pub trait CountZeros {
type L;
fn count_zeros(self) -> Self::L;
}
pub trait CountOnes {
type L;
fn count_ones(self) -> Self::L;
}
pub trait BSR {
type L;
fn bsr(self) -> Self::L;
}
pub trait BSF {
type L;
fn bsf(self) -> Self::L;
}
pub trait Popcount: CountOnes {}
impl<T: CountOnes> Popcount for T {}
pub trait Inverse {
fn invert(self) -> Self;
}
pub fn invert<T: std::ops::Not<Output = T>>(n: T) -> T {
!n
}
pub trait Reverse {
fn reverse(self) -> Self;
}
pub trait ShrUntilOdd {
fn shr_until_odd(self) -> Self;
}
pub fn shr_until_odd(n: u64) -> u64 {
assert!(n > 0);
n >> n.trailing_zeros()
}
pub fn rot_l(
x: u64,
k: u8,
) -> u64 {
(x << k) | (x >> (64 - k))
}
pub fn reset(
n: u64,
i: usize,
) -> u64 {
n & !(1 << i)
}
pub fn flip(
n: u64,
i: usize,
) -> u64 {
n ^ (1 << i)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shr_until_odd() {
assert_eq!(shr_until_odd(1), 1);
assert_eq!(shr_until_odd(2), 1);
assert_eq!(shr_until_odd(12), 3);
}
}