use alloc::{vec, vec::Vec};
const WORD_BITS: u64 = 64;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct BitSet {
words: Vec<u64>,
num_bits: u64,
}
impl BitSet {
#[inline]
pub(crate) fn new(num_bits: u64) -> Self {
let num_words = num_bits.div_ceil(WORD_BITS) as usize;
Self {
words: vec![0u64; num_words],
num_bits,
}
}
#[inline]
pub(crate) fn len(&self) -> u64 {
self.num_bits
}
#[inline(always)]
pub(crate) fn get(&self, index: u64) -> bool {
let word = (index / WORD_BITS) as usize;
let bit = index % WORD_BITS;
(self.words[word] >> bit) & 1 == 1
}
#[inline(always)]
pub(crate) fn set(&mut self, index: u64) -> bool {
let word = (index / WORD_BITS) as usize;
let mask = 1u64 << (index % WORD_BITS);
let previous = self.words[word] & mask != 0;
self.words[word] |= mask;
previous
}
#[inline]
pub(crate) fn count_ones(&self) -> u64 {
self.words.iter().map(|w| u64::from(w.count_ones())).sum()
}
#[inline]
pub(crate) fn clear(&mut self) {
self.words.iter_mut().for_each(|w| *w = 0);
}
#[inline]
pub(crate) fn is_compatible(&self, other: &Self) -> bool {
self.num_bits == other.num_bits
}
#[inline]
pub(crate) fn union_with(&mut self, other: &Self) {
for (dst, src) in self.words.iter_mut().zip(other.words.iter()) {
*dst |= *src;
}
}
}