use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
use crate::BitBlock;
#[cfg_attr(feature = "alloc", derive(Debug))]
#[cfg_attr(feature = "std", derive(Hash))]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct LE<B: BitBlock>(pub B);
macro_rules! impl_le_bit_block {
{$type:ty} => {
unsafe impl BitBlock for LE<$type> {
const ZERO: Self = LE(0);
const UPSTREAM_ONE: Self = LE(1);
const BITS: usize = <$type as BitBlock>::BITS;
#[inline(always)]
fn wrapping_shift_downstream(self, n: usize) -> Self {
LE(self.0.wrapping_shift_upstream(n))
}
#[inline(always)]
fn wrapping_shift_upstream(self, n: usize) -> Self {
LE(self.0.wrapping_shift_downstream(n))
}
#[inline(always)]
fn leading_zeros(self) -> usize {
self.0.trailing_zeros() as usize
}
#[inline(always)]
fn leading_ones(self) -> usize {
self.0.trailing_ones() as usize
}
}
}
}
impl_le_bit_block! {u8}
impl_le_bit_block! {u16}
impl_le_bit_block! {u32}
impl_le_bit_block! {u64}
impl_le_bit_block! {u128}
impl<B: BitBlock> Not for LE<B> {
type Output = LE<<B as Not>::Output>;
#[inline(always)]
fn not(self) -> Self::Output {
Self(!self.0)
}
}
impl<B: BitBlock> BitOr for LE<B> {
type Output = LE<<B as BitOr>::Output>;
#[inline(always)]
fn bitor(self, rhs: Self) -> Self::Output {
LE(self.0.bitor(rhs.0))
}
}
impl<B: BitBlock> BitAnd for LE<B> {
type Output = LE<<B as BitAnd>::Output>;
#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
LE(self.0.bitand(rhs.0))
}
}
impl<B: BitBlock> BitAndAssign for LE<B> {
#[inline(always)]
fn bitand_assign(&mut self, rhs: Self) {
self.0.bitand_assign(rhs.0)
}
}
impl<B: BitBlock> BitOrAssign for LE<B> {
#[inline(always)]
fn bitor_assign(&mut self, rhs: Self) {
self.0.bitor_assign(rhs.0)
}
}