diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 0a6b389..6cba44e 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -93,62 +93,47 @@ private: }; struct BitSet { - bool test(int i) const { - assert(0 <= i); - assert(i < 256); - if (i < 128) { - return (lo >> i) & 1; - } else { - return (hi >> (i - 128)) & 1; - } - } - - void set(int i) { - assert(0 <= i); - assert(i < 256); - if (i < 128) { - lo |= __uint128_t(1) << i; - } else { - hi |= __uint128_t(1) << (i - 128); - } - } - - void reset(int i) { - assert(0 <= i); - assert(i < 256); - if (i < 128) { - lo &= ~(__uint128_t(1) << i); - } else { - hi &= ~(__uint128_t(1) << (i - 128)); - } - } - - int firstSetGeq(int i) const { - assert(0 <= i); - if (i >= 256) { - return -1; - } - if (i < 128) { - int a = std::countr_zero(lo >> i); - if (a < 128) { - assert(i + a < 128); - return i + a; - } - i = 128; - } - int b = std::countr_zero(hi >> (i - 128)); - if (b < 128) { - assert(i + b < 256); - return i + b; - } - return -1; - } + bool test(int i) const; + void set(int i); + void reset(int i); + int firstSetGeq(int i) const; private: - __uint128_t lo = 0; - __uint128_t hi = 0; + uint64_t words[4] = {}; }; +bool BitSet::test(int i) const { + assert(0 <= i); + assert(i < 256); + return words[i >> 6] & (uint64_t(1) << (i & 63)); +} + +void BitSet::set(int i) { + assert(0 <= i); + assert(i < 256); + words[i >> 6] |= uint64_t(1) << (i & 63); +} + +void BitSet::reset(int i) { + assert(0 <= i); + assert(i < 256); + words[i >> 6] &= ~(uint64_t(1) << (i & 63)); +} + +int BitSet::firstSetGeq(int i) const { + assert(0 <= i); + // i may be >= 256 + uint64_t mask = uint64_t(-1) << (i & 63); + for (int j = i >> 6; j < 4; ++j) { + uint64_t masked = mask & words[j]; + if (masked) { + return (j << 6) + std::countr_zero(masked); + } + mask = -1; + } + return -1; +} + enum class Type : int8_t { Node4, Node16,