use std::fmt;
mod storage;
pub use storage::BitStorage;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct GrowableBitMap<S>
where
S: BitStorage,
{
bits: Vec<S>,
}
impl<S> fmt::Debug for GrowableBitMap<S>
where
S: BitStorage + fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_list().entries(self.bits.iter()).finish()
}
}
impl<S> GrowableBitMap<S>
where
S: BitStorage,
{
pub fn new() -> Self {
Self { bits: Vec::new() }
}
pub fn with_capacity(capacity: usize) -> Self {
if capacity == 0 {
return Self::new();
}
let div = capacity / S::BITS_IN_STORAGE;
let rem = (capacity % S::BITS_IN_STORAGE != 0) as usize;
Self {
bits: Vec::with_capacity(div + rem),
}
}
pub fn is_empty(&self) -> bool {
self.bits.is_empty() || self.bits.iter().all(|bits| bits.is_empty())
}
pub fn get_bit(&self, index: usize) -> bool {
let bits_index = index / S::BITS_IN_STORAGE;
if self.bits.len() <= bits_index {
return false;
}
let elem = &self.bits[bits_index];
unsafe { elem.get_bit(index - bits_index * S::BITS_IN_STORAGE) }
}
pub fn set_bit(&mut self, index: usize) -> bool {
let bits_index = index / S::BITS_IN_STORAGE;
if self.bits.len() <= bits_index {
self.bits.resize_with(bits_index + 1, S::empty);
}
let elem = &mut self.bits[bits_index];
unsafe { elem.set_bit(index - bits_index * S::BITS_IN_STORAGE) }
}
pub fn clear_bit(&mut self, index: usize) -> bool {
let bits_index = index / S::BITS_IN_STORAGE;
if self.bits.len() <= bits_index {
return false;
}
let elem = &mut self.bits[bits_index];
unsafe { elem.clear_bit(index - bits_index * S::BITS_IN_STORAGE) }
}
pub fn clear(&mut self) {
self.bits.clear();
}
pub fn count_ones(&self) -> usize {
self.bits
.iter()
.map(|store| store.count_ones() as usize)
.sum::<usize>()
}
pub fn capacity(&self) -> usize {
self.bits.capacity() * S::BITS_IN_STORAGE
}
pub fn shrink_to_fit(&mut self) {
let last_set_bit_index = self
.bits
.iter()
.rev()
.skip_while(|&store| store.is_empty())
.count();
self.bits.truncate(last_set_bit_index);
self.bits.shrink_to_fit();
}
}
macro_rules! growable_bitmap_storage_integer_tests {
($(($int: ty, $mod_name: ident))*) => {
$(
#[cfg(test)]
mod $mod_name {
use super::*;
#[test]
fn new() {
let bm = GrowableBitMap::<$int>::new();
let bm2 = GrowableBitMap {
bits: Vec::<$int>::new(),
};
assert_eq!(bm, bm2);
}
#[test]
fn with_capacity() {
let bm = GrowableBitMap::<$int>::with_capacity(0);
let vec = Vec::<$int>::with_capacity(0);
assert_eq!(bm.bits.capacity(), vec.capacity());
let bm = GrowableBitMap::<$int>::with_capacity(11);
let vec = Vec::<$int>::with_capacity(11);
assert!(bm.bits.capacity() >= vec.capacity() / <$int>::BITS_IN_STORAGE);
}
#[test]
fn is_empty() {
let bm = GrowableBitMap::<$int>::new();
assert!(bm.is_empty());
let mut bm = GrowableBitMap::<$int>::with_capacity(3);
assert!(bm.is_empty());
bm.set_bit(7);
assert!(!bm.is_empty());
bm.clear_bit(7);
assert!(bm.is_empty());
bm.set_bit(7);
bm.set_bit(3);
bm.set_bit(4);
assert!(!bm.is_empty());
bm.clear();
assert!(bm.is_empty());
}
#[test]
fn get_bit() {
let bm = GrowableBitMap::<$int>::new();
assert!(!bm.get_bit(0));
assert!(!bm.get_bit(7));
let old_capa = bm.capacity();
assert!(!bm.get_bit(200000003));
assert_eq!(old_capa, bm.capacity());
let mut bm = bm;
bm.set_bit(0);
bm.set_bit(6);
assert!(bm.get_bit(0));
assert!(bm.get_bit(6));
assert!(!bm.get_bit(7));
assert!(!bm.get_bit(3));
}
#[test]
fn set_bit() {
let mut bm = GrowableBitMap::<$int>::new();
assert!(bm.set_bit(0));
assert!(bm.set_bit(7));
assert!(!bm.set_bit(0));
let old_capa = bm.capacity();
assert!(bm.set_bit(150));
assert!(old_capa <= bm.capacity());
assert!(bm.get_bit(150));
}
#[test]
fn clear_bit() {
let mut bm = GrowableBitMap::<$int>::new();
assert!(!bm.clear_bit(0));
assert!(!bm.clear_bit(7));
bm.set_bit(0);
assert!(bm.clear_bit(0));
let old_capa = bm.capacity();
assert!(!bm.clear_bit(200000003));
assert_eq!(old_capa, bm.capacity());
bm.set_bit(150);
assert!(bm.clear_bit(150));
assert!(bm.is_empty());
}
#[test]
fn clear() {
let mut bm = GrowableBitMap::<$int>::new();
bm.clear();
assert!(bm.is_empty());
bm.set_bit(253);
let old_capa = bm.capacity();
bm.clear();
assert_eq!(old_capa, bm.capacity());
bm.set_bit(30);
bm.set_bit(4);
bm.clear();
assert!(bm.is_empty());
}
#[test]
fn count_ones() {
let mut bm = GrowableBitMap::<$int>::new();
assert_eq!(bm.count_ones(), 0);
bm.set_bit(0);
assert_eq!(bm.count_ones(), 1);
bm.set_bit(30);
assert_eq!(bm.count_ones(), 2);
bm.set_bit(7);
assert_eq!(bm.count_ones(), 3);
bm.clear_bit(0);
assert_eq!(bm.count_ones(), 2);
bm.clear();
assert_eq!(bm.count_ones(), 0);
}
#[test]
fn capacity() {
let mut bm = GrowableBitMap::<$int>::new();
assert_eq!(bm.capacity(), 0);
bm.set_bit(511);
assert_eq!(bm.capacity(), 512);
}
#[test]
fn shrink_to_fit() {
let mut bm = GrowableBitMap::<$int>::with_capacity(381);
bm.set_bit(127);
bm.set_bit(380);
assert_eq!(bm.capacity(), 384);
bm.clear_bit(380);
bm.shrink_to_fit();
assert_eq!(bm.capacity(), 128);
}
}
)*
}
}
growable_bitmap_storage_integer_tests! {
(u8, test_u8)
(u16, test_u16)
(u32, test_u32)
(u64, test_u64)
(u128, test_u128)
}