@@ -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 >>>
8386std::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