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