File tree Expand file tree Collapse file tree 4 files changed +43
-6
lines changed Expand file tree Collapse file tree 4 files changed +43
-6
lines changed Original file line number Diff line number Diff line change 14
14
#include < utility>
15
15
16
16
#include " llvm/ADT/STLForwardCompat.h"
17
+ #include " llvm/ADT/bit.h"
17
18
#include " llvm/Support/MathExtras.h"
18
19
19
20
// / LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can
@@ -138,10 +139,6 @@ template <typename E> constexpr std::underlying_type_t<E> Underlying(E Val) {
138
139
return U;
139
140
}
140
141
141
- constexpr unsigned bitWidth (uint64_t Value) {
142
- return Value ? 1 + bitWidth (Value >> 1 ) : 0 ;
143
- }
144
-
145
142
template <typename E, typename = std::enable_if_t <is_bitmask_enum<E>::value>>
146
143
constexpr bool operator !(E Val) {
147
144
return Val == static_cast <E>(0 );
@@ -220,7 +217,7 @@ e &operator>>=(e &lhs, e rhs) {
220
217
// Enable bitmask enums in namespace ::llvm and all nested namespaces.
221
218
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE ();
222
219
template <typename E, typename = std::enable_if_t <is_bitmask_enum<E>::value>>
223
- constexpr unsigned BitWidth = BitmaskEnumDetail::bitWidth (
220
+ constexpr unsigned BitWidth = llvm::bit_width_constexpr (
224
221
uint64_t {llvm::to_underlying (E::LLVM_BITMASK_LARGEST_ENUMERATOR)});
225
222
226
223
} // namespace llvm
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ namespace pointer_union_detail {
31
31
// / Determine the number of bits required to store integers with values < n.
32
32
// / This is ceil(log2(n)).
33
33
constexpr int bitsRequired (unsigned n) {
34
- return n > 1 ? 1 + bitsRequired ((n + 1 ) / 2 ) : 0 ;
34
+ return n == 0 ? 0 : llvm::bit_width_constexpr (n - 1 );
35
35
}
36
36
37
37
template <typename ... Ts> constexpr int lowBitsAvailable () {
Original file line number Diff line number Diff line change @@ -292,6 +292,23 @@ template <typename T> [[nodiscard]] int bit_width(T Value) {
292
292
return std::numeric_limits<T>::digits - llvm::countl_zero (Value);
293
293
}
294
294
295
+ // / Returns the number of bits needed to represent Value if Value is nonzero.
296
+ // / Returns 0 otherwise.
297
+ // /
298
+ // / A constexpr version of bit_width.
299
+ // /
300
+ // / Ex. bit_width_constexpr(5) == 3.
301
+ template <typename T> [[nodiscard]] constexpr int bit_width_constexpr (T Value) {
302
+ static_assert (std::is_unsigned_v<T>,
303
+ " Only unsigned integral types are allowed." );
304
+ int Width = 0 ;
305
+ while (Value > 0 ) {
306
+ Value >>= 1 ;
307
+ ++Width;
308
+ }
309
+ return Width;
310
+ }
311
+
295
312
// / Returns the largest integral power of two no greater than Value if Value is
296
313
// / nonzero. Returns 0 otherwise.
297
314
// /
Original file line number Diff line number Diff line change @@ -247,6 +247,29 @@ TEST(BitTest, BitWidth) {
247
247
EXPECT_EQ (64 , llvm::bit_width (uint64_t (0xffffffffffffffffull )));
248
248
}
249
249
250
+ TEST (BitTest, BitWidthConstexpr) {
251
+ static_assert (llvm::bit_width_constexpr (0u ) == 0 );
252
+ static_assert (llvm::bit_width_constexpr (1u ) == 1 );
253
+ static_assert (llvm::bit_width_constexpr (2u ) == 2 );
254
+ static_assert (llvm::bit_width_constexpr (3u ) == 2 );
255
+ static_assert (llvm::bit_width_constexpr (4u ) == 3 );
256
+ static_assert (llvm::bit_width_constexpr (5u ) == 3 );
257
+ static_assert (llvm::bit_width_constexpr (6u ) == 3 );
258
+ static_assert (llvm::bit_width_constexpr (7u ) == 3 );
259
+ static_assert (llvm::bit_width_constexpr (8u ) == 4 );
260
+
261
+ static_assert (llvm::bit_width_constexpr (255u ) == 8 );
262
+ static_assert (llvm::bit_width_constexpr (256u ) == 9 );
263
+ static_assert (llvm::bit_width_constexpr (257u ) == 9 );
264
+
265
+ static_assert (
266
+ llvm::bit_width_constexpr (std::numeric_limits<uint16_t >::max ()) == 16 );
267
+ static_assert (
268
+ llvm::bit_width_constexpr (std::numeric_limits<uint32_t >::max ()) == 32 );
269
+ static_assert (
270
+ llvm::bit_width_constexpr (std::numeric_limits<uint64_t >::max ()) == 64 );
271
+ }
272
+
250
273
TEST (BitTest, CountlZero) {
251
274
uint8_t Z8 = 0 ;
252
275
uint16_t Z16 = 0 ;
You can’t perform that action at this time.
0 commit comments