Improve BitSet
APIs
A few small cleanups to `BitSet` and friends: - Overload `clone_from` for `BitSet`. - Improve `Debug` represenation of `HybridBitSet`. - Make `HybridBitSet::domain_size` public. - Don't require `T: Idx` at the type level. The `Idx` bound is still on most `BitSet` methods, but like `HashMap`, it doesn't need to be satisfied for the type to exist.
This commit is contained in:
parent
85fbf49ce0
commit
149307efb7
@ -28,13 +28,20 @@ pub const WORD_BITS: usize = WORD_BYTES * 8;
|
||||
/// will panic if the bitsets have differing domain sizes.
|
||||
///
|
||||
/// [`GrowableBitSet`]: struct.GrowableBitSet.html
|
||||
#[derive(Clone, Eq, PartialEq, Decodable, Encodable)]
|
||||
pub struct BitSet<T: Idx> {
|
||||
#[derive(Eq, PartialEq, Decodable, Encodable)]
|
||||
pub struct BitSet<T> {
|
||||
domain_size: usize,
|
||||
words: Vec<Word>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> BitSet<T> {
|
||||
/// Gets the domain size.
|
||||
pub fn domain_size(&self) -> usize {
|
||||
self.domain_size
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Idx> BitSet<T> {
|
||||
/// Creates a new, empty bitset with a given `domain_size`.
|
||||
#[inline]
|
||||
@ -52,11 +59,6 @@ impl<T: Idx> BitSet<T> {
|
||||
result
|
||||
}
|
||||
|
||||
/// Gets the domain size.
|
||||
pub fn domain_size(&self) -> usize {
|
||||
self.domain_size
|
||||
}
|
||||
|
||||
/// Clear all elements.
|
||||
#[inline]
|
||||
pub fn clear(&mut self) {
|
||||
@ -75,12 +77,6 @@ impl<T: Idx> BitSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Efficiently overwrite `self` with `other`.
|
||||
pub fn overwrite(&mut self, other: &BitSet<T>) {
|
||||
assert!(self.domain_size == other.domain_size);
|
||||
self.words.clone_from_slice(&other.words);
|
||||
}
|
||||
|
||||
/// Count the number of set bits in the set.
|
||||
pub fn count(&self) -> usize {
|
||||
self.words.iter().map(|e| e.count_ones() as usize).sum()
|
||||
@ -243,6 +239,21 @@ impl<T: Idx> SubtractFromBitSet<T> for BitSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for BitSet<T> {
|
||||
fn clone(&self) -> Self {
|
||||
BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData }
|
||||
}
|
||||
|
||||
fn clone_from(&mut self, from: &Self) {
|
||||
if self.domain_size != from.domain_size {
|
||||
self.words.resize(from.domain_size, 0);
|
||||
self.domain_size = from.domain_size;
|
||||
}
|
||||
|
||||
self.words.copy_from_slice(&from.words);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Idx> fmt::Debug for BitSet<T> {
|
||||
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
w.debug_list().entries(self.iter()).finish()
|
||||
@ -363,7 +374,7 @@ const SPARSE_MAX: usize = 8;
|
||||
///
|
||||
/// This type is used by `HybridBitSet`; do not use directly.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SparseBitSet<T: Idx> {
|
||||
pub struct SparseBitSet<T> {
|
||||
domain_size: usize,
|
||||
elems: ArrayVec<[T; SPARSE_MAX]>,
|
||||
}
|
||||
@ -464,18 +475,27 @@ impl<T: Idx> SubtractFromBitSet<T> for SparseBitSet<T> {
|
||||
/// All operations that involve an element will panic if the element is equal
|
||||
/// to or greater than the domain size. All operations that involve two bitsets
|
||||
/// will panic if the bitsets have differing domain sizes.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum HybridBitSet<T: Idx> {
|
||||
#[derive(Clone)]
|
||||
pub enum HybridBitSet<T> {
|
||||
Sparse(SparseBitSet<T>),
|
||||
Dense(BitSet<T>),
|
||||
}
|
||||
|
||||
impl<T: Idx> fmt::Debug for HybridBitSet<T> {
|
||||
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Sparse(b) => b.fmt(w),
|
||||
Self::Dense(b) => b.fmt(w),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Idx> HybridBitSet<T> {
|
||||
pub fn new_empty(domain_size: usize) -> Self {
|
||||
HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
|
||||
}
|
||||
|
||||
fn domain_size(&self) -> usize {
|
||||
pub fn domain_size(&self) -> usize {
|
||||
match self {
|
||||
HybridBitSet::Sparse(sparse) => sparse.domain_size,
|
||||
HybridBitSet::Dense(dense) => dense.domain_size,
|
||||
|
Loading…
Reference in New Issue
Block a user