extern crate num_integer;
use num_integer::Integer;
use std::ops::{BitAnd, Shl, Shr};
pub trait BitOps:
Copy + Integer + BitAnd<Output = Self> + Shl<Output = Self> + Shr<Output = Self> + From<u8>
{
#[inline]
fn is_flag(&self) -> bool {
*self > Self::zero() && (*self & (*self - Self::one())) == Self::zero()
}
#[inline]
fn is_bit_set(&self, bit: u8) -> bool {
self.is_flag_set(Self::one() << Self::from(bit))
}
#[inline]
fn is_flag_set(&self, flag: Self) -> bool {
*self & flag > Self::zero()
}
#[inline]
fn bits_as_int(&self, bit: u8, count: u8) -> Self {
(*self >> Self::from(bit)) & ((Self::one() << Self::from(count)) - Self::one())
}
}
impl<N> BitOps for N
where
N: Copy + Integer + BitAnd<Output = Self> + Shl<Output = Self> + Shr<Output = Self> + From<u8>,
{
}
mod tests {
#[allow(unused_imports)]
use super::BitOps;
#[test]
fn flag_zero() {
assert!(!0.is_flag());
}
#[test]
fn flag_set_blank() {
assert!(!0x0000.is_flag_set(0));
}
#[test]
fn bits_at_zero() {
assert_eq!(0xabcd.bits_as_int(0, 8), 0xcd);
}
#[test]
#[should_panic]
fn bits_overflow() {
0u16.bits_as_int(16, 0);
}
}