Add forEachInRange
This commit is contained in:
@@ -98,6 +98,61 @@ struct BitSet {
|
|||||||
void reset(int i);
|
void reset(int i);
|
||||||
int firstSetGeq(int i) const;
|
int firstSetGeq(int i) const;
|
||||||
|
|
||||||
|
// Calls `f` with the index of each bit set in [begin, end)
|
||||||
|
template <class F> void forEachInRange(F f, int begin, int end) {
|
||||||
|
// See section 3.1 in https://arxiv.org/pdf/1709.07821.pdf for details about
|
||||||
|
// this approach
|
||||||
|
|
||||||
|
if ((begin >> 6) == (end >> 6)) {
|
||||||
|
{
|
||||||
|
uint64_t word = words[begin >> 6] & (uint64_t(-1) << (begin & 63)) &
|
||||||
|
~(uint64_t(-1) << (end & 63));
|
||||||
|
while (word) {
|
||||||
|
uint64_t temp = word & -word;
|
||||||
|
int index = (begin & ~63) + std::countr_zero(word);
|
||||||
|
f(index);
|
||||||
|
word ^= temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check begin partial word
|
||||||
|
{
|
||||||
|
uint64_t word = words[begin >> 6] & (uint64_t(-1) << (begin & 63));
|
||||||
|
while (word) {
|
||||||
|
uint64_t temp = word & -word;
|
||||||
|
int index = (begin & ~63) + std::countr_zero(word);
|
||||||
|
f(index);
|
||||||
|
word ^= temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check inner, full words
|
||||||
|
begin += 64;
|
||||||
|
while ((begin >> 6) != (end >> 6)) {
|
||||||
|
uint64_t word = words[begin >> 6];
|
||||||
|
while (word) {
|
||||||
|
uint64_t temp = word & -word;
|
||||||
|
int index = (begin & ~63) + std::countr_zero(word);
|
||||||
|
f(index);
|
||||||
|
word ^= temp;
|
||||||
|
}
|
||||||
|
begin += 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end < 256) {
|
||||||
|
// Check end partial word
|
||||||
|
uint64_t word = words[end >> 6] & ~(uint64_t(-1) << (end & 63));
|
||||||
|
while (word) {
|
||||||
|
uint64_t temp = word & -word;
|
||||||
|
int index = (begin & ~63) + std::countr_zero(word);
|
||||||
|
f(index);
|
||||||
|
word ^= temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t words[4] = {};
|
uint64_t words[4] = {};
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user