Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating bit mask at compile time

I would like to generate various bit masks at compile time:

0x11111111 or 0x1111111111111111

0xF0F0F0F0 or 0xF0F0F0F0F0F0F0F0

The size will be dependant on a type, either 32 bits or 64 bits.

ex:

template <typename T> genMask(unsigned char templt) {
  ....
};

genMask<uint32_t>(0xF0);
genMask<uint64_t>(0xF0);

The first call should generate 0xF0F0F0F0 while the second call to genMask should generate 0xF0F0F0F0F0F0F0F0

Currently I have these hard coded.

Any ideas here would be greatly appreciated.

EDIT: here is an old-school way of doing it:

#define MASK(b) ((T(-1) / 0xFF) * (b))

where T is the type.

like image 648
Jacko Avatar asked Sep 19 '25 20:09

Jacko


1 Answers

Using c++20, you can accomplish this with std::bit_cast:

template <std::unsigned_integral T>
constexpr T genMask(unsigned char templt) {
  std::array<unsigned char, sizeof(T)> mask;
  mask.fill(templt);
  return std::bit_cast<T>(mask);
}

If you want to ensure this function may only return compile-time constants, you can use the consteval specifier instead, but it is sufficient to achieve the same effect by calling the function above in the initializer of a constexpr variable, or as a non-type template parameter.

like image 103
Patrick Roberts Avatar answered Sep 21 '25 13:09

Patrick Roberts