NAIA  1.0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
bitmask.h
Go to the documentation of this file.
1 /*
2  * BitMask.h
3  *
4  * Created on: 13 Nov 2020
5  * Author: Valerio Formato
6  */
7 
8 #ifndef NAIA_BITMASK_H_
9 #define NAIA_BITMASK_H_
10 
11 #include <bitset>
12 #include <string>
13 #include <type_traits>
14 
15 #define NAIA_ENABLE_BITMASK_OPERATORS(x) \
16  template <> struct NAIA::EnableBitMaskOperators<x> { static const bool enable = true; };
17 
18 namespace NAIA {
19 
26 template <typename Enum> struct EnableBitMaskOperators { static const bool enable = false; };
27 
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));
32 }
33 
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));
38 }
39 
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));
44 }
45 
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));
50 }
51 
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));
56 }
57 
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));
62  return lhs;
63 }
64 
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));
69  return lhs;
70 }
71 
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));
76  return lhs;
77 }
78 
79 // check if at least one bit from a pattern of ones and zeroes is present in bitmask
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);
84 }
85 
86 // check if a given pattern of ones and zeroes is present in bitmask
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;
91 }
92 
93 // print this bitmask as a binary string
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();
97 }
98 
99 } // namespace NAIA
100 
101 #endif
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator&(const Enum lhs, const Enum rhs)
Definition: bitmask.h:35
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator|(const Enum lhs, const Enum rhs)
Definition: bitmask.h:29
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator~(const Enum rhs)
Definition: bitmask.h:47
std::enable_if< EnableBitMaskOperators< Enum >::enable, bool >::type MatchAnyBit(const Enum test, const Enum ones, const Enum zeroes=static_cast< Enum >(0))
Definition: bitmask.h:82
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator|=(Enum &lhs, const Enum rhs)
Definition: bitmask.h:59
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator^=(Enum &lhs, const Enum rhs)
Definition: bitmask.h:73
std::enable_if< EnableBitMaskOperators< Enum >::enable, bool >::type MatchAllBits(const Enum test, const Enum ones, const Enum zeroes=static_cast< Enum >(0))
Definition: bitmask.h:89
bool operator!=(const NAIAChain::EventItr &lhs, const NAIAChain::EventItr &rhs)
Definition: NAIAChain.h:295
static const bool enable
Definition: bitmask.h:26
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator^(const Enum lhs, const Enum rhs)
Definition: bitmask.h:41
std::enable_if< EnableBitMaskOperators< Enum >::enable, std::string >::type to_string_binary(const Enum rhs)
Definition: bitmask.h:95
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator&=(Enum &lhs, const Enum rhs)
Definition: bitmask.h:66
Type safe implementation of a bitmask enum.
Definition: bitmask.h:26