Gamedev Framework (gf)  0.17.0
A C++14 framework for 2D games
Flags.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 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 
28 namespace gf {
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 inline 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
234  Flags<E> operator&(Flags<E> lhs, E rhs) {
235  return lhs & Flags<E>(rhs);
236  }
237 
246  template<typename E>
247  constexpr
248  Flags<E> operator&(E lhs, Flags<E> rhs) {
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 
284 template<typename E>
285 struct 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 
292 template<typename E>
293 constexpr
294 typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
295 operator|(E lhs, E rhs) {
296  return gf::Flags<E>(lhs) | gf::Flags<E>(rhs);
297 }
298 
299 template<typename E>
300 constexpr
301 typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
302 operator&(E lhs, E rhs) {
303  return gf::Flags<E>(lhs) & gf::Flags<E>(rhs);
304 }
305 
306 template<typename E>
307 constexpr
308 typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
309 operator~(E val) {
310  return ~gf::Flags<E>(val);
311 }
312 
313 #endif
314 }
315 
316 #endif // GF_FLAGS_H
typename std::underlying_type< Flip >::type Type
The underlying type of the enum.
Definition: Flags.h:173
Semantic type to represent "none".
Definition: Types.h:37
Bitfield relying on an enumeration.
Definition: Flags.h:46
Flags< E > & operator &=(Flags< E > flags)
Binary AND and assignment.
Definition: Flags.h:128
constexpr Flags< E > combineFlags(E flag, F ... others)
Combine several enum values into a flag value.
Definition: Flags.h:274
void reset(E flag)
Reset a flag.
Definition: Flags.h:166
constexpr Flags(NoneType)
Constructor with no flag set.
Definition: Flags.h:56
Semantic type to represent "all".
Definition: Types.h:53
constexpr Flags operator &(Flags flags) const
Binary AND between two bitfields.
Definition: Flags.h:118
constexpr Flags(AllType)
Constructor with all flags set.
Definition: Flags.h:65
constexpr Flags< E > operator~() const
Binary NOT operator.
Definition: Flags.h:87
constexpr Flags(E e)
Constructor with an enum value.
Definition: Flags.h:76
constexpr bool test(E flag) const
Test if a specified flag is set.
Definition: Flags.h:148
Type getValue() const
Get the underlying value of the flags.
Definition: Flags.h:182
The namespace for gf classes.
Definition: Action.h:35
Flags< E > & operator|=(Flags< E > flags)
Binary OR and assignment.
Definition: Flags.h:107
constexpr Flags operator|(Flags flags) const
Binary OR between two bitfields.
Definition: Flags.h:97
constexpr Flags< E > operator|(Flags< E > lhs, E rhs)
Binary OR between a bitfield and a flag.
Definition: Flags.h:206
constexpr Flags< E > operator|(E lhs, Flags< E > rhs)
Binary OR between a flag and a bitfield.
Definition: Flags.h:220
constexpr Flags< E > combineFlags(E flag)
Combine a single enum value into a flag value.
Definition: Flags.h:261