Gamedev Framework (gf)  0.2.0
A C++11 framework for 2D games
Flags.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 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  * Part of this file comes from SFML, with the same license:
22  * Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
23  */
24 #ifndef GF_FLAGS_H
25 #define GF_FLAGS_H
26 
27 #include <type_traits>
28 
29 namespace gf {
30 #ifndef DOXYGEN_SHOULD_SKIP_THIS
31 inline namespace v1 {
32 #endif
33 
34  /**
35  * @brief Bitfield relying on an enumeration
36  *
37  * ~~~
38  * enum class AnimalProperties {
39  * HasClaws = 0x01,
40  * CanFly = 0x02,
41  * EatsFish = 0x04,
42  * IsEndangered = 0x08,
43  * };
44  *
45  * namespace gf {
46  * template<>
47  * struct EnableBitmaskOperators<AnimalProperties> {
48  * static constexpr bool value = true;
49  * };
50  * }
51  *
52  * gf::Flags<AnimalProperties> seahawk = AnimalProperties::CanFly | AnimalProperties::EatsFish;
53  * seahawk |= AnimalProperties::IsEndangered;
54  *
55  * bool b = seahawk.test(AnimalProperties::HasClaws); // false
56  * ~~~
57  *
58  */
59  template<typename E>
60  class Flags {
61  public:
62  /**
63  * @brief Default constructor
64  */
65  constexpr Flags()
66  : m_data{0}
67  {
68 
69  }
70 
71  /**
72  * @brief Constructor with an enum value
73  *
74  * @param e An enum value
75  */
76  constexpr Flags(E e)
77  : m_data(static_cast<Type>(e))
78  {
79 
80  }
81 
82  /**
83  * @brief Binary NOT operator
84  *
85  * @returns A bitfield where all flags have been inverted
86  */
87  constexpr Flags<E> operator~() const {
88  return Flags(~m_data);
89  }
90 
91  /**
92  * @brief Binary OR and assignment
93  *
94  * @param flags Another bitfield
95  * @return The bitfield with a binary OR of the flags and the other's flags
96  */
97  Flags<E>& operator|=(const Flags<E>& flags) {
98  m_data |= flags.m_data;
99  return *this;
100  }
101 
102  /**
103  * @brief Binary AND and assignment
104  *
105  * @param flags Another bitfield
106  * @return The bitfield with a binary AND of the flags and the other's flags
107  */
108  Flags<E>& operator&=(const Flags<E>& flags) {
109  m_data &= flags.m_data;
110  return *this;
111  }
112 
113  /**
114  * @brief Test if any flag is set
115  *
116  * @returns True if any flag is set
117  */
118  operator bool() const {
119  return m_data != 0;
120  }
121 
122  /**
123  * @brief Test if a specified flag is set
124  *
125  * @param flag The flag to test
126  * @return True if the flag is set
127  */
128  bool test(E flag) const {
129  return (m_data & static_cast<Type>(flag)) != 0;
130  }
131 
132  /**
133  * @brief Set a flag
134  *
135  * @param flag The flag to set
136  */
137  void set(E flag) {
138  m_data |= static_cast<Type>(flag);
139  }
140 
141  /**
142  * @brief Reset a flag
143  *
144  * @param flag The flag to reset
145  */
146  void reset(E flag) {
147  m_data &= ~static_cast<Type>(flag);
148  }
149 
150  private:
151  using Type = typename std::underlying_type<E>::type;
152 
153  Flags(Type data)
154  : m_data(data)
155  {
156 
157  }
158 
159  Type m_data;
160  };
161 
162  /**
163  * @relates Flags
164  * @brief Binary OR between two bitfields
165  *
166  * @param lhs The first bitfield
167  * @param rhs The second bitfield
168  * @return The bitfield with a binary OR of the two bitfields
169  */
170  template<typename E>
171  inline
172  Flags<E> operator|(Flags<E> lhs, Flags<E> rhs) {
173  Flags<E> flags(lhs);
174  flags |= rhs;
175  return flags;
176  }
177 
178  /**
179  * @relates Flags
180  * @brief Binary OR between a bitfield and a flag
181  *
182  * @param lhs The bitfield
183  * @param rhs The flag
184  * @return The bitfield with a binary OR of the bitfield and the flag
185  */
186  template<typename E>
187  inline
188  Flags<E> operator|(Flags<E> lhs, E rhs) {
189  Flags<E> flags(lhs);
190  flags |= rhs;
191  return flags;
192  }
193 
194  /**
195  * @relates Flags
196  * @brief Binary AND between two bitfields
197  *
198  * @param lhs The first bitfield
199  * @param rhs The second bitfield
200  * @return The bitfield with a binary AND of the two bitfields
201  */
202  template<typename E>
203  inline
204  Flags<E> operator&(Flags<E> lhs, Flags<E> rhs) {
205  Flags<E> flags(lhs);
206  flags &= rhs;
207  return flags;
208  }
209 
210  /**
211  * @relates Flags
212  * @brief Binary AND between a bitfield and a flag
213  *
214  * @param lhs The bitfield
215  * @param rhs The flag
216  * @return The bitfield with a binary AND of the bitfield and the flag
217  */
218  template<typename E>
219  inline
220  Flags<E> operator&(Flags<E> lhs, E rhs) {
221  Flags<E> flags(lhs);
222  flags &= rhs;
223  return flags;
224  }
225 
226 #ifndef DOXYGEN_SHOULD_SKIP_THIS
227 }
228 #endif
229 
230 #ifndef DOXYGEN_SHOULD_SKIP_THIS
231 // this traits is not versioned to ease external usage
232 template<typename E>
233 struct EnableBitmaskOperators {
234  static constexpr bool value = false;
235 };
236 #endif
237 
238 }
239 
240 
241 #ifndef DOXYGEN_SHOULD_SKIP_THIS
242 template<typename E>
243 typename std::enable_if<gf::EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
244 operator|(E lhs, E rhs){
245  gf::Flags<E> flags(lhs);
246  flags |= rhs;
247  return flags;
248 }
249 
250 template<typename E>
251 typename std::enable_if<gf::EnableBitmaskOperators<E>::value, gf::Flags<E>>::type
252 operator&(E lhs, E rhs){
253  gf::Flags<E> flags(lhs);
254  flags &= rhs;
255  return flags;
256 }
257 #endif
258 
259 #endif // GF_FLAGS_H
Flags< E > & operator|=(const Flags< E > &flags)
Binary OR and assignment.
Definition: Flags.h:97
operator bool() const
Test if any flag is set.
Definition: Flags.h:118
Bitfield relying on an enumeration.
Definition: Flags.h:60
Flags< E > & operator&=(const Flags< E > &flags)
Binary AND and assignment.
Definition: Flags.h:108
void reset(E flag)
Reset a flag.
Definition: Flags.h:146
Flags< E > operator&(Flags< E > lhs, Flags< E > rhs)
Binary AND between two bitfields.
Definition: Flags.h:204
void set(E flag)
Set a flag.
Definition: Flags.h:137
constexpr Flags(E e)
Constructor with an enum value.
Definition: Flags.h:76
Definition: Action.h:34
Flags< E > operator|(Flags< E > lhs, Flags< E > rhs)
Binary OR between two bitfields.
Definition: Flags.h:172
bool test(E flag) const
Test if a specified flag is set.
Definition: Flags.h:128
Flags< E > operator|(Flags< E > lhs, E rhs)
Binary OR between a bitfield and a flag.
Definition: Flags.h:188
constexpr Flags()
Default constructor.
Definition: Flags.h:65
constexpr Flags< E > operator~() const
Binary NOT operator.
Definition: Flags.h:87
Flags< E > operator&(Flags< E > lhs, E rhs)
Binary AND between a bitfield and a flag.
Definition: Flags.h:220