From 8b453e1f015f0acccb979f7992bc0003c08753e4 Mon Sep 17 00:00:00 2001 From: Kostiantyn Lazukin Date: Mon, 28 Oct 2024 03:54:32 +0000 Subject: [PATCH] Replace custom bitscan with countr_zero --- include/ass/bit/bit_scan_constexpr.hpp | 70 -------------------------- include/ass/fixed_bitset.hpp | 8 +-- tests/bit/bit_scan_test.cpp | 9 ---- 3 files changed, 4 insertions(+), 83 deletions(-) delete mode 100644 include/ass/bit/bit_scan_constexpr.hpp delete mode 100644 tests/bit/bit_scan_test.cpp diff --git a/include/ass/bit/bit_scan_constexpr.hpp b/include/ass/bit/bit_scan_constexpr.hpp deleted file mode 100644 index f3fa5db..0000000 --- a/include/ass/bit/bit_scan_constexpr.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "bit_count_to_type.hpp" - -namespace ass::bit_scan_constexpr_detail -{ -inline constexpr auto kBitScanTable = []() -{ - std::array table{}; - - auto bit_scan_slow = [](uint8_t value) - { - uint8_t index = 0; - constexpr size_t bits_in_byte = 8; - while (!(value & (1 << index)) && index != bits_in_byte) - { - ++index; - } - return index; - }; - - uint8_t value = 0; - do // NOLINT - { - table[value] = bit_scan_slow(value); - value += 1; - } while (value != std::numeric_limits::max()); - - return table; -}(); -} // namespace ass::bit_scan_constexpr_detail - -namespace ass -{ - -inline constexpr size_t BitScanConstexpr(const uint8_t v) -{ - return bit_scan_constexpr_detail::kBitScanTable[v]; -} - -// Returns an index of first non-zero bit -// Also may be interpreted as number of leading zero bits -template >> -inline constexpr size_t BitScanConstexpr(const T v) -{ - // Split the bitset into two parts and count bits in these parts recursively - // util we come to uint8_t, which has it's own table - constexpr size_t kBitsCount = sizeof(v) * 8; - constexpr size_t kHalfBitsCount = kBitsCount / 2; - using HalfType = BitsCountToUnsignedIntT; - - if (const auto lo = static_cast(v); lo != 0) - { - return BitScanConstexpr(lo); - } - - if (const auto hi = static_cast(v >> kHalfBitsCount); hi != 0) - { - return BitScanConstexpr(hi) + kHalfBitsCount; - } - - return kBitsCount; -} -} // namespace ass diff --git a/include/ass/fixed_bitset.hpp b/include/ass/fixed_bitset.hpp index d58eed7..6848189 100644 --- a/include/ass/fixed_bitset.hpp +++ b/include/ass/fixed_bitset.hpp @@ -4,9 +4,9 @@ #include #include #include +#include #include "bit/bit_count_to_type.hpp" -#include "bit/bit_scan_constexpr.hpp" namespace ass::fixed_bitset_detail { @@ -110,7 +110,7 @@ class FixedBitset for (size_t part_index = 0; part_index != parts_.size(); ++part_index) { const Part& part = parts_[part_index]; - const size_t local = BitScanConstexpr(part); + const size_t local = std::countr_zero(part); result += local; if (local != kPartBitsCount) { @@ -134,7 +134,7 @@ class FixedBitset mask = ~mask; mask <<= ignored_bits; const Part part = parts_[part_index] & mask; - const size_t local = BitScanConstexpr(part); + const size_t local = std::countr_zero(part); if (local != kPartBitsCount) { return result + local; @@ -147,7 +147,7 @@ class FixedBitset for (; part_index != parts_.size(); ++part_index) { const Part& part = parts_[part_index]; - const size_t local = BitScanConstexpr(part); + const size_t local = std::countr_zero(part); result += local; if (local != kPartBitsCount) { diff --git a/tests/bit/bit_scan_test.cpp b/tests/bit/bit_scan_test.cpp deleted file mode 100644 index bc04c1c..0000000 --- a/tests/bit/bit_scan_test.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "ass/bit/bit_scan_constexpr.hpp" - -static_assert(ass::BitScanConstexpr(0b11111111) == 0); -static_assert(ass::BitScanConstexpr(0b11111100) == 2); -static_assert(ass::BitScanConstexpr(0b00000000) == 8); -static_assert(ass::BitScanConstexpr(static_cast(0b00000000'00000000)) == 16u); -static_assert(ass::BitScanConstexpr(static_cast(0b00000000'10000000)) == 7u); -static_assert(ass::BitScanConstexpr(static_cast(0b00000001'00000000)) == 8u); -static_assert(ass::BitScanConstexpr(static_cast(0b10000000'00000000)) == 15u);