use core::{mem, fmt, ops, hash};
#[repr(transparent)]
#[derive(Clone, Copy, Default)]
pub struct Bits<T>(pub T);
macro_rules! impl_bits {
($($ty:ident),*) => {$(
impl Bits<$ty> {
#[inline(always)]
pub const fn get(&self, idx: u32) -> bool {
self.0.wrapping_shr(idx) & 1 != 0
}
#[must_use]
#[inline(always)]
pub const fn set(self, idx: u32) -> Self {
const ONE: $ty = 1;
Self(self.0 | ONE.wrapping_shl(idx))
}
#[must_use]
#[inline(always)]
pub const fn unset(self, idx: u32) -> Self {
Self(self.0 & !(1 << idx))
}
#[must_use]
#[inline(always)]
pub const fn toggle(self, idx: u32) -> Self {
Self(self.0 ^ (1 << idx))
}
#[inline(always)]
pub const fn empty(&self) -> bool {
self.0 == 0
}
#[inline(always)]
pub const fn reset(&self) -> Self {
Self(0)
}
#[must_use]
#[inline(always)]
pub const fn flip(&self) -> Self {
Self(self.0.reverse_bits())
}
#[inline(always)]
pub const fn len(&self) -> usize {
Self::size()
}
#[inline(always)]
pub const fn size() -> usize {
mem::size_of::<$ty>() * 8
}
}
impl PartialEq<Bits<$ty>> for $ty {
#[inline(always)]
fn eq(&self, other: &Bits<$ty>) -> bool {
PartialEq::eq(self, &other.0)
}
}
impl fmt::Debug for Bits<$ty> {
#[inline(always)]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, fmt)
}
}
impl fmt::Display for Bits<$ty> {
#[inline(always)]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, fmt)
}
}
impl fmt::Binary for Bits<$ty> {
#[inline(always)]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Binary::fmt(&self.0, fmt)
}
}
impl PartialEq<$ty> for Bits<$ty> {
#[inline(always)]
fn eq(&self, other: &$ty) -> bool {
PartialEq::eq(&self.0, other)
}
}
impl ops::Deref for Bits<$ty> {
type Target = $ty;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl ops::DerefMut for Bits<$ty> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl hash::Hash for Bits<$ty> {
#[inline(always)]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
hash::Hash::hash(&self.0, state)
}
}
impl From<$ty> for Bits<$ty> {
#[inline(always)]
fn from(val: $ty) -> Self {
Self(val)
}
}
impl Into<$ty> for Bits<$ty> {
#[inline(always)]
fn into(self) -> $ty {
self.0
}
}
)*};
}
impl_bits!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);