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.
|
/// will panic if the bitsets have differing domain sizes.
|
||||||
///
|
///
|
||||||
/// [`GrowableBitSet`]: struct.GrowableBitSet.html
|
/// [`GrowableBitSet`]: struct.GrowableBitSet.html
|
||||||
#[derive(Clone, Eq, PartialEq, Decodable, Encodable)]
|
#[derive(Eq, PartialEq, Decodable, Encodable)]
|
||||||
pub struct BitSet<T: Idx> {
|
pub struct BitSet<T> {
|
||||||
domain_size: usize,
|
domain_size: usize,
|
||||||
words: Vec<Word>,
|
words: Vec<Word>,
|
||||||
marker: PhantomData<T>,
|
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> {
|
impl<T: Idx> BitSet<T> {
|
||||||
/// Creates a new, empty bitset with a given `domain_size`.
|
/// Creates a new, empty bitset with a given `domain_size`.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -52,11 +59,6 @@ impl<T: Idx> BitSet<T> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the domain size.
|
|
||||||
pub fn domain_size(&self) -> usize {
|
|
||||||
self.domain_size
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear all elements.
|
/// Clear all elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clear(&mut self) {
|
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.
|
/// Count the number of set bits in the set.
|
||||||
pub fn count(&self) -> usize {
|
pub fn count(&self) -> usize {
|
||||||
self.words.iter().map(|e| e.count_ones() as usize).sum()
|
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> {
|
impl<T: Idx> fmt::Debug for BitSet<T> {
|
||||||
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
w.debug_list().entries(self.iter()).finish()
|
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.
|
/// This type is used by `HybridBitSet`; do not use directly.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SparseBitSet<T: Idx> {
|
pub struct SparseBitSet<T> {
|
||||||
domain_size: usize,
|
domain_size: usize,
|
||||||
elems: ArrayVec<[T; SPARSE_MAX]>,
|
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
|
/// 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
|
/// to or greater than the domain size. All operations that involve two bitsets
|
||||||
/// will panic if the bitsets have differing domain sizes.
|
/// will panic if the bitsets have differing domain sizes.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub enum HybridBitSet<T: Idx> {
|
pub enum HybridBitSet<T> {
|
||||||
Sparse(SparseBitSet<T>),
|
Sparse(SparseBitSet<T>),
|
||||||
Dense(BitSet<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> {
|
impl<T: Idx> HybridBitSet<T> {
|
||||||
pub fn new_empty(domain_size: usize) -> Self {
|
pub fn new_empty(domain_size: usize) -> Self {
|
||||||
HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
|
HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn domain_size(&self) -> usize {
|
pub fn domain_size(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
HybridBitSet::Sparse(sparse) => sparse.domain_size,
|
HybridBitSet::Sparse(sparse) => sparse.domain_size,
|
||||||
HybridBitSet::Dense(dense) => dense.domain_size,
|
HybridBitSet::Dense(dense) => dense.domain_size,
|
||||||
|
Loading…
Reference in New Issue
Block a user