algo-rs 0.1.0

Set of data structures and algorithms.
Documentation
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);
    }
}