Replace BitUtils with C++20: Counting Zeroes

With the upgrade to C++20, std::countl_zero and std::countr_zero can replace these home-spun implementations from the BitUtil.h library.
This commit is contained in:
Minty-Meeo
2022-10-10 04:03:15 -05:00
parent d853da3b0b
commit 05bebee802
8 changed files with 15 additions and 119 deletions

View File

@ -11,10 +11,6 @@
#include <initializer_list>
#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace Common
{
///
@ -316,105 +312,4 @@ T ExpandValue(T value, size_t left_shift_amount)
return (value << left_shift_amount) |
(T(-ExtractBit<0>(value)) >> (BitSize<T>() - left_shift_amount));
}
template <typename T>
constexpr int CountLeadingZerosConst(T value)
{
int result = sizeof(T) * 8;
while (value)
{
result--;
value >>= 1;
}
return result;
}
constexpr int CountLeadingZeros(uint64_t value)
{
#if defined(__GNUC__)
return value ? __builtin_clzll(value) : 64;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountLeadingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanReverse64(&index, value) ? 63 - index : 64;
}
#else
return CountLeadingZerosConst(value);
#endif
}
constexpr int CountLeadingZeros(uint32_t value)
{
#if defined(__GNUC__)
return value ? __builtin_clz(value) : 32;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountLeadingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanReverse(&index, value) ? 31 - index : 32;
}
#else
return CountLeadingZerosConst(value);
#endif
}
template <typename T>
constexpr int CountTrailingZerosConst(T value)
{
int result = sizeof(T) * 8;
while (value)
{
result--;
value <<= 1;
}
return result;
}
constexpr int CountTrailingZeros(uint64_t value)
{
#if defined(__GNUC__)
return value ? __builtin_ctzll(value) : 64;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountTrailingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanForward64(&index, value) ? index : 64;
}
#else
return CountTrailingZerosConst(value);
#endif
}
constexpr int CountTrailingZeros(uint32_t value)
{
#if defined(__GNUC__)
return value ? __builtin_ctz(value) : 32;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountTrailingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanForward(&index, value) ? index : 32;
}
#else
return CountTrailingZerosConst(value);
#endif
}
} // namespace Common