I would like to implement a template function which generates bitmasks in compile-time for integral types. These masks should be based on 8-bit patterns where the pattern will be repeated consecutively to fill the integer. The following example does exactly what I want but in run-time:
#include <iostream>
#include <type_traits>
#include <cstring>
template<typename Int>
typename std::enable_if<std::is_integral<Int>::value, Int>::type
make_mask(unsigned char pattern) {
Int output {};
std::memset(&output, pattern, sizeof(Int));
return output;
}
int main() {
auto mask = make_mask<unsigned long>(0xf0);
std::cout << "Bitmask: '" << std::hex << mask << "'" << std::endl;
}
The output of the code above is:
Bitmask: 'f0f0f0f0f0f0f0f0'
I know that the optimizer can eliminate the entire function call in the code above, but I'm looking for a constexpr
solution with c++14 and optionally with c++11.
I'm not sure there's a well-defined solution for signed types. For unsigned types, I'd go with:
template<class Int>
constexpr typename std::enable_if</* std::is_integral<Int>::value && */ std::is_unsigned<Int>::value,
Int>::type make_mask(const unsigned char pattern) {
return ((std::numeric_limits<Int>::max() / std::numeric_limits<unsigned char>::max()) * pattern);
}
This should work provided that std::numeric_limits<Int>::max()
is a multiple of std::numeric_limits<unsigned char>::max()
; you could add a check for that to the std::enable_if
condition and use another solution if that check fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With