use core::{
cmp::Eq,
convert::From,
default::Default,
fmt::{
Binary,
Debug,
Display,
LowerHex,
UpperHex,
},
mem::size_of,
ops::{
Not,
BitAnd,
BitAndAssign,
BitOrAssign,
Shl,
ShlAssign,
Shr,
ShrAssign,
},
};
pub trait Bits:
Sealed
+ Binary
+ BitAnd<Self, Output=Self>
+ BitAndAssign<Self>
+ BitOrAssign<Self>
+ Copy
+ Debug
+ Default
+ Display
+ Eq
+ From<u8>
+ LowerHex
+ Not<Output=Self>
+ Shl<u8, Output=Self>
+ ShlAssign<u8>
+ Shr<u8, Output=Self>
+ ShrAssign<u8>
+ Sized
+ UpperHex
{
const WIDTH: u8 = size_of::<Self>() as u8 * 8;
const BITS: u8;
const MASK: u8 = Self::WIDTH - 1;
const MAX_ELT: usize = core::usize::MAX >> Self::BITS;
fn set(&mut self, place: u8, value: bool) {
assert!(place <= Self::MASK, "Index out of range");
*self &= !(Self::from(1u8) << place);
*self |= Self::from(value as u8) << place;
}
fn get(&self, place: u8) -> bool {
assert!(place <= Self::MASK, "Index out of range");
(*self >> place) & Self::from(1) == Self::from(1)
}
fn ones(&self) -> u32;
fn zeros(&self) -> u32;
fn split(cursor: usize) -> (usize, u8) {
(cursor >> Self::BITS, (cursor & Self::MASK as usize) as u8)
}
fn join(elt: usize, bit: u8) -> usize {
assert!(elt <= core::usize::MAX >> Self::BITS, "Element count out of range!");
assert!(bit <= Self::MASK, "Bit count out of range!");
(elt << Self::BITS) | bit as usize
}
#[doc(hidden)]
const TY: &'static str;
}
impl Bits for u8 {
const BITS: u8 = 3;
fn ones(&self) -> u32 {
self.count_ones()
}
fn zeros(&self) -> u32 {
self.count_zeros()
}
const TY: &'static str = "u8";
}
impl Bits for u16 {
const BITS: u8 = 4;
fn ones(&self) -> u32 {
self.count_ones()
}
fn zeros(&self) -> u32 {
self.count_zeros()
}
const TY: &'static str = "u16";
}
impl Bits for u32 {
const BITS: u8 = 5;
fn ones(&self) -> u32 {
self.count_ones()
}
fn zeros(&self) -> u32 {
self.count_zeros()
}
const TY: &'static str = "u32";
}
impl Bits for u64 {
const BITS: u8 = 6;
fn ones(&self) -> u32 {
self.count_ones()
}
fn zeros(&self) -> u32 {
self.count_zeros()
}
const TY: &'static str = "u64";
}
#[doc(hidden)]
pub trait Sealed {}
impl Sealed for u8 {}
impl Sealed for u16 {}
impl Sealed for u32 {}
impl Sealed for u64 {}