Gamedev Framework (gf) 0.22.0
A C++17 framework for 2D games
Flags.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2022 Julien Bernard
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21#ifndef GF_FLAGS_H
22#define GF_FLAGS_H
23
24#include <type_traits>
25
26#include "Types.h"
27
28namespace gf {
29#ifndef DOXYGEN_SHOULD_SKIP_THIS
30inline namespace v1 {
31#endif
32
45 template<typename E>
46 class Flags {
47 public:
51 Flags() = default;
52
56 constexpr Flags(NoneType)
57 : m_data(0)
58 {
59
60 }
61
65 constexpr Flags(AllType)
66 : m_data(static_cast<Type>(~0))
67 {
68
69 }
70
76 constexpr Flags(E e)
77 : m_data(static_cast<Type>(e))
78 {
79
80 }
81
87 constexpr Flags<E> operator~() const {
88 return Flags(~m_data);
89 }
90
97 constexpr Flags operator|(Flags flags) const {
98 return Flags(m_data | flags.m_data);
99 }
100
108 m_data |= flags.m_data;
109 return *this;
110 }
111
118 constexpr Flags operator&(Flags flags) const {
119 return Flags(m_data & flags.m_data);
120 }
121
129 m_data &= flags.m_data;
130 return *this;
131 }
132
138 constexpr operator bool() const {
139 return m_data != 0;
140 }
141
148 constexpr bool test(E flag) const {
149 return (m_data & static_cast<Type>(flag)) != 0;
150 }
151
157 void set(E flag) {
158 m_data |= static_cast<Type>(flag);
159 }
160
166 void reset(E flag) {
167 m_data &= ~static_cast<Type>(flag);
168 }
169
173 using Type = typename std::underlying_type<E>::type;
174
182 Type getValue() const {
183 return m_data;
184 }
185
186 private:
187 constexpr Flags(Type data)
188 : m_data(data)
189 {
190
191 }
192
193 Type m_data;
194 };
195
204 template<typename E>
205 constexpr
207 return lhs | Flags<E>(rhs);
208 }
209
218 template<typename E>
219 constexpr
221 return Flags<E>(lhs) | rhs;
222 }
223
232 template<typename E>
233 constexpr
235 return lhs & Flags<E>(rhs);
236 }
237
246 template<typename E>
247 constexpr
249 return Flags<E>(lhs) & rhs;
250 }
251
252
260 template<typename E>
261 constexpr Flags<E> combineFlags(E flag) {
262 return Flags<E>(flag);
263 }
264
273 template<typename E, typename ... F>
274 constexpr Flags<E> combineFlags(E flag, F ... others) {
275 return Flags<E>(flag) | combineFlags(others ...);
276 }
277
278#ifndef DOXYGEN_SHOULD_SKIP_THIS
279}
280
281
282// this traits is not versioned
283
284template<typename E>
285struct EnableBitmaskOperators {
286 static constexpr bool value = false;
287};
288
289// these overloads are only available to gf enum types and gf flags
290// unless you add: "using gf::operator|;"
291
292template<typename E>
293constexpr
294typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
295operator|(E lhs, E rhs) {
296 return gf::Flags<E>(lhs) | gf::Flags<E>(rhs);
297}
298
299template<typename E>
300constexpr
301typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
302operator&(E lhs, E rhs) {
303 return gf::Flags<E>(lhs) & gf::Flags<E>(rhs);
304}
305
306template<typename E>
307constexpr
308typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
309operator~(E val) {
310 return ~gf::Flags<E>(val);
311}
312
313#endif
314}
315
316#endif // GF_FLAGS_H
Bitfield relying on an enumeration.
Definition: Flags.h:46
constexpr Flags< E > combineFlags(E flag, F ... others)
Combine several enum values into a flag value.
Definition: Flags.h:274
constexpr Flags(E e)
Constructor with an enum value.
Definition: Flags.h:76
Flags< E > & operator|=(Flags< E > flags)
Binary OR and assignment.
Definition: Flags.h:107
constexpr Flags(NoneType)
Constructor with no flag set.
Definition: Flags.h:56
typename std::underlying_type< E >::type Type
The underlying type of the enum.
Definition: Flags.h:173
Flags()=default
Default constructor.
constexpr Flags< E > operator|(Flags< E > lhs, E rhs)
Binary OR between a bitfield and a flag.
Definition: Flags.h:206
Type getValue() const
Get the underlying value of the flags.
Definition: Flags.h:182
constexpr Flags< E > operator~() const
Binary NOT operator.
Definition: Flags.h:87
constexpr Flags< E > operator&(E lhs, Flags< E > rhs)
Binary AND between a flag and a bitfield.
Definition: Flags.h:248
void set(E flag)
Set a flag.
Definition: Flags.h:157
constexpr Flags< E > operator|(E lhs, Flags< E > rhs)
Binary OR between a flag and a bitfield.
Definition: Flags.h:220
Flags< E > & operator&=(Flags< E > flags)
Binary AND and assignment.
Definition: Flags.h:128
constexpr Flags< E > operator&(Flags< E > lhs, E rhs)
Binary AND between a bitfield and a flag.
Definition: Flags.h:234
constexpr Flags operator|(Flags flags) const
Binary OR between two bitfields.
Definition: Flags.h:97
constexpr Flags operator&(Flags flags) const
Binary AND between two bitfields.
Definition: Flags.h:118
void reset(E flag)
Reset a flag.
Definition: Flags.h:166
constexpr Flags(AllType)
Constructor with all flags set.
Definition: Flags.h:65
constexpr bool test(E flag) const
Test if a specified flag is set.
Definition: Flags.h:148
constexpr Flags< E > combineFlags(E flag)
Combine a single enum value into a flag value.
Definition: Flags.h:261
The namespace for gf classes.
Semantic type to represent "all".
Definition: Types.h:53
Semantic type to represent "none".
Definition: Types.h:37