#[cfg(feature = "serde")]
use serde_derive::{Deserialize, Serialize};
#[cfg(test)]
mod test;
const U32_BITS: usize = std::mem::size_of::<u32>() * 8;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct BitSet {
chunks: Vec<u32>,
num_bits: usize,
}
impl BitSet {
#[inline]
fn calc_chunks(num_bits: usize) -> usize {
(num_bits + U32_BITS - 1) / U32_BITS
}
#[inline]
fn last_mask(num_bits: usize) -> u32 {
!(!1 << ((num_bits - 1) % U32_BITS))
}
pub fn chunks(&self) -> &Vec<u32> {
&self.chunks
}
pub fn from_bits(chunks: Vec<u32>, num_bits: usize) -> Self {
#[cfg(debug_assertions)]
assert!(num_bits > 0);
#[cfg(debug_assertions)]
assert_eq!(Self::calc_chunks(num_bits), chunks.len());
#[cfg(debug_assertions)]
assert_eq!(chunks[chunks.len() - 1] & !Self::last_mask(num_bits), 0);
Self { chunks, num_bits }
}
pub fn reset(&mut self, idx: usize) {
#[cfg(debug_assertions)]
assert!(idx / U32_BITS < self.chunks.len());
#[cfg(debug_assertions)]
assert!(idx < self.num_bits);
let chunk = &mut self.chunks[idx / U32_BITS];
let chunk_pos = idx % U32_BITS;
*chunk = (*chunk & !(1 << chunk_pos)).to_le();
}
pub fn reset_all(&mut self) {
for chunk in &mut self.chunks {
*chunk = 0;
}
}
pub fn set(&mut self, idx: usize) {
#[cfg(debug_assertions)]
assert!(idx / U32_BITS < self.chunks.len());
#[cfg(debug_assertions)]
assert!(idx < self.num_bits);
let chunk = &mut self.chunks[idx / U32_BITS];
let chunk_pos = idx % U32_BITS;
*chunk = (*chunk | 1 << chunk_pos).to_le();
}
pub fn set_all(&mut self) {
for chunk in &mut self.chunks {
*chunk = u32::MAX;
}
let num_chunks = self.chunks.len();
self.chunks[num_chunks - 1] = Self::last_mask(self.num_bits);
}
pub fn test(&self, idx: usize) -> bool {
#[cfg(debug_assertions)]
assert!(idx / U32_BITS < self.chunks.len());
#[cfg(debug_assertions)]
assert!(idx < self.num_bits);
let chunk = self.chunks[idx / U32_BITS].to_le();
let chunk_pos = idx % U32_BITS;
((chunk >> chunk_pos) & 1) == 1
}
pub fn with_capacity(num_bits: usize) -> Self {
#[cfg(debug_assertions)]
assert!(num_bits > 0);
let num_chunks = Self::calc_chunks(num_bits);
let chunks = vec![0; num_chunks];
Self { chunks, num_bits }
}
}
impl From<BitSet> for Vec<u32> {
fn from(bitset: BitSet) -> Self {
bitset.chunks
}
}