use core::{
ops::{Deref, DerefMut},
ptr::addr_of,
};
use crate::{BitBlock, BitSlice, LE};
#[cfg(feature = "alloc")]
use alloc::fmt::Debug;
#[cfg_attr(feature = "std", derive(Hash))]
#[derive(Clone)]
#[repr(transparent)]
pub struct BitMap<B: BitBlock, const BLOCKS: usize>(pub [B; BLOCKS]);
#[cfg(feature = "alloc")]
impl<B: BitBlock, const BLOCKS: usize> Debug for BitMap<B, BLOCKS> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let slice: &BitSlice<B> = self.as_ref();
slice.fmt(f)
}
}
impl<B: BitBlock, const BLOCKS: usize> BitMap<LE<B>, BLOCKS>
where
LE<B>: BitBlock,
{
pub fn from_raw_le(raw: [B; BLOCKS]) -> Self {
Self::from_raw(unsafe { *addr_of!(raw).cast::<[LE<B>; BLOCKS]>() })
}
}
impl<B: BitBlock, const BLOCKS: usize> BitMap<B, BLOCKS> {
pub const fn new() -> Self {
Self([B::ZERO; BLOCKS])
}
pub const fn from_raw(raw: [B; BLOCKS]) -> Self {
Self(raw)
}
}
impl<B: BitBlock, const BLOCKS: usize> Default for BitMap<B, BLOCKS> {
fn default() -> Self {
Self::new()
}
}
impl<B: BitBlock, const BLOCKS: usize> From<[B; BLOCKS]> for BitMap<B, BLOCKS> {
fn from(value: [B; BLOCKS]) -> Self {
Self::from_raw(value)
}
}
impl<B: BitBlock, const BLOCKS: usize> From<BitMap<B, BLOCKS>> for [B; BLOCKS] {
fn from(value: BitMap<B, BLOCKS>) -> Self {
unsafe { *(addr_of!(value).cast::<[B; BLOCKS]>()) }
}
}
impl<B: BitBlock, const BLOCKS: usize> AsRef<[B]> for BitMap<B, BLOCKS> {
fn as_ref(&self) -> &[B] {
self.0.as_ref()
}
}
impl<B: BitBlock, const BLOCKS: usize> AsMut<[B]> for BitMap<B, BLOCKS> {
fn as_mut(&mut self) -> &mut [B] {
self.0.as_mut()
}
}
impl<B: BitBlock, const BLOCKS: usize> AsRef<[B; BLOCKS]> for BitMap<B, BLOCKS> {
fn as_ref(&self) -> &[B; BLOCKS] {
&self.0
}
}
impl<B: BitBlock, const BLOCKS: usize> AsMut<[B; BLOCKS]> for BitMap<B, BLOCKS> {
fn as_mut(&mut self) -> &mut [B; BLOCKS] {
&mut self.0
}
}
impl<B: BitBlock, const BLOCKS: usize> AsRef<BitSlice<B>> for BitMap<B, BLOCKS> {
fn as_ref(&self) -> &BitSlice<B> {
let slice: &[B] = self.as_ref();
slice.as_ref()
}
}
impl<B: BitBlock, const BLOCKS: usize> AsMut<BitSlice<B>> for BitMap<B, BLOCKS> {
fn as_mut(&mut self) -> &mut BitSlice<B> {
let slice: &mut [B] = self.as_mut();
slice.as_mut()
}
}
impl<B: BitBlock, const BLOCKS: usize> Deref for BitMap<B, BLOCKS> {
type Target = BitSlice<B>;
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
impl<B: BitBlock, const BLOCKS: usize> DerefMut for BitMap<B, BLOCKS> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut()
}
}