diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 146d2bd10a..12bd02138d 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -322,11 +322,7 @@ 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; } @@ -337,29 +333,14 @@ 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)); - } + this->bitpos = static_cast(FindFirstBit(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 + this->bitset = KillFirstBit(this->bitset); } }; diff --git a/src/tests/bitmath_func.cpp b/src/tests/bitmath_func.cpp index 6ab2697854..e96093bbc6 100644 --- a/src/tests/bitmath_func.cpp +++ b/src/tests/bitmath_func.cpp @@ -51,3 +51,22 @@ TEST_CASE("FindLastBit tests") CHECK(FindLastBit(0x42U) == FindLastBit(0x40U)); CHECK(FindLastBit(0xAAAAU) == FindLastBit(0x8000U)); } + +TEST_CASE("SetBitIterator tests") +{ + auto test_case = [&](auto input, std::initializer_list expected) { + auto iter = expected.begin(); + for (auto bit : SetBitIterator(input)) { + if (iter == expected.end()) return false; + if (bit != *iter) return false; + ++iter; + } + return iter == expected.end(); + }; + CHECK(test_case(0, {})); + CHECK(test_case(1, { 0 })); + CHECK(test_case(42, { 1, 3, 5 })); + CHECK(test_case(0x8080FFFFU, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 23, 31 })); + CHECK(test_case(INT32_MIN, { 31 })); + CHECK(test_case(INT64_MIN, { 63 })); +}