Check for full words on boundaries

This commit is contained in:
2024-02-26 10:36:45 -08:00
parent c97c7eee8e
commit 172dd40648

View File

@@ -116,6 +116,11 @@ struct BitSet {
// Check begin partial word // Check begin partial word
if (begin & 63) { if (begin & 63) {
uint64_t word = words[begin >> 6] & (uint64_t(-1) << (begin & 63)); uint64_t word = words[begin >> 6] & (uint64_t(-1) << (begin & 63));
if (std::popcount(word) + (begin & 63) == 64) {
while (begin & 63) {
f(begin++);
}
} else {
while (word) { while (word) {
uint64_t temp = word & -word; uint64_t temp = word & -word;
int index = (begin & ~63) + std::countr_zero(word); int index = (begin & ~63) + std::countr_zero(word);
@@ -125,6 +130,7 @@ struct BitSet {
begin &= ~63; begin &= ~63;
begin += 64; begin += 64;
} }
}
// Check inner, full words // Check inner, full words
while (begin != (end & ~63)) { while (begin != (end & ~63)) {
@@ -147,6 +153,11 @@ struct BitSet {
if (end & 63) { if (end & 63) {
// Check end partial word // Check end partial word
uint64_t word = words[end >> 6] & ~(uint64_t(-1) << (end & 63)); uint64_t word = words[end >> 6] & ~(uint64_t(-1) << (end & 63));
if (std::popcount(word) == (end & 63)) {
while (begin < end) {
f(begin++);
}
} else {
while (word) { while (word) {
uint64_t temp = word & -word; uint64_t temp = word & -word;
int index = begin + std::countr_zero(word); int index = begin + std::countr_zero(word);
@@ -155,6 +166,7 @@ struct BitSet {
} }
} }
} }
}
private: private:
uint64_t words[4] = {}; uint64_t words[4] = {};