From d585ce75ddd481d7d24af1d86dbd73c39d90ce65 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 1 Nov 2021 22:11:27 +0000 Subject: [PATCH] Use bitmath builtins for SetBitIterator when available --- src/core/bitmath_func.hpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 532bb7382e..6fd6e29ded 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -377,7 +377,11 @@ struct SetBitIterator { bool operator==(const Iterator &other) const { +#ifdef WITH_BITMATH_BUILTINS + return this->bitset == other.bitset; +#else return this->bitset == other.bitset && (this->bitset == 0 || this->bitpos == other.bitpos); +#endif } bool operator!=(const Iterator &other) const { return !(*this == other); } Tbitpos operator*() const { return this->bitpos; } @@ -388,12 +392,29 @@ struct SetBitIterator { Tbitpos bitpos; void Validate() { +#ifdef WITH_BITMATH_BUILTINS + if (this->bitset != 0) { + typename std::make_unsigned::type unsigned_value = this->bitset; + if (sizeof(Tbitset) <= sizeof(unsigned int)) { + bitpos = static_cast(__builtin_ctz(unsigned_value)); + } else if (sizeof(Tbitset) == sizeof(unsigned long)) { + bitpos = static_cast(__builtin_ctzl(unsigned_value)); + } else { + bitpos = static_cast(__builtin_ctzll(unsigned_value)); + } + } +#else while (this->bitset != 0 && (this->bitset & 1) == 0) this->Next(); +#endif } void Next() { +#ifdef WITH_BITMATH_BUILTINS + this->bitset = static_cast(this->bitset ^ (this->bitset & -this->bitset)); +#else this->bitset = static_cast(this->bitset >> 1); this->bitpos++; +#endif } };