8 #ifndef NAIA_BITMASK_H_
9 #define NAIA_BITMASK_H_
13 #include <type_traits>
15 #define NAIA_ENABLE_BITMASK_OPERATORS(x) \
16 template <> struct NAIA::EnableBitMaskOperators<x> { static const bool enable = true; };
28 template <
typename Enum>
29 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator|(
const Enum lhs,
const Enum rhs) {
30 using underlying =
typename std::underlying_type<Enum>::type;
31 return static_cast<Enum
>(
static_cast<underlying
>(lhs) |
static_cast<underlying
>(rhs));
34 template <
typename Enum>
35 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator&(
const Enum lhs,
const Enum rhs) {
36 using underlying =
typename std::underlying_type<Enum>::type;
37 return static_cast<Enum
>(
static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs));
40 template <
typename Enum>
41 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator^(
const Enum lhs,
const Enum rhs) {
42 using underlying =
typename std::underlying_type<Enum>::type;
43 return static_cast<Enum
>(
static_cast<underlying
>(lhs) ^
static_cast<underlying
>(rhs));
46 template <
typename Enum>
47 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator~(
const Enum rhs) {
48 using underlying =
typename std::underlying_type<Enum>::type;
49 return static_cast<Enum
>(~static_cast<underlying>(rhs));
52 template <
typename Enum>
53 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator!=(
const Enum lhs,
const Enum rhs) {
54 using underlying =
typename std::underlying_type<Enum>::type;
55 return static_cast<Enum
>(
static_cast<underlying
>(lhs) !=
static_cast<underlying
>(rhs));
58 template <
typename Enum>
59 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator|=(Enum &lhs,
const Enum rhs) {
60 using underlying =
typename std::underlying_type<Enum>::type;
61 lhs =
static_cast<Enum
>(
static_cast<underlying
>(lhs) |
static_cast<underlying
>(rhs));
65 template <
typename Enum>
66 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator&=(Enum &lhs,
const Enum rhs) {
67 using underlying =
typename std::underlying_type<Enum>::type;
68 lhs =
static_cast<Enum
>(
static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs));
72 template <
typename Enum>
73 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type
operator^=(Enum &lhs,
const Enum rhs) {
74 using underlying =
typename std::underlying_type<Enum>::type;
75 lhs =
static_cast<Enum
>(
static_cast<underlying
>(lhs) ^
static_cast<underlying
>(rhs));
80 template <
typename Enum>
81 typename std::enable_if<EnableBitMaskOperators<Enum>::enable,
bool>::type
82 MatchAnyBit(
const Enum test,
const Enum ones,
const Enum zeroes =
static_cast<Enum
>(0)) {
83 return static_cast<bool>(test & ones) ||
static_cast<bool>((test ^ zeroes) & zeroes);
87 template <
typename Enum>
88 typename std::enable_if<EnableBitMaskOperators<Enum>::enable,
bool>::type
89 MatchAllBits(
const Enum test,
const Enum ones,
const Enum zeroes =
static_cast<Enum
>(0)) {
90 return (test & (ones | zeroes)) == ones;
94 template <
int N,
typename Enum>
95 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, std::string>::type
to_string_binary(
const Enum rhs) {
96 return std::bitset<N>{
static_cast<size_t>(rhs)}.to_string();