Check for full words on boundaries
This commit is contained in:
@@ -116,14 +116,20 @@ 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));
|
||||||
while (word) {
|
if (std::popcount(word) + (begin & 63) == 64) {
|
||||||
uint64_t temp = word & -word;
|
while (begin & 63) {
|
||||||
int index = (begin & ~63) + std::countr_zero(word);
|
f(begin++);
|
||||||
f(index);
|
}
|
||||||
word ^= temp;
|
} else {
|
||||||
|
while (word) {
|
||||||
|
uint64_t temp = word & -word;
|
||||||
|
int index = (begin & ~63) + std::countr_zero(word);
|
||||||
|
f(index);
|
||||||
|
word ^= temp;
|
||||||
|
}
|
||||||
|
begin &= ~63;
|
||||||
|
begin += 64;
|
||||||
}
|
}
|
||||||
begin &= ~63;
|
|
||||||
begin += 64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check inner, full words
|
// Check inner, full words
|
||||||
@@ -147,11 +153,17 @@ 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));
|
||||||
while (word) {
|
if (std::popcount(word) == (end & 63)) {
|
||||||
uint64_t temp = word & -word;
|
while (begin < end) {
|
||||||
int index = begin + std::countr_zero(word);
|
f(begin++);
|
||||||
f(index);
|
}
|
||||||
word ^= temp;
|
} else {
|
||||||
|
while (word) {
|
||||||
|
uint64_t temp = word & -word;
|
||||||
|
int index = begin + std::countr_zero(word);
|
||||||
|
f(index);
|
||||||
|
word ^= temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user