use std::fmt::{Binary, Debug};
use std::hash::Hash;
use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
#[doc(hidden)]
pub trait BitSlot:
Clone
+ Copy
+ Default
+ Debug
+ Binary
+ Eq
+ PartialEq
+ Hash
+ Not<Output = Self>
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitXor<Output = Self>
+ Shl<u8, Output = Self>
+ Shr<u8, Output = Self>
{
const LEN: u8;
fn single_bit(pos: u8) -> Self;
fn bitmask(len: u8) -> Self;
fn first_bit(&self) -> u8;
fn is_set(&self, pos: u8) -> bool;
fn last_16_bits(&self) -> u16;
}
macro_rules! bitslot {
($slot:ty) => {
impl BitSlot for $slot {
const LEN: u8 = std::mem::size_of::<$slot>() as u8 * 8;
fn first_bit(&self) -> u8 {
self.leading_zeros() as u8 + 1
}
fn single_bit(pos: u8) -> Self {
debug_assert!(pos > 0); debug_assert!( pos <= Self::LEN);
1 as $slot << (Self::LEN-pos)
}
fn is_set(&self, pos: u8) -> bool {
debug_assert!(pos > 0); debug_assert!( pos <= Self::LEN);
(self >> (Self::LEN-pos)) & 1 != 0
}
fn bitmask(len:u8) -> Self {
debug_assert!( len <= Self::LEN);
if len == 0 { 0 } else { (!0 as $slot) << (Self::LEN-len) }
}
fn last_16_bits(&self) -> u16 {
*self as u16
}
}
};
}
bitslot!(u32);
bitslot!(u64);
bitslot!(u128);