use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, Shr};
use core::ptr;
pub type Bit = bool;
pub type Byte = u8;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub(crate) struct Word(usize);
impl Word {
pub(crate) const BITS: usize = usize::BITS as usize;
pub(crate) const BYTES: usize = size_of::<Self>();
pub(crate) const MSB_SET: Self = Self::mask(0);
pub(crate) const MSB_CLEAR: Self = Self(0);
pub(crate) const CLEAR: Self = Self(0);
pub(crate) unsafe fn from_byte_slice(value: &[Byte]) -> Self {
let mut word = [0; Word::BYTES];
let src = value.as_ptr();
let dst = word.as_mut_ptr();
let count = value.len();
unsafe {
ptr::copy_nonoverlapping(src, dst, count);
}
Self::from_byte_array(word)
}
pub(crate) fn from_byte_array(value: [Byte; Word::BYTES]) -> Self {
Self(usize::from_be_bytes(value))
}
#[cfg(feature = "serde")]
pub(crate) fn to_byte_array(self) -> [Byte; Word::BYTES] {
self.0.to_be_bytes()
}
pub(crate) fn align_last_to_lsb(self, last: usize) -> Self {
self >> (Self::BITS - 1 - last)
}
pub(crate) fn get(self, index: usize) -> Bit {
self & Self::mask(index) != Self(0)
}
pub(crate) fn set(&mut self, index: usize, value: Bit) {
if value {
*self |= Self::mask(index);
} else {
*self &= !Self::mask(index);
}
}
const fn mask(index: usize) -> Self {
Self(1 << (Self::BITS - 1 - index))
}
}
impl BitAnd for Word {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & rhs.0)
}
}
impl BitAndAssign for Word {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
impl BitOr for Word {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl BitOrAssign for Word {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl BitXor for Word {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
}
impl BitXorAssign for Word {
fn bitxor_assign(&mut self, rhs: Self) {
self.0 ^= rhs.0;
}
}
impl Not for Word {
type Output = Self;
fn not(self) -> Self::Output {
Self(!self.0)
}
}
impl Shl<usize> for Word {
type Output = Self;
fn shl(self, rhs: usize) -> Self::Output {
Self(self.0 << rhs)
}
}
impl Shr<usize> for Word {
type Output = Self;
fn shr(self, rhs: usize) -> Self::Output {
Self(self.0 >> rhs)
}
}