libcosmos
Linux C++ System Programming Library
All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
BitMask.hxx
1#pragma once
2
3// C++
4#include <initializer_list>
5#include <string>
6#include <type_traits>
7
8namespace cosmos {
9
11
18template <typename ENUM>
19class BitMask {
20public: // types
21
23 struct All {};
24 static constexpr All all{};
25
26 using EnumBaseType = typename std::underlying_type<ENUM>::type;
27
28public: // functions
29
31 constexpr BitMask() {}
32
34 explicit BitMask(const All a) {
35 set(a);
36 }
37
39 constexpr BitMask(const std::initializer_list<ENUM> &init_list) {
40 for (auto val: init_list) {
41 m_flags |= static_cast<EnumBaseType>(val);
42 }
43 }
44
46 explicit constexpr BitMask(const ENUM val) :
47 m_flags{static_cast<EnumBaseType>(val)}
48 {}
49
51 explicit constexpr BitMask(const EnumBaseType value) :
52 m_flags{value}
53 {}
54
56 EnumBaseType raw() const { return m_flags; }
57
59 explicit operator std::string() const { return toString(); }
60
62 bool operator[] (const ENUM flag) const { return test(flag); }
63
64 std::string toString() const {
65 std::string ret;
66
67 // append each bit starting with the highest one
68 for (int bit = size() - 1; bit >= 0; bit--) {
69 const auto val = 1 << bit;
70 ret.push_back(this->test(static_cast<ENUM>(val)) ? '1' : '0');
71 }
72
73 return ret;
74 }
75
77 BitMask& set(const All) {
78 m_flags = ~EnumBaseType(0);
79 return *this;
80 }
81
83 BitMask& set(const ENUM val, bool on_off = true) {
84 const auto bitval = static_cast<EnumBaseType>(val);
85 m_flags = (on_off ? (m_flags|bitval) : (m_flags & ~bitval));
86 return *this;
87 }
88
89 BitMask& set(const std::initializer_list<ENUM> &flags) {
90 for (auto flag: flags) {
91 set(flag);
92 }
93 return *this;
94 }
95
97 BitMask& set(const BitMask other) {
98 m_flags |= other.m_flags;
99 return *this;
100 }
101
104 m_flags = EnumBaseType{0};
105 return *this;
106 }
107
109 BitMask& reset(const ENUM val) {
110 reset({val});
111 return *this;
112 }
113
115 BitMask& reset(const std::initializer_list<ENUM> &flags) {
116 for (auto val: flags) {
117 m_flags &= ~static_cast<EnumBaseType>(val);
118 }
119 return *this;
120 }
121
122 BitMask& reset(const BitMask other) {
123 m_flags &= ~(other.raw());
124 return *this;
125 }
126
127 BitMask reset(const BitMask other) const {
128 auto ret = *this;
129 return ret.reset(other);
130 }
131
133 BitMask& limit(const std::initializer_list<ENUM> &flags) {
134 EnumBaseType mask = 0;
135 for (auto val: flags) {
136 mask |= static_cast<EnumBaseType>(val);
137 }
138
139 m_flags &= mask;
140 return *this;
141 }
142
144 BitMask& limit(const ENUM flag) {
145 return limit({flag});
146 }
147
149 BitMask& limit(const BitMask other) {
150 m_flags &= other.raw();
151 return *this;
152 }
153
154 BitMask limit(const BitMask other) const {
155 auto ret = *this;
156 return ret.limit(other);
157 }
158
161 m_flags = ~m_flags;
162 return *this;
163 }
164
166 BitMask& flip(const ENUM val) {
167 m_flags ^= static_cast<EnumBaseType>(val);
168 return *this;
169 }
170
172 size_t count() const {
173 size_t ret = 0;
174
175 for (size_t bit = 0; bit < size(); bit++) {
176 auto val = 1 << bit;
177 if (this->test(static_cast<ENUM>(val)))
178 ret++;
179 }
180
181 return ret;
182 }
183
185 constexpr size_t size() const {
186 return sizeof(EnumBaseType) * 8;
187 }
188
190
194 bool test(const ENUM val) const {
195 const auto raw_val = static_cast<EnumBaseType>(val);
196 return (m_flags & raw_val) == raw_val;
197 }
198
200
207 bool testAny(const ENUM val) const {
208 return ((m_flags & static_cast<EnumBaseType>(val)) != 0);
209 }
210
211
213 bool only(const ENUM val) const {
214 return m_flags == static_cast<EnumBaseType>(val);
215 }
216
218 bool any() const {
219 return m_flags != 0;
220 }
221
223 bool allOf(const std::initializer_list<ENUM> &flags) const {
224 for (auto val: flags) {
225 if (!test(val))
226 return false;
227 }
228
229 return true;
230 }
231
232 bool allOf(const BitMask other) const {
233 return (m_flags & other.m_flags) == other.m_flags;
234 }
235
237 bool anyOf(const std::initializer_list<ENUM> &flags) const {
238 for (auto val: flags) {
239 if (test(val))
240 return true;
241 }
242
243 return false;
244 }
245
246 bool anyOf(const BitMask other) const {
247 return (m_flags & other.m_flags) != 0;
248 }
249
251 bool none() const {
252 return !this->any();
253 }
254
255 bool operator==(const BitMask &other) const {
256 return m_flags == other.m_flags;
257 }
258
259 bool operator!=(const BitMask &other) const {
260 return !(*this == other);
261 }
262
264 bool operator&(const ENUM val) const {
265 return testAny(val);
266 }
267
269 ENUM operator&(const BitMask &other) const {
270 return ENUM{other.raw() & this->raw()};
271 }
272
273 BitMask operator~() const {
274 return BitMask{~m_flags};
275 }
276
278 friend BitMask operator-(const BitMask &first, const BitMask &second) {
279 BitMask ret{first};
280 return ret.reset(second);
281 }
282
284 friend BitMask operator-(const BitMask &first, const ENUM val) {
285 BitMask ret{first};
286 return ret.reset(val);
287 }
288
290 friend BitMask operator+(const BitMask &first, const BitMask &second) {
291 BitMask ret{first};
292 return ret.set(second);
293 }
294
296 friend BitMask operator+(const BitMask &first, const ENUM val) {
297 BitMask ret{first};
298 return ret.set(val);
299 }
300
301protected: // data
302
303 EnumBaseType m_flags = 0;
304};
305
306} // end ns
A typesafe bit mask representation using class enums.
Definition BitMask.hxx:19
BitMask & limit(const BitMask other)
Sets all bits to zero except the bits in the given mask.
Definition BitMask.hxx:149
friend BitMask operator-(const BitMask &first, const ENUM val)
Returns an object containing all the bits found in first without val.
Definition BitMask.hxx:284
BitMask & set(const BitMask other)
Sets all the bits that are also set in other.
Definition BitMask.hxx:97
BitMask & flip(const ENUM val)
Flips the given value.
Definition BitMask.hxx:166
friend BitMask operator+(const BitMask &first, const BitMask &second)
Returns an object containing all the bits found in first and second.
Definition BitMask.hxx:290
bool anyOf(const std::initializer_list< ENUM > &flags) const
Returns whether any of the given values is set.
Definition BitMask.hxx:237
constexpr size_t size() const
Returns the maximum number of bits that can be stored in the bit mask.
Definition BitMask.hxx:185
BitMask & reset()
Sets all bits to zero.
Definition BitMask.hxx:103
bool operator&(const ENUM val) const
Checks whether any bit of the given value is set,.
Definition BitMask.hxx:264
constexpr BitMask(const EnumBaseType value)
Sets exactly the given primitive type bitmask.
Definition BitMask.hxx:51
BitMask & limit(const std::initializer_list< ENUM > &flags)
Sets all bits to zero except the given flags.
Definition BitMask.hxx:133
size_t count() const
Returns the number of set bits.
Definition BitMask.hxx:172
friend BitMask operator+(const BitMask &first, const ENUM val)
Returns an object containing all the bits found in first and /also val.
Definition BitMask.hxx:296
bool only(const ENUM val) const
Returns whether this is the only value set.
Definition BitMask.hxx:213
BitMask & set(const All)
Sets all bits it the set.
Definition BitMask.hxx:77
friend BitMask operator-(const BitMask &first, const BitMask &second)
Returns an object containing all the bits found in first without the bits found inc second.
Definition BitMask.hxx:278
bool testAny(const ENUM val) const
Returns whether any of the bits of val are set.
Definition BitMask.hxx:207
BitMask & limit(const ENUM flag)
Sets all bits to zero except the given flag.
Definition BitMask.hxx:144
constexpr BitMask()
Sets all bits to zero.
Definition BitMask.hxx:31
bool test(const ENUM val) const
Returns whether the given value is set.
Definition BitMask.hxx:194
BitMask & flip()
Flip every bit in the bit mask.
Definition BitMask.hxx:160
constexpr BitMask(const std::initializer_list< ENUM > &init_list)
Sets only the flags found in the given initializer list.
Definition BitMask.hxx:39
ENUM operator&(const BitMask &other) const
returns an ENUM value containing only the values found in both masks.
Definition BitMask.hxx:269
BitMask & set(const ENUM val, bool on_off=true)
Set or unset the given value.
Definition BitMask.hxx:83
bool any() const
Returns whether any bit in the bitset is set.
Definition BitMask.hxx:218
bool operator[](const ENUM flag) const
Returns a boolean value for the given value,.
Definition BitMask.hxx:62
BitMask(const All a)
Sets all bits to one.
Definition BitMask.hxx:34
bool allOf(const std::initializer_list< ENUM > &flags) const
Tests whether all of the given values are set.
Definition BitMask.hxx:223
constexpr BitMask(const ENUM val)
Sets exactly the given value to one.
Definition BitMask.hxx:46
bool none() const
Returns whether no bit in the bitset is set.
Definition BitMask.hxx:251
BitMask & reset(const ENUM val)
Zeroes the given value.
Definition BitMask.hxx:109
EnumBaseType raw() const
Returns the raw bitfield integer.
Definition BitMask.hxx:56
BitMask & reset(const std::initializer_list< ENUM > &flags)
Zeroes all of the given values.
Definition BitMask.hxx:115
Helper type for setting all bits during construction time of BitMask.
Definition BitMask.hxx:23