#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct FixedBitset {
words: Vec<u64>,
capacity: usize,
}
impl FixedBitset {
pub fn new(capacity: usize) -> Self {
let words = capacity.div_ceil(64);
FixedBitset { words: vec![0u64; words], capacity }
}
pub fn set(&mut self, i: usize) {
assert!(i < self.capacity);
self.words[i / 64] |= 1u64 << (i % 64);
}
pub fn clear(&mut self, i: usize) {
assert!(i < self.capacity);
self.words[i / 64] &= !(1u64 << (i % 64));
}
pub fn test(&self, i: usize) -> bool {
assert!(i < self.capacity);
(self.words[i / 64] >> (i % 64)) & 1 == 1
}
pub fn toggle(&mut self, i: usize) {
assert!(i < self.capacity);
self.words[i / 64] ^= 1u64 << (i % 64);
}
pub fn count_ones(&self) -> u32 {
self.words.iter().map(|w| w.count_ones()).sum()
}
pub fn capacity(&self) -> usize {
self.capacity
}
pub fn clear_all(&mut self) {
for w in &mut self.words {
*w = 0;
}
}
pub fn set_all(&mut self) {
for w in &mut self.words {
*w = u64::MAX;
}
let rem = self.capacity % 64;
if rem != 0 {
if let Some(last) = self.words.last_mut() {
*last = (1u64 << rem).saturating_sub(1);
}
}
}
}
pub fn new_fixed_bitset(capacity: usize) -> FixedBitset {
FixedBitset::new(capacity)
}
pub fn fb_set(bs: &mut FixedBitset, i: usize) {
bs.set(i);
}
pub fn fb_clear(bs: &mut FixedBitset, i: usize) {
bs.clear(i);
}
pub fn fb_test(bs: &FixedBitset, i: usize) -> bool {
bs.test(i)
}
pub fn fb_count_ones(bs: &FixedBitset) -> u32 {
bs.count_ones()
}
pub fn fb_capacity(bs: &FixedBitset) -> usize {
bs.capacity()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_initial_clear() {
let bs = new_fixed_bitset(128);
assert_eq!(fb_count_ones(&bs), 0 );
}
#[test]
fn test_set_and_test() {
let mut bs = new_fixed_bitset(64);
fb_set(&mut bs, 7);
assert!(fb_test(&bs, 7) );
assert!(!fb_test(&bs, 0));
}
#[test]
fn test_clear_bit() {
let mut bs = new_fixed_bitset(64);
fb_set(&mut bs, 3);
fb_clear(&mut bs, 3);
assert!(!fb_test(&bs, 3) );
}
#[test]
fn test_count_ones() {
let mut bs = new_fixed_bitset(64);
fb_set(&mut bs, 0);
fb_set(&mut bs, 1);
fb_set(&mut bs, 63);
assert_eq!(fb_count_ones(&bs), 3 );
}
#[test]
fn test_toggle() {
let mut bs = new_fixed_bitset(64);
bs.toggle(5);
assert!(bs.test(5));
bs.toggle(5);
assert!(!bs.test(5) );
}
#[test]
fn test_set_all() {
let mut bs = new_fixed_bitset(10);
bs.set_all();
assert_eq!(fb_count_ones(&bs), 10 );
}
#[test]
fn test_clear_all() {
let mut bs = new_fixed_bitset(32);
bs.set_all();
bs.clear_all();
assert_eq!(fb_count_ones(&bs), 0 );
}
#[test]
fn test_capacity() {
let bs = new_fixed_bitset(200);
assert_eq!(fb_capacity(&bs), 200 );
}
#[test]
fn test_cross_word_boundary() {
let mut bs = new_fixed_bitset(128);
fb_set(&mut bs, 63);
fb_set(&mut bs, 64);
assert!(fb_test(&bs, 63) );
assert!(fb_test(&bs, 64));
}
#[test]
fn test_large_index() {
let mut bs = new_fixed_bitset(1000);
fb_set(&mut bs, 999);
assert!(fb_test(&bs, 999) );
}
}