/// The returned value is undefined.
ZB_Undefined,
/// The returned value is numeric_limits<T>::max()
- ZB_Max,
- /// The returned value is numeric_limits<T>::digits
- ZB_Width
+ ZB_Max
};
/// Mathematical constants.
namespace detail {
template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
- static unsigned count(T Val, ZeroBehavior) {
+ static unsigned count(T Val) {
if (!Val)
return std::numeric_limits<T>::digits;
if (Val & 0x1)
#if defined(__GNUC__) || defined(_MSC_VER)
template <typename T> struct TrailingZerosCounter<T, 4> {
- static unsigned count(T Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
+ static unsigned count(T Val) {
+ if (Val == 0)
return 32;
#if __has_builtin(__builtin_ctz) || defined(__GNUC__)
#if !defined(_MSC_VER) || defined(_M_X64)
template <typename T> struct TrailingZerosCounter<T, 8> {
- static unsigned count(T Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
+ static unsigned count(T Val) {
+ if (Val == 0)
return 64;
#if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
///
/// Only unsigned integral types are allowed.
///
-/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
-/// valid arguments.
-template <typename T>
-unsigned countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+/// Returns std::numeric_limits<T>::digits on an input of 0.
+template <typename T> unsigned countTrailingZeros(T Val) {
static_assert(std::is_unsigned_v<T>,
"Only unsigned integral types are allowed.");
- return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
+ return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val);
}
namespace detail {
template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
- static unsigned count(T Val, ZeroBehavior) {
+ static unsigned count(T Val) {
if (!Val)
return std::numeric_limits<T>::digits;
#if defined(__GNUC__) || defined(_MSC_VER)
template <typename T> struct LeadingZerosCounter<T, 4> {
- static unsigned count(T Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
+ static unsigned count(T Val) {
+ if (Val == 0)
return 32;
#if __has_builtin(__builtin_clz) || defined(__GNUC__)
#if !defined(_MSC_VER) || defined(_M_X64)
template <typename T> struct LeadingZerosCounter<T, 8> {
- static unsigned count(T Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
+ static unsigned count(T Val) {
+ if (Val == 0)
return 64;
#if __has_builtin(__builtin_clzll) || defined(__GNUC__)
///
/// Only unsigned integral types are allowed.
///
-/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
-/// valid arguments.
-template <typename T>
-unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+/// Returns std::numeric_limits<T>::digits on an input of 0.
+template <typename T> unsigned countLeadingZeros(T Val) {
static_assert(std::is_unsigned_v<T>,
"Only unsigned integral types are allowed.");
- return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
+ return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val);
}
/// Get the index of the first set bit starting from the least
///
/// Only unsigned integral types are allowed.
///
-/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
-/// valid arguments.
+/// \param ZB the behavior on an input of 0.
template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
- return countTrailingZeros(Val, ZB_Undefined);
+ return countTrailingZeros(Val);
}
/// Create a bitmask with the N right-most bits set to 1, and all other
///
/// Only unsigned integral types are allowed.
///
-/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
-/// valid arguments.
+/// \param ZB the behavior on an input of 0.
template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
// Use ^ instead of - because both gcc and llvm can remove the associated ^
// in the __builtin_clz intrinsic on x86.
- return countLeadingZeros(Val, ZB_Undefined) ^
- (std::numeric_limits<T>::digits - 1);
+ return countLeadingZeros(Val) ^ (std::numeric_limits<T>::digits - 1);
}
/// Macro compressed bit reversal table for 256 bits.
/// Ex. countLeadingOnes(0xFF0FFF00) == 8.
/// Only unsigned integral types are allowed.
///
-/// \param ZB the behavior on an input of all ones. Only ZB_Width and
-/// ZB_Undefined are valid arguments.
-template <typename T>
-unsigned countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
+/// Returns std::numeric_limits<T>::digits on an input of all ones.
+template <typename T> unsigned countLeadingOnes(T Value) {
static_assert(std::is_unsigned_v<T>,
"Only unsigned integral types are allowed.");
- return countLeadingZeros<T>(~Value, ZB);
+ return countLeadingZeros<T>(~Value);
}
/// Count the number of ones from the least significant bit to the first
/// Ex. countTrailingOnes(0x00FF00FF) == 8.
/// Only unsigned integral types are allowed.
///
-/// \param ZB the behavior on an input of all ones. Only ZB_Width and
-/// ZB_Undefined are valid arguments.
-template <typename T>
-unsigned countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
+/// Returns std::numeric_limits<T>::digits on an input of all ones.
+template <typename T> unsigned countTrailingOnes(T Value) {
static_assert(std::is_unsigned_v<T>,
"Only unsigned integral types are allowed.");
- return countTrailingZeros<T>(~Value, ZB);
+ return countTrailingZeros<T>(~Value);
}
/// Count the number of set bits in a value.
/// Essentially, it is a floor operation across the domain of powers of two.
inline uint64_t PowerOf2Floor(uint64_t A) {
if (!A) return 0;
- return 1ull << (63 - countLeadingZeros(A, ZB_Undefined));
+ return 1ull << (63 - countLeadingZeros(A));
}
/// Returns the power of two which is greater than or equal to the given value.