use super::BitmapSize;
use core::fmt::Formatter;
use serde::{Deserialize, Serialize};
use std::{
fmt::{Debug, Display},
mem,
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, Div,
DivAssign, Mul, MulAssign, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
},
};
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Default, Serialize, Deserialize)]
pub struct BitmapArch(usize);
impl BitmapArch {
pub fn capacity() -> usize {
BitmapArch::MAP_LENGTH
}
pub fn to_usize(&self) -> usize {
self.0
}
pub fn new(value: bool) -> BitmapArch {
BitmapArch(if value { usize::MAX } else { 0 })
}
pub fn create_bit_mask(begin: usize, end: usize, value: bool) -> BitmapArch {
if value {
if begin >= BitmapArch::MAP_LENGTH || end < 1 {
BitmapArch(0)
} else if end >= BitmapArch::MAP_LENGTH {
BitmapArch(usize::MAX << begin)
} else {
BitmapArch(usize::MAX << begin & usize::MAX >> BitmapArch::MAP_LENGTH - end)
}
} else {
!BitmapArch::create_bit_mask(begin, end, true)
}
}
pub fn from_set(index: usize) -> Option<BitmapArch> {
if index >= BitmapArch::MAP_LENGTH {
return None;
}
let mut bitmap = BitmapArch::default();
bitmap.set(index, true).unwrap();
Some(bitmap)
}
pub fn set(&mut self, index: usize, value: bool) -> Result<(), String> {
if index >= BitmapArch::MAP_LENGTH {
return Err(String::from(
"Tried to set bit that's out of range of the bitmap (range: ",
) + &BitmapArch::MAP_LENGTH.to_string()
+ ", index: "
+ &index.to_string()
+ ")");
}
if value {
let mask = 1 << index;
self.0 |= mask;
} else {
let mask = usize::MAX - (1 << index);
self.0 &= mask;
}
Ok(())
}
pub fn set_range(&mut self, begin: usize, end: usize, value: bool) {
if value {
*self |= BitmapArch::create_bit_mask(begin, end, true);
} else {
*self &= BitmapArch::create_bit_mask(begin, end, false);
}
}
pub fn get(&self, index: usize) -> Result<bool, String> {
if index >= BitmapArch::MAP_LENGTH {
return Err(String::from(
"Tried to get bit that's out of range of the bitmap (range: ",
) + &BitmapArch::MAP_LENGTH.to_string()
+ ", index: "
+ &index.to_string()
+ ")");
}
let mask = 1 << index;
Ok(self.0 & mask > 0)
}
}
impl Display for BitmapArch {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{:b}", self.0)
}
}
impl Debug for BitmapArch {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "BitmapArch({:X})", self.0)
}
}
impl From<usize> for BitmapArch {
fn from(value: usize) -> Self {
BitmapArch(value)
}
}
impl BitmapSize for BitmapArch {
const MAP_LENGTH: usize = mem::size_of::<usize>() * 8;
}
impl BitAnd for BitmapArch {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & rhs.0)
}
}
impl BitAndAssign for BitmapArch {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
impl BitOr for BitmapArch {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl BitOrAssign for BitmapArch {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl BitXor for BitmapArch {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
}
impl BitXorAssign for BitmapArch {
fn bitxor_assign(&mut self, rhs: Self) {
self.0 ^= rhs.0;
}
}
impl Add for BitmapArch {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign for BitmapArch {
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}
impl Sub for BitmapArch {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign for BitmapArch {
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
impl Mul for BitmapArch {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}
impl MulAssign for BitmapArch {
fn mul_assign(&mut self, rhs: Self) {
self.0 *= rhs.0;
}
}
impl Div for BitmapArch {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self(self.0 / rhs.0)
}
}
impl DivAssign for BitmapArch {
fn div_assign(&mut self, rhs: Self) {
self.0 /= rhs.0;
}
}
impl BitAnd<usize> for BitmapArch {
type Output = Self;
fn bitand(self, rhs: usize) -> Self::Output {
Self(self.0 & rhs)
}
}
impl BitAndAssign<usize> for BitmapArch {
fn bitand_assign(&mut self, rhs: usize) {
self.0 &= rhs;
}
}
impl BitOr<usize> for BitmapArch {
type Output = Self;
fn bitor(self, rhs: usize) -> Self::Output {
Self(self.0 | rhs)
}
}
impl BitOrAssign<usize> for BitmapArch {
fn bitor_assign(&mut self, rhs: usize) {
self.0 |= rhs;
}
}
impl BitXor<usize> for BitmapArch {
type Output = Self;
fn bitxor(self, rhs: usize) -> Self::Output {
Self(self.0 ^ rhs)
}
}
impl BitXorAssign<usize> for BitmapArch {
fn bitxor_assign(&mut self, rhs: usize) {
self.0 ^= rhs;
}
}
impl Add<usize> for BitmapArch {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}
impl AddAssign<usize> for BitmapArch {
fn add_assign(&mut self, rhs: usize) {
self.0 += rhs;
}
}
impl Sub<usize> for BitmapArch {
type Output = Self;
fn sub(self, rhs: usize) -> Self::Output {
Self(self.0 - rhs)
}
}
impl SubAssign<usize> for BitmapArch {
fn sub_assign(&mut self, rhs: usize) {
self.0 -= rhs;
}
}
impl Mul<usize> for BitmapArch {
type Output = Self;
fn mul(self, rhs: usize) -> Self::Output {
Self(self.0 * rhs)
}
}
impl MulAssign<usize> for BitmapArch {
fn mul_assign(&mut self, rhs: usize) {
self.0 *= rhs;
}
}
impl Div<usize> for BitmapArch {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs)
}
}
impl DivAssign<usize> for BitmapArch {
fn div_assign(&mut self, rhs: usize) {
self.0 /= rhs;
}
}
impl Shl<usize> for BitmapArch {
type Output = Self;
fn shl(self, rhs: usize) -> Self::Output {
Self(self.0 << rhs)
}
}
impl ShlAssign<usize> for BitmapArch {
fn shl_assign(&mut self, rhs: usize) {
self.0 <<= rhs;
}
}
impl Shr<usize> for BitmapArch {
type Output = Self;
fn shr(self, rhs: usize) -> Self::Output {
Self(self.0 >> rhs)
}
}
impl ShrAssign<usize> for BitmapArch {
fn shr_assign(&mut self, rhs: usize) {
self.0 >>= rhs;
}
}
impl Not for BitmapArch {
type Output = Self;
fn not(self) -> Self::Output {
Self(self.0 ^ usize::MAX)
}
}
impl Deref for BitmapArch {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}