Skip to content

Commit ec7c0af

Browse files
committed
Make msb function less easy to misuse.
1 parent 08d222f commit ec7c0af

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

kagen/tools/random_permutation.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,31 @@ inline uint8_t most_significant_bit_set(Data bytes) {
7979
asm("bsr %1,%0" : "=r"(msb) : "r"(bytes));
8080
return asserting_cast<uint8_t>(msb);
8181
}*/
82-
template <typename Data>
82+
template <
83+
typename Data, typename Enable = std::enable_if_t<
84+
std::is_same_v<Data, unsigned int> || std::is_same_v<Data, unsigned long>
85+
|| std::is_same_v<Data, unsigned long long>>>
8386
std::uint8_t most_significant_bit_set(const Data arg) {
84-
constexpr std::size_t arg_width = std::numeric_limits<Data>::digits;
85-
auto log2 = static_cast<Data>(arg_width);
87+
constexpr std::size_t width = std::numeric_limits<Data>::digits;
88+
8689

87-
// __builtin_clz(l) is undefined for 0
90+
// __builtin_clz* is undefined for 0
8891
if (arg == 0) {
8992
return 0;
9093
}
9194

92-
if constexpr (arg_width == std::numeric_limits<unsigned int>::digits) {
93-
log2 -= __builtin_clz(arg);
94-
} else {
95-
static_assert(arg_width == std::numeric_limits<unsigned long>::digits, "unsupported data type width");
95+
std::size_t leading_zeros = 0;
96+
97+
if constexpr (std::is_same_v<Data, unsigned int>) {
98+
leading_zeros = __builtin_clz(arg);
99+
} else if constexpr (std::is_same_v<Data, unsigned long>) {
96100
log2 -= __builtin_clzl(arg);
101+
leading_zeros = __builtin_clzl(arg);
102+
} else {
103+
static_assert(std::is_same_v<Data, unsigned long long>);
104+
leading_zeros = __builtin_clzll(arg);
97105
}
98-
99-
return log2 - 1;
106+
return asserting_cast<std::uint8_t>(width - leading_zeros - 1);
100107
}
101108

102109
#define UNUSED(expr) (void)(expr)

0 commit comments

Comments
 (0)