NAIA
 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 
21 #define ENABLE_BITMASK_OPERATORS(x) \
22  template <> struct EnableBitMaskOperators<x> { static const bool enable = true; };
23 
24 template <typename Enum> struct EnableBitMaskOperators { static const bool enable = false; };
25 
26 template <typename Enum>
27 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator|(const Enum lhs, const Enum rhs) {
28  using underlying = typename std::underlying_type<Enum>::type;
29  return static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
30 }
31 
32 template <typename Enum>
33 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator&(const Enum lhs, const Enum rhs) {
34  using underlying = typename std::underlying_type<Enum>::type;
35  return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
36 }
37 
38 template <typename Enum>
39 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator^(const Enum lhs, const Enum rhs) {
40  using underlying = typename std::underlying_type<Enum>::type;
41  return static_cast<Enum>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs));
42 }
43 
44 template <typename Enum>
45 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator~(const Enum rhs) {
46  using underlying = typename std::underlying_type<Enum>::type;
47  return static_cast<Enum>(~static_cast<underlying>(rhs));
48 }
49 
50 template <typename Enum>
51 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator!=(const Enum lhs, const Enum rhs) {
52  using underlying = typename std::underlying_type<Enum>::type;
53  return static_cast<Enum>(static_cast<underlying>(lhs) != static_cast<underlying>(rhs));
54 }
55 
56 template <typename Enum>
57 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator|=(Enum &lhs, const Enum rhs) {
58  using underlying = typename std::underlying_type<Enum>::type;
59  lhs = static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
60  return lhs;
61 }
62 
63 template <typename Enum>
64 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator&=(Enum &lhs, const Enum rhs) {
65  using underlying = typename std::underlying_type<Enum>::type;
66  lhs = static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
67  return lhs;
68 }
69 
70 template <typename Enum>
71 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, Enum>::type operator^=(Enum &lhs, const Enum rhs) {
72  using underlying = typename std::underlying_type<Enum>::type;
73  lhs = static_cast<Enum>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs));
74  return lhs;
75 }
76 
77 // check if at least one bit from a pattern of ones and zeroes is present in bitmask
78 template <typename Enum>
79 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, bool>::type
80 MatchAnyBit(const Enum test, const Enum ones, const Enum zeroes = static_cast<Enum>(0)) {
81  return static_cast<bool>(test & ones) || static_cast<bool>((test ^ zeroes) & zeroes);
82 }
83 
84 // check if a given pattern of ones and zeroes is present in bitmask
85 template <typename Enum>
86 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, bool>::type
87 MatchAllBits(const Enum test, const Enum ones, const Enum zeroes = static_cast<Enum>(0)) {
88  return (test & (ones | zeroes)) == ones;
89 }
90 
91 // print this bitmask as a binary string
92 template <int N, typename Enum>
93 typename std::enable_if<EnableBitMaskOperators<Enum>::enable, std::string>::type to_string_binary(const Enum rhs) {
94  return std::bitset<N>{static_cast<size_t>(rhs)}.to_string();
95 }
96 
97 #endif
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator~(const Enum rhs)
Definition: bitmask.h:45
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator&(const Enum lhs, const Enum rhs)
Definition: bitmask.h:33
std::enable_if< EnableBitMaskOperators< Enum >::enable, std::string >::type to_string_binary(const Enum rhs)
Definition: bitmask.h:93
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator^(const Enum lhs, const Enum rhs)
Definition: bitmask.h:39
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator&=(Enum &lhs, const Enum rhs)
Definition: bitmask.h:64
static const bool enable
Definition: bitmask.h:24
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator|(const Enum lhs, const Enum rhs)
Definition: bitmask.h:27
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator|=(Enum &lhs, const Enum rhs)
Definition: bitmask.h:57
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator!=(const Enum lhs, const Enum rhs)
Definition: bitmask.h:51
std::enable_if< EnableBitMaskOperators< Enum >::enable, Enum >::type operator^=(Enum &lhs, const Enum rhs)
Definition: bitmask.h:71
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:87
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:80