21 uint64_t * words_ =
nullptr;
24 uint64_t static_words_[8];
30 Mask(
size_t log2dim,
bool on);
79 operator bool()
const {
80 return pos_ != parent_->SIZE;
85 pos_ = parent_->findNextOn(pos_ + 1);
98 return !((*this) == other);
107 bool isOn(uint32_t n)
const;
113 bool setOn(uint32_t n);
117 void set(uint32_t n,
bool On);
141 uint32_t findNextOn(uint32_t start)
const;
143 static uint32_t FindLowestOn(uint64_t v);
144 static uint32_t CountOn(uint64_t v);
156#define BONXAI_USE_INTRINSICS
164inline uint32_t Mask::FindLowestOn(uint64_t v)
166#if defined(_MSC_VER) && defined(BONXAI_USE_INTRINSICS)
168 _BitScanForward64(&index, v);
169 return static_cast<uint32_t
>(index);
170#elif (defined(__GNUC__) || defined(__clang__)) && defined(BONXAI_USE_INTRINSICS)
171 return static_cast<uint32_t
>(__builtin_ctzll(v));
173 static const unsigned char DeBruijn[64] = {
174 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, 62, 5, 39, 46, 44, 42,
175 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21,
176 23, 58, 17, 10, 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12,
179#if defined(_MSC_VER) && !defined(__NVCC__)
181#pragma warning(disable : 4146)
184 return DeBruijn[uint64_t((v & -v) * UINT64_C(0x022FDD63CC95386D)) >> 58];
185#if defined(_MSC_VER) && !defined(__NVCC__)
194inline uint32_t Mask::CountOn(uint64_t v)
196#if defined(_MSC_VER) && defined(_M_X64)
198#elif (defined(__GNUC__) || defined(__clang__))
199 v = __builtin_popcountll(v);
203 v = v - ((v >> 1) & uint64_t(0x5555555555555555));
204 v = (v & uint64_t(0x3333333333333333)) + ((v >> 2) & uint64_t(0x3333333333333333));
205 v = (((v + (v >> 4)) & uint64_t(0xF0F0F0F0F0F0F0F)) * uint64_t(0x101010101010101)) >> 56;
207 return static_cast<uint32_t
>(v);
212 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
213 words_[i] = ~uint64_t(0);
219 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
220 words_[i] = uint64_t(0);
226 const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
227 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
234 uint32_t n = WORD_COUNT;
235 for (
auto * w = words_; n--; ++w) {
242 words_[n >> 6] ^= uint64_t(1) << (n & 63);
247 const uint64_t * w = words_;
249 while (n < WORD_COUNT && !*w) {
253 return n == WORD_COUNT ? SIZE : (n << 6) + FindLowestOn(*w);
256inline uint32_t Mask::findNextOn(uint32_t start)
const
258 uint32_t n = start >> 6;
259 if (n >= WORD_COUNT) {
262 uint32_t m = start & 63;
263 uint64_t b = words_[n];
264 if (b & (uint64_t(1) << m)) {
267 b &= ~uint64_t(0) << m;
268 while (!b && ++n < WORD_COUNT) {
271 return !b ? SIZE : (n << 6) + FindLowestOn(b);
275: SIZE(1U << (3 * log2dim)),
276 WORD_COUNT(
std::max(SIZE >> 6, 1u))
278 words_ = (WORD_COUNT <= 8) ? static_words_ :
new uint64_t[WORD_COUNT];
280 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
286: SIZE(1U << (3 * log2dim)),
287 WORD_COUNT(
std::max(SIZE >> 6, 1u))
289 words_ = (WORD_COUNT <= 8) ? static_words_ :
new uint64_t[WORD_COUNT];
291 const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
292 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
299 WORD_COUNT(other.WORD_COUNT)
301 words_ = (WORD_COUNT <= 8) ? static_words_ :
new uint64_t[WORD_COUNT];
303 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
304 words_[i] = other.words_[i];
310 WORD_COUNT(other.WORD_COUNT)
312 if (WORD_COUNT <= 8) {
313 words_ = static_words_;
314 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
315 words_[i] = other.words_[i];
318 std::swap(words_, other.words_);
324 if (WORD_COUNT > 8) {
331 if (WORD_COUNT > 8) {
332 return sizeof(
Mask) +
sizeof(uint64_t) * WORD_COUNT;
339 uint32_t sum = 0, n = WORD_COUNT;
340 for (
const uint64_t * w = words_; n--; ++w) {
348 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
349 if (words_[i] != other.words_[i]) {
358 return 0 != (words_[n >> 6] & (uint64_t(1) << (n & 63)));
363 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
364 if (words_[i] != ~uint64_t(0)) {
373 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
374 if (words_[i] != uint64_t(0)) {
383 uint64_t & word = words_[n >> 6];
384 const uint64_t on_bit = (uint64_t(1) << (n & 63));
385 bool was_on = word & on_bit;
392 uint64_t & word = words_[n >> 6];
393 const uint64_t on_bit = (uint64_t(1) << (n & 63));
394 bool was_on = word & on_bit;
402 auto & word = words_[n >> 6];
404 word &= ~(uint64_t(1) << n);
405 word |= uint64_t(On) << n;
Iterator & operator=(const Iterator &)=default
uint32_t operator*() const
Definition mask.hpp:74
Iterator(uint32_t pos, const Mask *parent)
Definition mask.hpp:69
Iterator & operator++()
Definition mask.hpp:83
Iterator(const Mask *parent)
Definition mask.hpp:66
uint32_t bitCount() const
Return the number of bits available in this Mask.
Definition mask.hpp:41
Iterator beginOn() const
Definition mask.hpp:101
uint32_t findFirstOn() const
Definition mask.hpp:245
size_t memUsage() const
Return the memory footprint in bytes of this Mask.
Definition mask.hpp:329
void set(uint32_t n, bool On)
Definition mask.hpp:399
void setWord(size_t n, uint64_t v)
Definition mask.hpp:57
bool operator==(const Mask &other) const
Definition mask.hpp:346
Mask(size_t log2dim)
Initialize all bits to zero.
Definition mask.hpp:274
void setOn()
Set all bits on.
Definition mask.hpp:210
uint32_t size() const
Definition mask.hpp:135
uint32_t countOn() const
Definition mask.hpp:337
void setOff()
Set all bits off.
Definition mask.hpp:217
uint64_t getWord(size_t n) const
Definition mask.hpp:52
bool isOff() const
Definition mask.hpp:371
bool operator!=(const Mask &other) const
Definition mask.hpp:96
void toggle()
Toggle the state of all bits in the mask.
Definition mask.hpp:232
uint32_t wordCount() const
Return the number of machine words used by this Mask.
Definition mask.hpp:47
~Mask()
Definition mask.hpp:322
bool isOn() const
Return true if any bit is set.
Definition mask.hpp:361
Definition grid_coord.hpp:226