use std::ops::Index;
pub struct BitSet {
size: usize,
inner: Vec<u64>,
}
#[inline(always)]
fn mask(bit: usize) -> u64 {
1 << (bit % 64)
}
impl BitSet {
pub fn new(size: usize) -> Self {
Self {
size,
inner: vec![0; (size + 63) / 64],
}
}
pub fn get(&self, bit: usize) -> Option<bool> {
if bit >= self.size {
return None;
}
let mask = mask(bit);
Some(self.inner[bit / 64] & mask == mask)
}
pub fn set(&mut self, bit: usize, value: bool) {
if bit >= self.size {
panic!("{} index is out of bitset bounds", bit)
}
if value {
self.inner[bit / 64] |= mask(bit);
} else {
self.inner[bit / 64] &= !mask(bit);
}
}
}
impl Index<usize> for BitSet {
type Output = bool;
fn index(&self, bit: usize) -> &Self::Output {
if self.get(bit).unwrap() {
&true
} else {
&false
}
}
}
#[cfg(test)]
mod tests {
use crate::bitset::BitSet;
#[test]
fn test_bit_set_get_set() {
let mut bit_set = BitSet::new(1000);
for i in 1..1000 {
if i & (i - 1) == 0 {
bit_set.set(i, true);
}
}
for i in 1..1000 {
assert_eq!(i & (i - 1) == 0, bit_set.get(i).unwrap());
}
assert_eq!(None, bit_set.get(1000));
}
#[test]
fn test_bit_set_index() {
let mut bit_set = BitSet::new(1000);
for i in 1..1000 {
if i & (i - 1) == 0 {
bit_set.set(i, true);
}
}
for i in 1..1000 {
assert_eq!(i & (i - 1) == 0, bit_set[i]);
}
}
#[test]
#[should_panic(expected = "1001 index is out of bitset bounds")]
fn test_fixed_stack_full_stack() {
let mut bit_set = BitSet::new(1000);
bit_set.set(1001, false);
}
}