CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Flags.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
12
13#include <utility>
14
15namespace CeresEngine {
16
19 template<typename Enum, typename Storage = std::underlying_type_t<Enum>> struct Flags {
21
22 constexpr Flags() noexcept = default;
23
26 constexpr Flags(Enum value) noexcept // NOLINT
27 : raw(static_cast<Storage>(value)) {}
28
32 constexpr Flags& operator=(Enum value) noexcept {
33 raw = static_cast<Storage>(value);
34 return *this;
35 }
36
39 constexpr Flags(const std::initializer_list<Enum>& values) noexcept {
40 for(Enum value : values) {
41 set(value);
42 }
43 }
44
45 constexpr Flags(const Flags& value) noexcept : raw(value.raw) {}
46 constexpr Flags& operator=(const Flags& rhs) noexcept {
47 raw = rhs.raw;
48 return *this;
49 }
50
51 explicit constexpr Flags(Storage bits) noexcept : raw(bits) {}
52
54 [[nodiscard]] constexpr bool isSet(Enum value) const noexcept {
55 return (raw & static_cast<Storage>(value)) == static_cast<Storage>(value); // NOLINT
56 }
57
59 [[nodiscard]] constexpr bool isSet(const Flags& value) const noexcept {
60 return (raw & value.raw) == value.raw; // NOLINT
61 }
62
64 [[nodiscard]] constexpr bool isSetAny(Enum value) const noexcept {
65 return (raw & static_cast<Storage>(value)) != 0; // NOLINT
66 }
67
69 [[nodiscard]] constexpr bool isSetAny(const Flags& value) const noexcept {
70 return (raw & value.raw) != 0; // NOLINT
71 }
72
74 constexpr Flags& set(Enum value) noexcept {
75 raw |= static_cast<Storage>(value); // NOLINT
76 return *this;
77 }
78
80 constexpr Flags& set(Enum value, const bool state) noexcept {
81 if(state) {
82 set(value);
83 } else {
84 unset(value);
85 }
86 return *this;
87 }
88
90 constexpr Flags& unset(Enum value) noexcept {
91 raw &= ~static_cast<Storage>(value); // NOLINT
92 return *this;
93 }
94
96 constexpr Flags& unset(const Flags<Enum> value) noexcept {
97 raw &= ~static_cast<Storage>(value.raw); // NOLINT
98 return *this;
99 }
100
104 constexpr bool setIfUnset(Enum value) noexcept {
105 if(isSet(value)) {
106 return false;
107 }
108
109 set(value);
110 return true;
111 }
112
116 constexpr bool unsetIfSet(Enum value) noexcept {
117 if(!isSet(value)) {
118 return false;
119 }
120
121 unset(value);
122 return true;
123 }
124
125 constexpr bool operator==(Enum rhs) const noexcept { return raw == static_cast<Storage>(rhs); }
126 constexpr bool operator==(const Flags& rhs) const noexcept { return raw == rhs.raw; }
127 constexpr bool operator==(const bool rhs) const noexcept { return ((bool)*this) == rhs; }
128
129 constexpr bool operator!=(Enum rhs) const noexcept { return raw != static_cast<Storage>(rhs); }
130 constexpr bool operator!=(const Flags& rhs) const noexcept { return raw != rhs.raw; }
131
132 constexpr Flags& operator|=(Enum rhs) noexcept {
133 raw |= static_cast<Storage>(rhs); // NOLINT
134 return *this;
135 }
136
137 constexpr Flags& operator|=(const Flags& rhs) noexcept {
138 raw |= rhs.raw; // NOLINT
139 return *this;
140 }
141
142 constexpr Flags operator|(Enum rhs) const noexcept {
143 Flags out(*this);
144 out |= rhs; // NOLINT
145 return out;
146 }
147
148 constexpr Flags operator|(const Flags& rhs) const noexcept {
149 Flags out(*this);
150 out |= rhs; // NOLINT
151 return out;
152 }
153
154 constexpr Flags& operator&=(Enum rhs) noexcept {
155 raw &= static_cast<Storage>(rhs); // NOLINT
156 return *this;
157 }
158
159 constexpr Flags& operator&=(const Flags& rhs) noexcept {
160 raw &= rhs.raw; // NOLINT
161 return *this;
162 }
163
164 constexpr Flags operator&(Enum rhs) const noexcept {
165 Flags out = *this;
166 out.raw &= static_cast<Storage>(rhs); // NOLINT
167 return out;
168 }
169
170 constexpr Flags operator&(const Flags& rhs) const noexcept {
171 Flags out = *this;
172 out.raw &= rhs.raw; // NOLINT
173 return out;
174 }
175
176 constexpr Flags& operator^=(Enum rhs) noexcept {
177 raw ^= static_cast<Storage>(rhs); // NOLINT
178 return *this;
179 }
180
181 constexpr Flags& operator^=(const Flags& rhs) noexcept {
182 raw ^= rhs.raw; // NOLINT
183 return *this;
184 }
185
186 constexpr Flags operator^(Enum rhs) const noexcept {
187 Flags out = *this;
188 out.raw ^= static_cast<Storage>(rhs); // NOLINT
189 return out;
190 }
191
192 constexpr Flags operator^(const Flags& rhs) const noexcept {
193 Flags out = *this;
194 out.raw ^= rhs.raw; // NOLINT
195 return out;
196 }
197
199 Flags out;
200 out.raw = (Storage)~raw; // NOLINT
201 return out;
202 }
203
204 explicit constexpr operator Enum() const noexcept { return static_cast<Enum>(raw); }
205 explicit constexpr operator Storage() const noexcept { return static_cast<UInt8>(raw); }
206 explicit constexpr operator bool() const noexcept { return raw ? true : false; }
207
208 friend constexpr Flags operator&(Enum a, Flags& b) noexcept {
209 Flags out;
210 out.raw = a & b.raw;
211 return out;
212 }
213 };
214
216#define CE_FLAGS_OPERATORS(Enum) CE_FLAGS_OPERATORS_EXT(Enum, std::underlying_type_t<Enum>)
217
219#define CE_FLAGS_OPERATORS_EXT(Enum, Storage) \
220 [[nodiscard]] inline constexpr Flags<Enum, Storage> operator|(Enum a, Enum b) noexcept { \
221 Flags<Enum, Storage> r(a); \
222 r |= b; /* NOLINT */ \
223 return r; \
224 } \
225 \
226 [[nodiscard]] inline constexpr Flags<Enum, Storage> operator&(Enum a, Enum b) noexcept { \
227 Flags<Enum, Storage> r(a); \
228 r &= b; /* NOLINT */ \
229 return r; \
230 } \
231 \
232 [[nodiscard]] inline constexpr Flags<Enum, Storage> operator~(Enum a) noexcept { return ~Flags<Enum, Storage>(a); }
233
234 // Common flags class.
235 class RawFlags {
236 public:
237 unsigned int raw = 0;
238
239 RawFlags() = default;
240 RawFlags(const RawFlags&) = default;
241 RawFlags& operator=(const RawFlags&) = default;
242
243 // Initializes the object with the specified flags.
244 inline RawFlags(const unsigned int flags) : raw{flags} {}
245
246 // Sets the specified flag only once and returns true if the flag has not already been set.
247 inline bool setOnce(const unsigned int flag) {
248 if(!all(flag)) {
249 *this << flag;
250 return true;
251 }
252 return false;
253 }
254
255 // Sets the specified flag.
256 inline void insert(const unsigned int flag) { raw |= flag; }
257
258 // Removes the specified flag.
259 inline void remove(const unsigned int flag) { raw &= (~flag); }
260
261 // Sets the specified flag (see 'Insert' function).
262 inline RawFlags& operator<<(const unsigned int flag) {
263 insert(flag);
264 return *this;
265 }
266
267 // Returns true if this flags instance has any of the specified flags.
268 [[nodiscard]] inline bool any(const unsigned int flags) const { return ((raw & flags) != 0); }
269
270 // Returns true if this flags instance has all of the specified flags.
271 [[nodiscard]] inline bool all(const unsigned int flags) const { return ((raw & flags) == flags); }
272
273 // Returns true if the specified flag is set.
274 inline bool operator()(const unsigned int flag) const { return any(flag); }
275
276 // Returns the flags bit mask.
277 inline operator unsigned int() const { return raw; }
278 };
279
280} // namespace CeresEngine
281
283template<class Enum, class Storage> struct std::hash<CeresEngine::Flags<Enum, Storage>> {
284 size_t operator()(const CeresEngine::Flags<Enum, Storage>& key) const {
285 std::hash<Storage> hasher{};
286 return hasher(key.raw);
287 }
288};
Represents a reflected enum from C++.
Definition Enum.hpp:26
Definition Flags.hpp:235
RawFlags(const RawFlags &)=default
bool any(const unsigned int flags) const
Definition Flags.hpp:268
void remove(const unsigned int flag)
Definition Flags.hpp:259
bool all(const unsigned int flags) const
Definition Flags.hpp:271
void insert(const unsigned int flag)
Definition Flags.hpp:256
bool setOnce(const unsigned int flag)
Definition Flags.hpp:247
RawFlags & operator=(const RawFlags &)=default
unsigned int raw
Definition Flags.hpp:237
RawFlags(const unsigned int flags)
Definition Flags.hpp:244
RawFlags & operator<<(const unsigned int flag)
Definition Flags.hpp:262
bool operator()(const unsigned int flag) const
Definition Flags.hpp:274
Definition Application.hpp:19
auto values(Container &container)
Returns an iterable object that iterates over the values of a map-like container.
Definition Iterator.hpp:400
struct CeresEngine::GLState state
std::uint8_t UInt8
Definition DataTypes.hpp:17
@ Storage
Storage buffer type (also called "Shader Storage Buffer Object" or "Read/Write Buffer").
@ Flags
Indicates that only the object flags are dirty.
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Wrapper around an enum that allows simple use of bitwise logic operations.
Definition Flags.hpp:19
constexpr Flags(const Flags &value) noexcept
Definition Flags.hpp:45
constexpr bool operator==(Enum rhs) const noexcept
Definition Flags.hpp:125
constexpr bool operator==(const Flags &rhs) const noexcept
Definition Flags.hpp:126
constexpr Flags() noexcept=default
constexpr Flags & operator=(Enum value) noexcept
Assigns the Flags object with the given enum value.
Definition Flags.hpp:32
constexpr Flags operator&(const Flags &rhs) const noexcept
Definition Flags.hpp:170
constexpr Flags & operator=(const Flags &rhs) noexcept
Definition Flags.hpp:46
Storage raw
Definition Flags.hpp:20
constexpr Flags operator&(Enum rhs) const noexcept
Definition Flags.hpp:164
constexpr bool setIfUnset(Enum value) noexcept
Sets a set of bits only if any of it's bits were previously unset.
Definition Flags.hpp:104
constexpr Flags & operator^=(const Flags &rhs) noexcept
Definition Flags.hpp:181
constexpr Flags & set(Enum value, const bool state) noexcept
Activates or deactives all of the provided bits.
Definition Flags.hpp:80
constexpr Flags operator~() const noexcept
Definition Flags.hpp:198
constexpr Flags operator|(Enum rhs) const noexcept
Definition Flags.hpp:142
constexpr bool operator!=(Enum rhs) const noexcept
Definition Flags.hpp:129
constexpr bool operator!=(const Flags &rhs) const noexcept
Definition Flags.hpp:130
constexpr Flags & operator&=(Enum rhs) noexcept
Definition Flags.hpp:154
constexpr bool isSet(const Flags &value) const noexcept
Checks whether all of the provided bits are set.
Definition Flags.hpp:59
constexpr bool isSetAny(const Flags &value) const noexcept
Checks whether any of the provided bits are set.
Definition Flags.hpp:69
constexpr bool operator==(const bool rhs) const noexcept
Definition Flags.hpp:127
constexpr bool isSet(Enum value) const noexcept
Checks whether all of the provided bits are set.
Definition Flags.hpp:54
constexpr Flags(const std::initializer_list< Enum > &values) noexcept
Creates a new Flags object from a list of values.
Definition Flags.hpp:39
constexpr Flags & unset(Enum value) noexcept
Deactivates all of the provided bits.
Definition Flags.hpp:90
constexpr Flags(Storage bits) noexcept
Definition Flags.hpp:51
constexpr Flags & set(Enum value) noexcept
Activates all of the provided bits.
Definition Flags.hpp:74
constexpr Flags & operator|=(const Flags &rhs) noexcept
Definition Flags.hpp:137
constexpr Flags & unset(const Flags< Enum > value) noexcept
Deactivates all of the provided bits.
Definition Flags.hpp:96
constexpr Flags & operator|=(Enum rhs) noexcept
Definition Flags.hpp:132
constexpr Flags & operator&=(const Flags &rhs) noexcept
Definition Flags.hpp:159
constexpr Flags & operator^=(Enum rhs) noexcept
Definition Flags.hpp:176
constexpr Flags operator|(const Flags &rhs) const noexcept
Definition Flags.hpp:148
constexpr bool unsetIfSet(Enum value) noexcept
Unsets a set of bits only if any of it's bits were previously set.
Definition Flags.hpp:116
friend constexpr Flags operator&(Enum a, Flags &b) noexcept
Definition Flags.hpp:208
constexpr Flags operator^(const Flags &rhs) const noexcept
Definition Flags.hpp:192
constexpr Flags operator^(Enum rhs) const noexcept
Definition Flags.hpp:186
constexpr bool isSetAny(Enum value) const noexcept
Checks whether any of the provided bits are set.
Definition Flags.hpp:64