In C 17, is there are way to generate at compile-time a constant with the first N bits set?
In pseudocode, I am looking for something like:
constexpr uint32_t MY_CONSTANT = setBits<2>();
Would be equivalent to:
constexpr uint32_t MY_CONSTANT = 0b11;
In other words, given a compile-time constant N, return a compile-time constant M where bits 0 to (N-1) are 1 (set).
CodePudding user response:
I don't think there's a ready made function for it in the standard library (although std::bitset::set
is constexpr
since C 23). You could make your own though:
template<class T, std::size_t N>
constexpr T setBits() {
if constexpr (N == sizeof(unsigned long long) * CHAR_BIT) return ~T{};
else return static_cast<T>((1ull << N) - 1);
}
constexpr auto MY_CONSTANT = setBits<std::uint32_t, 2>();
Example for setBits<std::uint8_t, 2>()
:
0b00000001
<< 2
-------------
= 0b00000100
0b00000100
- 1
-------------
= 0b00000011
Or negate 0
to get all bits set and right shift away all but N
bits:
template<class T, std::size_t N>
constexpr T setBits() {
if constexpr (N == 0) return 0;
else return ~T{} >> (sizeof(T) * CHAR_BIT - N);
}