use std::fmt::Binary;
pub trait FixedSizeBitSet : Default + Binary {
const NUM_BITS: usize;
fn get(&self, i: usize) -> bool;
fn insert(&mut self, i: usize);
fn remove(&mut self, i: usize);
}
macro_rules! impl_bit_set {
(
$type:ty, $num_bits:expr
) => {
impl FixedSizeBitSet for $type {
const NUM_BITS: usize = $num_bits;
fn get(&self, i: usize) -> bool {
if i >= Self::NUM_BITS {
panic!("index is out of bounds: the len is {} but the index is {}",
Self::NUM_BITS, i);
}
(*self >> i & 0b_1) == 1
}
fn insert(&mut self, i: usize) {
if i >= Self::NUM_BITS {
panic!("index is out of bounds: the len is {} but the index is {}",
Self::NUM_BITS, i);
}
*self |= 1 << i;
}
fn remove(&mut self, i: usize) {
if i >= Self::NUM_BITS {
panic!("index is out of bounds: the len is {} but the index is {}",
Self::NUM_BITS, i);
}
*self &= !(1 << i);
}
}
};
}
impl_bit_set!(u8, 8);
impl_bit_set!(u16, 16);
impl_bit_set!(u32, 32);
impl_bit_set!(u64, 64);
#[cfg(test)]
mod tests {
mod bitset {
#[test]
fn test_bitset() {
use crate::bitset::FixedSizeBitSet;
let mut bitset: u64 = 0;
bitset.insert(3);
bitset.insert(10);
bitset.insert(13);
bitset.insert(35);
for i in 0..32 {
match i {
3 | 10 | 13 | 35 => { assert!(bitset.get(i)); },
_ => { assert!(!bitset.get(i)); },
}
}
}
}
}