Gamedev Framework (gf)  0.10.0
A C++14 framework for 2D games
Flags.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2018 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 
67  template<typename E>
68  class Flags {
69  public:
73  Flags() = default;
74 
78  constexpr Flags(NoneType)
79  : m_data(0)
80  {
81 
82  }
83 
87  constexpr Flags(AllType)
88  : m_data(static_cast<Type>(~0))
89  {
90 
91  }
92 
98  constexpr Flags(E e)
99  : m_data(static_cast<Type>(e))
100  {
101 
102  }
103 
109  constexpr Flags<E> operator~() const {
110  return Flags(~m_data);
111  }
112 
119  constexpr Flags operator|(Flags flags) const {
120  return Flags(m_data | flags.m_data);
121  }
122 
130  m_data |= flags.m_data;
131  return *this;
132  }
133 
140  constexpr Flags operator&(Flags flags) const {
141  return Flags(m_data & flags.m_data);
142  }
143 
151  m_data &= flags.m_data;
152  return *this;
153  }
154 
160  constexpr operator bool() const {
161  return m_data != 0;
162  }
163 
170  constexpr bool test(E flag) const {
171  return (m_data & static_cast<Type>(flag)) != 0;
172  }
173 
179  void set(E flag) {
180  m_data |= static_cast<Type>(flag);
181  }
182 
188  void reset(E flag) {
189  m_data &= ~static_cast<Type>(flag);
190  }
191 
195  using Type = typename std::underlying_type<E>::type;
196 
204  Type getValue() const {
205  return m_data;
206  }
207 
208  private:
209  constexpr Flags(Type data)
210  : m_data(data)
211  {
212 
213  }
214 
215  Type m_data;
216  };
217 
226  template<typename E>
227  constexpr
229  return lhs | Flags<E>(rhs);
230  }
231 
240  template<typename E>
241  constexpr
243  return Flags<E>(lhs) | rhs;
244  }
245 
254  template<typename E>
255  constexpr
256  Flags<E> operator&(Flags<E> lhs, E rhs) {
257  return lhs & Flags<E>(rhs);
258  }
259 
268  template<typename E>
269  constexpr
270  Flags<E> operator&(E lhs, Flags<E> rhs) {
271  return Flags<E>(lhs) & rhs;
272  }
273 
274 
282  template<typename E>
283  constexpr Flags<E> combineFlags(E flag) {
284  return Flags<E>(flag);
285  }
286 
295  template<typename E, typename ... F>
296  constexpr Flags<E> combineFlags(E flag, F ... others) {
297  return Flags<E>(flag) | combineFlags(others ...);
298  }
299 
300 #ifndef DOXYGEN_SHOULD_SKIP_THIS
301 }
302 
303 
304 // this traits is not versioned
305 
306 template<typename E>
307 struct EnableBitmaskOperators {
308  static constexpr bool value = false;
309 };
310 
311 // these overloads are only available to gf enum types and gf flags
312 // unless you add: "using gf::operator|;"
313 
314 template<typename E>
315 constexpr
316 typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
317 operator|(E lhs, E rhs) {
318  return gf::Flags<E>(lhs) | gf::Flags<E>(rhs);
319 }
320 
321 template<typename E>
322 constexpr
323 typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
324 operator&(E lhs, E rhs) {
325  return gf::Flags<E>(lhs) & gf::Flags<E>(rhs);
326 }
327 
328 template<typename E>
329 constexpr
330 typename std::enable_if<EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
331 operator~(E val) {
332  return ~gf::Flags<E>(val);
333 }
334 
335 #endif
336 }
337 
338 #endif // GF_FLAGS_H
typename std::underlying_type< Flip >::type Type
The underlying type of the enum.
Definition: Flags.h:195
Semantic type to represent "none".
Definition: Types.h:37
Bitfield relying on an enumeration.
Definition: Flags.h:68
Flags< E > & operator &=(Flags< E > flags)
Binary AND and assignment.
Definition: Flags.h:150
constexpr Flags< E > combineFlags(E flag, F ... others)
Combine several enum values into a flag value.
Definition: Flags.h:296
void reset(E flag)
Reset a flag.
Definition: Flags.h:188
constexpr Flags(NoneType)
Constructor with no flag set.
Definition: Flags.h:78
Semantic type to represent "all".
Definition: Types.h:53
constexpr Flags operator &(Flags flags) const
Binary AND between two bitfields.
Definition: Flags.h:140
constexpr Flags(AllType)
Constructor with all flags set.
Definition: Flags.h:87
constexpr Flags< E > operator~() const
Binary NOT operator.
Definition: Flags.h:109
constexpr Flags(E e)
Constructor with an enum value.
Definition: Flags.h:98
constexpr bool test(E flag) const
Test if a specified flag is set.
Definition: Flags.h:170
Type getValue() const
Get the underlying value of the flags.
Definition: Flags.h:204
The namespace for gf classes.
Definition: Action.h:34
Flags< E > & operator|=(Flags< E > flags)
Binary OR and assignment.
Definition: Flags.h:129
constexpr Flags operator|(Flags flags) const
Binary OR between two bitfields.
Definition: Flags.h:119
constexpr Flags< E > operator|(Flags< E > lhs, E rhs)
Binary OR between a bitfield and a flag.
Definition: Flags.h:228
Deserializer & operator|(Deserializer &ar, T &data)
Definition: SerializationOps.h:313
constexpr Flags< E > operator|(E lhs, Flags< E > rhs)
Binary OR between a flag and a bitfield.
Definition: Flags.h:242
constexpr Flags< E > combineFlags(E flag)
Combine a single enum value into a flag value.
Definition: Flags.h:283