use alloc::vec::Vec;
use core::ops::{BitAnd, BitOr, Not};
#[derive(Debug, Clone)]
pub(crate) struct BitVec {
data: Vec<u32>,
}
impl BitVec {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn resize(&mut self, new_len: usize, value: bool) {
let word_len = new_len.div_ceil(32);
self.data
.resize(word_len, if value { 0xFFFFFFFF } else { 0x00000000 });
}
pub fn len(&self) -> usize {
self.data.len() * 32
}
pub fn set(&mut self, index: usize, value: bool) {
if index >= self.len() {
return;
}
let word_index = index / 32;
let bit_index = index % 32;
if value {
self.data[word_index] |= 1 << bit_index;
} else {
self.data[word_index] &= !(1 << bit_index);
}
}
pub fn get(&self, index: usize) -> bool {
if index >= self.len() {
return false;
}
let word_index = index / 32;
let bit_index = index % 32;
(self.data[word_index] & (1 << bit_index)) != 0
}
#[cfg(test)]
pub fn is_empty(&self) -> bool {
self.data.iter().all(|&word| word == 0)
}
}
impl core::ops::Index<usize> for BitVec {
type Output = bool;
fn index(&self, index: usize) -> &Self::Output {
if self.get(index) {
&true
} else {
&false
}
}
}
impl BitAnd for BitVec {
type Output = BitVec;
fn bitand(mut self, rhs: Self) -> Self::Output {
if rhs.len() < self.len() {
self.resize(rhs.len(), false);
}
self.data
.iter_mut()
.zip(rhs.data.iter())
.for_each(|(a, b)| *a &= *b);
self
}
}
impl BitOr for BitVec {
type Output = BitVec;
fn bitor(mut self, rhs: Self) -> Self::Output {
if self.len() < rhs.len() {
self.resize(rhs.len(), false);
}
self.data
.iter_mut()
.zip(rhs.data.iter())
.for_each(|(a, b)| *a |= *b);
self
}
}
impl Not for BitVec {
type Output = BitVec;
fn not(mut self) -> Self::Output {
for word in &mut self.data {
*word = !*word;
}
self
}
}
impl Default for BitVec {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_bitvec() {
let bv = BitVec::new();
assert_eq!(bv.len(), 0);
assert!(bv.is_empty());
}
#[test]
fn test_set_and_get() {
let mut bv = BitVec::new();
bv.resize(8, false);
bv.set(0, true);
bv.set(3, true);
bv.set(7, true);
assert!(bv.get(0));
assert!(!bv.get(1));
assert!(!bv.get(2));
assert!(bv.get(3));
assert!(!bv.get(4));
assert!(!bv.get(5));
assert!(!bv.get(6));
assert!(bv.get(7));
}
#[test]
fn test_index() {
let mut bv = BitVec::new();
bv.resize(5, false);
bv.set(2, true);
assert!(!bv[0]);
assert!(!bv[1]);
assert!(bv[2]);
assert!(!bv[3]);
assert!(!bv[4]);
}
#[test]
fn test_bitand() {
let mut bv1 = BitVec::new();
bv1.resize(4, false);
bv1.set(0, true);
bv1.set(1, true);
bv1.set(2, false);
bv1.set(3, true);
let mut bv2 = BitVec::new();
bv2.resize(4, false);
bv2.set(0, true);
bv2.set(1, false);
bv2.set(2, true);
bv2.set(3, true);
let result = bv1.bitand(bv2);
assert!(result[0]); assert!(!result[1]); assert!(!result[2]); assert!(result[3]); }
#[test]
fn test_bitor() {
let mut bv1 = BitVec::new();
bv1.resize(4, false);
bv1.set(0, true);
bv1.set(1, false);
bv1.set(2, false);
bv1.set(3, true);
let mut bv2 = BitVec::new();
bv2.resize(4, false);
bv2.set(0, false);
bv2.set(1, true);
bv2.set(2, false);
bv2.set(3, true);
let result = bv1.bitor(bv2);
assert!(result[0]); assert!(result[1]); assert!(!result[2]); assert!(result[3]); }
#[test]
fn test_not() {
let mut bv = BitVec::new();
bv.resize(4, false);
bv.set(0, true);
bv.set(2, true);
let result = bv.not();
assert!(!result[0]); assert!(result[1]); assert!(!result[2]); assert!(result[3]); }
}