Flag.hh
Go to the documentation of this file.
1 
4 #pragma once
5 
6 #include <type_traits>
7 
8 namespace boca
9 {
10 
21 template<typename Enum>
22 struct Flag {
23  static const bool enable = false;
24 };
25 
26 template <typename Enum, typename Type>
27 using FlagReturn = typename std::enable_if<Flag<Enum>::enable, Type>;
28 
29 template<typename Enum>
31 Underlying(Enum enum_1)
32 {
33  return static_cast<typename std::underlying_type<Enum>::type>(enum_1);
34 }
35 
36 template<typename Enum>
37 typename FlagReturn<Enum, Enum>::type operator&(Enum enum_1, Enum enum_2)
38 {
39  return static_cast<Enum>(Underlying(enum_1) & Underlying(enum_2));
40 }
41 
42 template<typename Enum>
43 constexpr typename FlagReturn<Enum, Enum>::type operator|(Enum enum_1, Enum enum_2)
44 {
45  return static_cast<Enum>(Underlying(enum_1) | Underlying(enum_2));
46 }
47 
48 template<typename Enum>
49 typename FlagReturn<Enum, Enum>::type operator^(Enum enum_1, Enum enum_2)
50 {
51  return static_cast<Enum>(Underlying(enum_1) ^ Underlying(enum_2));
52 }
53 
54 template<typename Enum>
56 {
57  return static_cast<Enum>(~Underlying(enum_1));
58 }
59 
60 template<typename Enum>
61 typename FlagReturn<Enum, Enum&>::type operator&=(Enum& enum_1, Enum enum_2)
62 {
63  enum_1 = enum_1 & enum_2;
64  return enum_1;
65 }
66 
67 template<typename Enum>
68 typename FlagReturn<Enum, Enum&>::type operator|=(Enum& enum_1, Enum enum_2)
69 {
70  enum_1 = enum_1 | enum_2;
71  return enum_1;
72 }
73 
74 template<typename Enum>
75 typename FlagReturn<Enum, Enum&>::type operator^=(Enum& enum_1, Enum enum_2)
76 {
77  enum_1 = enum_1 ^ enum_2;
78  return enum_1;
79 }
80 
81 template<typename Enum>
82 typename FlagReturn<Enum, Enum&>::type operator<<=(Enum& enum_1, Enum enum_2)
83 {
84  enum_1 = static_cast<Enum>(Underlying(enum_1) << Underlying(enum_2));
85  return enum_1;
86 }
87 
88 template <typename Enum>
90 {
91  return Underlying(value);
92 }
93 
94 template<typename Enum>
95 typename FlagReturn<Enum, bool>::type is(Enum enum_1, Enum enum_2)
96 {
97  return to_bool(enum_1 & enum_2);
98 }
99 
100 template<typename Enum, typename Function>
101 void FlagSwitch(Enum enum_1, Function function)
102 {
103  auto mask = Enum(1); // define mask of lowest enum value
104  while (to_bool(enum_1)) {
105  auto pure = enum_1 & mask; // project onto mask value
106  if (pure != Enum(0)) function(pure); // if non-zero apply function
107  enum_1 &= ~mask; // remove mask value from enum
108  mask <<= Enum(1); // increment mask value
109  }
110 }
111 
112 // @}
113 
114 }
Mark a strongly typed enumerator as a flag.
Definition: Flag.hh:22
FlagReturn< Enum, Enum & >::type operator<<=(Enum &enum_1, Enum enum_2)
Definition: Flag.hh:82
FlagReturn< Enum, bool >::type to_bool(Enum value)
Definition: Flag.hh:89
FlagReturn< Enum, Enum >::type operator~(Enum enum_1)
Definition: Flag.hh:55
FlagReturn< Enum, Enum >::type operator&(Enum enum_1, Enum enum_2)
Definition: Flag.hh:37
FlagReturn< Enum, Enum & >::type operator|=(Enum &enum_1, Enum enum_2)
Definition: Flag.hh:68
FlagReturn< Enum, Enum >::type operator^(Enum enum_1, Enum enum_2)
Definition: Flag.hh:49
static const bool enable
Definition: Flag.hh:23
void FlagSwitch(Enum enum_1, Function function)
Definition: Flag.hh:101
Boosted Collider Analysis.
Definition: Analysis.hh:15
FlagReturn< Enum, bool >::type is(Enum enum_1, Enum enum_2)
Definition: Flag.hh:95
typename std::enable_if< Flag< Enum >::enable, Type > FlagReturn
Definition: Flag.hh:27
FlagReturn< Enum, typename std::underlying_type< Enum >::type >::type Underlying(Enum enum_1)
Definition: Flag.hh:31
constexpr FlagReturn< Enum, Enum >::type operator|(Enum enum_1, Enum enum_2)
Definition: Flag.hh:43
FlagReturn< Enum, Enum & >::type operator&=(Enum &enum_1, Enum enum_2)
Definition: Flag.hh:61
FlagReturn< Enum, Enum & >::type operator^=(Enum &enum_1, Enum enum_2)
Definition: Flag.hh:75