Factor out a recurring pattern as count_ones.

This commit is contained in:
Nicholas Nethercote
2025-10-13 08:27:27 +11:00
parent 6e85c4e2d9
commit 8386278866

View File

@@ -160,7 +160,7 @@ impl<T: Idx> DenseBitSet<T> {
/// 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()
count_ones(&self.words)
}
/// Returns `true` if `self` contains `elem`.
@@ -817,10 +817,8 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
op,
);
debug_assert!(has_changed);
*self_chunk_count = self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum();
*self_chunk_count =
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
if *self_chunk_count == chunk_domain_size {
*self_chunk = Ones;
}
@@ -871,10 +869,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
let self_chunk_count = chunk_domain_size - *other_chunk_count;
debug_assert_eq!(
self_chunk_count,
self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum()
count_ones(&self_chunk_words[0..num_words]) as ChunkSize
);
*self_chunk = Mixed(self_chunk_count, Rc::new(self_chunk_words));
}
@@ -897,10 +892,8 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
op,
);
debug_assert!(has_changed);
*self_chunk_count = self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum();
*self_chunk_count =
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
if *self_chunk_count == 0 {
*self_chunk = Zeros;
}
@@ -956,10 +949,8 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
op,
);
debug_assert!(has_changed);
*self_chunk_count = self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum();
*self_chunk_count =
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
if *self_chunk_count == 0 {
*self_chunk = Zeros;
}
@@ -1046,21 +1037,12 @@ impl Chunk {
assert!(0 < count && count < chunk_domain_size);
// Check the number of set bits matches `count`.
assert_eq!(
words.iter().map(|w| w.count_ones() as ChunkSize).sum::<ChunkSize>(),
count
);
assert_eq!(count_ones(words.as_slice()) as ChunkSize, count);
// Check the not-in-use words are all zeroed.
let num_words = num_words(chunk_domain_size as usize);
if num_words < CHUNK_WORDS {
assert_eq!(
words[num_words..]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum::<ChunkSize>(),
0
);
assert_eq!(count_ones(&words[num_words..]) as ChunkSize, 0);
}
}
}
@@ -1542,7 +1524,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
/// Returns the number of elements in `row`.
pub fn count(&self, row: R) -> usize {
let (start, end) = self.range(row);
self.words[start..end].iter().map(|e| e.count_ones() as usize).sum()
count_ones(&self.words[start..end])
}
}
@@ -1753,6 +1735,11 @@ fn max_bit(word: Word) -> usize {
WORD_BITS - 1 - word.leading_zeros() as usize
}
#[inline]
fn count_ones(words: &[Word]) -> usize {
words.iter().map(|word| word.count_ones() as usize).sum()
}
/// Integral type used to represent the bit set.
pub trait FiniteBitSetTy:
BitAnd<Output = Self>