A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
BitFlag.hh
1#pragma once
2
3#include <Logger.hh>
4
5#include <array>
6#include <cstddef>
7#include <cstdint>
8#include <limits>
9#include <type_traits>
10
11namespace Kinoko {
12
13// We can't include Common.hh, because we have a cyclic dependency
14typedef uint32_t u32;
15
16namespace EGG {
17
21template <typename T, typename E>
22 requires(std::is_enum_v<E> && std::is_integral_v<T>)
23struct TBitFlag {
26 constexpr TBitFlag() {
27 makeAllZero();
28 }
29
33 constexpr TBitFlag(T mask) {
34 setDirect(mask);
35 }
36
40 constexpr TBitFlag(E e) : TBitFlag() {
41 setBit(e);
42 }
43
45 [[nodiscard]] constexpr operator T() const {
46 return getDirect();
47 }
48
52 constexpr TBitFlag<T, E> &operator=(const TBitFlag<T, E> &rhs) {
53 bits = rhs.bits;
54 return *this;
55 }
56
62 template <typename... Es>
63 requires(std::is_same_v<Es, E> && ...)
64 constexpr TBitFlag<T, E> &setBit(Es... es) {
65 (setBit_(es), ...);
66 return *this;
67 }
68
73 template <typename... Es>
74 requires(std::is_same_v<Es, E> && ...)
75 constexpr TBitFlag<T, E> &resetBit(Es... es) {
76 (resetBit_(es), ...);
77 return *this;
78 }
79
85 template <typename... Es>
86 requires(std::is_same_v<Es, E> && ...)
87 constexpr TBitFlag<T, E> &changeBit(bool on, Es... es) {
88 (changeBit_(on, es), ...);
89 return *this;
90 }
91
96 template <typename... Es>
97 requires(std::is_same_v<Es, E> && ...)
98 constexpr TBitFlag<T, E> &toggleBit(Es... es) {
99 (toggleBit_(es), ...);
100 return *this;
101 }
102
108 template <typename... Es>
109 requires(std::is_same_v<Es, E> && ...)
110 [[nodiscard]] constexpr bool onBit(Es... es) const {
111 return (onAnyBit(es...));
112 }
113
119 template <typename... Es>
120 requires(std::is_same_v<Es, E> && ...)
121 [[nodiscard]] constexpr bool onAnyBit(Es... es) const {
122 return (onBit_(es) || ...);
123 }
124
130 template <typename... Es>
131 requires(std::is_same_v<Es, E> && ...)
132 [[nodiscard]] constexpr bool onAllBit(Es... es) const {
133 return (onBit_(es) && ...);
134 }
135
141 template <typename... Es>
142 requires(std::is_same_v<Es, E> && ...)
143 [[nodiscard]] constexpr bool offBit(Es... es) const {
144 return offAllBit(es...);
145 }
146
152 template <typename... Es>
153 requires(std::is_same_v<Es, E> && ...)
154 [[nodiscard]] constexpr bool offAllBit(Es... es) const {
155 return (offBit_(es) && ...);
156 }
157
163 template <typename... Es>
164 requires(std::is_same_v<Es, E> && ...)
165 [[nodiscard]] constexpr bool offAnyBit(Es... es) const {
166 return (offBit_(es) || ...);
167 }
168
174 template <typename... Es>
175 requires(std::is_same_v<Es, E> && ...)
176 [[nodiscard]] constexpr T maskBit(Es... es) const {
177 return bits & makeMask(es...);
178 }
179
184 template <typename... Es>
185 requires(std::is_same_v<Es, E> && ...)
186 [[nodiscard]] constexpr T makeMask(Es... es) const {
187 return (makeMask_(es) | ...);
188 }
189
193 constexpr TBitFlag<T, E> &set(T mask) {
194 bits |= mask;
195 return *this;
196 }
197
201 constexpr TBitFlag<T, E> &reset(T mask) {
202 bits &= ~mask;
203 return *this;
204 }
205
210 constexpr TBitFlag<T, E> &change(bool on, T mask) {
211 return on ? set(mask) : reset(mask);
212 }
213
217 [[nodiscard]] constexpr bool on(T mask) const {
218 return (bits & mask) != 0;
219 }
220
224 [[nodiscard]] constexpr bool onAll(T mask) const {
225 return (bits | mask) == bits;
226 }
227
231 [[nodiscard]] constexpr bool off(T mask) const {
232 return (bits & mask) == 0;
233 }
234
236 constexpr void makeAllZero() {
237 bits = 0;
238 }
239
242 [[nodiscard]] constexpr T getDirect() const {
243 return bits;
244 }
245
248 constexpr void setDirect(T mask) {
249 bits = mask;
250 }
251
252private:
253 typedef std::underlying_type_t<E> EI;
254 static constexpr size_t MAX_CAPACITY = std::numeric_limits<T>::digits;
255
259 constexpr void setBit_(E e) {
260 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
261 set(makeMask_(e));
262 }
263
267 constexpr void resetBit_(E e) {
268 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
269 reset(makeMask_(e));
270 }
271
276 constexpr void changeBit_(bool on, E e) {
277 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
278 change(on, makeMask_(e));
279 }
280
284 constexpr void toggleBit_(E e) {
285 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
286 changeBit_(offBit_(e), e);
287 }
288
293 [[nodiscard]] constexpr bool onBit_(E e) const {
294 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
295 return on(makeMask_(e));
296 }
297
302 [[nodiscard]] constexpr bool offBit_(E e) const {
303 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
304 return off(makeMask_(e));
305 }
306
311 [[nodiscard]] constexpr T makeMask_(E e) const {
312 ASSERT(static_cast<EI>(e) < MAX_CAPACITY);
313 return static_cast<T>(1) << static_cast<T>(e);
314 }
315
317};
318
322template <size_t N, typename E>
323 requires(std::is_enum_v<E> && N > 64)
325public:
328 constexpr TBitFlagExt() {
329 makeAllZero();
330 }
331
335 std::fill(bits.begin(), bits.end(), 0);
336 return *this;
337 }
338
344 template <typename... Es>
345 requires(std::is_same_v<Es, E> && ...)
346 constexpr TBitFlagExt<N, E> &setBit(Es... es) {
347 (setBit_(es), ...);
348 return *this;
349 }
350
355 template <typename... Es>
356 requires(std::is_same_v<Es, E> && ...)
357 constexpr TBitFlagExt<N, E> &resetBit(Es... es) {
358 (resetBit_(es), ...);
359 return *this;
360 }
361
367 template <typename... Es>
368 requires(std::is_same_v<Es, E> && ...)
369 constexpr TBitFlagExt<N, E> &changeBit(bool on, Es... es) {
370 (changeBit_(on, es), ...);
371 return *this;
372 }
373
379 template <typename... Es>
380 requires(std::is_same_v<Es, E> && ...)
381 [[nodiscard]] constexpr bool onBit(Es... es) const {
382 return onAnyBit(es...);
383 }
384
390 template <typename... Es>
391 requires(std::is_same_v<Es, E> && ...)
392 [[nodiscard]] constexpr bool onAnyBit(Es... es) const {
393 return (onBit_(es) || ...);
394 }
395
401 template <typename... Es>
402 requires(std::is_same_v<Es, E> && ...)
403 [[nodiscard]] constexpr bool onAllBit(Es... es) const {
404 return (onBit_(es) && ...);
405 }
406
412 template <typename... Es>
413 requires(std::is_same_v<Es, E> && ...)
414 [[nodiscard]] constexpr bool offBit(Es... es) const {
415 return offAllBit(es...);
416 }
417
423 template <typename... Es>
424 requires(std::is_same_v<Es, E> && ...)
425 [[nodiscard]] constexpr bool offAllBit(Es... es) const {
426 return (offBit_(es) && ...);
427 }
428
434 template <typename... Es>
435 requires(std::is_same_v<Es, E> && ...)
436 [[nodiscard]] constexpr bool offAnyBit(Es... es) const {
437 return (offBit_(es) || ...);
438 }
439
440private:
441 typedef std::underlying_type_t<E> EI;
442
446 constexpr void setBit_(E e) {
447 auto [field, mask] = makeMask_(e);
448 field |= mask;
449 }
450
454 constexpr void resetBit_(E e) {
455 auto [field, mask] = makeMask_(e);
456 field &= ~mask;
457 }
458
463 [[nodiscard]] constexpr void changeBit_(bool on, E e) {
464 on ? setBit_(e) : resetBit_(e);
465 }
466
471 [[nodiscard]] constexpr bool onBit_(E e) const {
472 auto [field, mask] = makeMask_(e);
473 return (field & mask) != 0;
474 }
475
480 [[nodiscard]] constexpr bool offBit_(E e) const {
481 auto [field, mask] = makeMask_(e);
482 return (field & mask) == 0;
483 }
484
485 typedef u32 T;
486
491 [[nodiscard]] constexpr std::pair<T, T> makeMask_(E e) const {
492 EI ei = static_cast<EI>(e);
493 ASSERT(ei < N);
494 return std::pair<T, T>(bits[ei / C], static_cast<T>(1) << (ei % C));
495 }
496
501 [[nodiscard]] constexpr std::pair<T &, T> makeMask_(E e) {
502 EI ei = static_cast<EI>(e);
503 ASSERT(ei < N);
504 return std::pair<T &, T>(bits[ei / C], static_cast<T>(1) << (ei % C));
505 }
506
507 static constexpr size_t C = 8 * sizeof(T);
508 std::array<T, (N + C - 1) / C> bits;
509};
510
511} // namespace EGG
512
513} // namespace Kinoko
Wrapper around a variable length bitfield with an enum corresponding to its bits.
Definition BitFlag.hh:324
constexpr bool offBit_(E e) const
Checks if a specific bit is off.
Definition BitFlag.hh:480
constexpr void changeBit_(bool on, E e)
Internal. Changes a specific bit.
Definition BitFlag.hh:463
constexpr bool offBit(Es... es) const
Checks if all of the corresponding bits for the provided enum values are off.
Definition BitFlag.hh:414
constexpr bool onAnyBit(Es... es) const
Checks if any of the corresponding bits for the provided enum values are on.
Definition BitFlag.hh:392
constexpr bool offAnyBit(Es... es) const
Checks if any of the corresponding bits for the provided enum values are off.
Definition BitFlag.hh:436
constexpr bool onBit(Es... es) const
Checks if any of the corresponding bits for the provided enum values are on.
Definition BitFlag.hh:381
constexpr bool onAllBit(Es... es) const
Checks if all of the corresponding bits for the provided enum values are on.
Definition BitFlag.hh:403
constexpr TBitFlagExt< N, E > & makeAllZero()
Resets all the bits to zero across the entire bitfield array.
Definition BitFlag.hh:334
constexpr bool onBit_(E e) const
Checks if a specific bit is on.
Definition BitFlag.hh:471
constexpr std::pair< T &, T > makeMask_(E e)
Gets bit index and mask for a specific bit.
Definition BitFlag.hh:501
constexpr void setBit_(E e)
Internal. Sets a specific bit.
Definition BitFlag.hh:446
constexpr bool offAllBit(Es... es) const
Checks if all of the corresponding bits for the provided enum values are off.
Definition BitFlag.hh:425
constexpr TBitFlagExt()
Default constructor, initializes all flags to off.
Definition BitFlag.hh:328
constexpr std::pair< T, T > makeMask_(E e) const
Gets bit index and mask for a specific bit.
Definition BitFlag.hh:491
constexpr void resetBit_(E e)
Internal. Resets a specific bit.
Definition BitFlag.hh:454
constexpr TBitFlagExt< N, E > & resetBit(Es... es)
Resets the corresponding bits for the provided enum values.
Definition BitFlag.hh:357
Wrapper around an integral type with an enum corresponding to its bits.
Definition BitFlag.hh:23
constexpr TBitFlag< T, E > & change(bool on, T mask)
Changes the bits using a direct mask.
Definition BitFlag.hh:210
constexpr bool onAll(T mask) const
Checks if all bits are on in the specified mask.
Definition BitFlag.hh:224
constexpr void makeAllZero()
Resets all the bits to zero.
Definition BitFlag.hh:236
constexpr void changeBit_(bool on, E e)
Internal. Changes a specific bit.
Definition BitFlag.hh:276
constexpr TBitFlag< T, E > & toggleBit(Es... es)
Toggles the corresponding bits for the provided enum values.
Definition BitFlag.hh:98
constexpr TBitFlag< T, E > & resetBit(Es... es)
Resets the corresponding bits for the provided enum values.
Definition BitFlag.hh:75
constexpr bool offBit(Es... es) const
Checks if all of the corresponding bits for the provided enum values are off.
Definition BitFlag.hh:143
constexpr void setDirect(T mask)
Sets the bits using a direct mask.
Definition BitFlag.hh:248
constexpr bool off(T mask) const
Checks if all bits are off in the specified mask.
Definition BitFlag.hh:231
constexpr TBitFlag< T, E > & reset(T mask)
Resets the bits using a direct mask.
Definition BitFlag.hh:201
constexpr bool onAllBit(Es... es) const
Checks if all of the corresponding bits for the provided enum values are on.
Definition BitFlag.hh:132
constexpr TBitFlag()
Default constructor, initializes all flags to off.
Definition BitFlag.hh:26
constexpr bool offAllBit(Es... es) const
Checks if all of the corresponding bits for the provided enum values are off.
Definition BitFlag.hh:154
constexpr TBitFlag(T mask)
Constructor that initializes the bit flags with a given mask.
Definition BitFlag.hh:33
constexpr T makeMask(Es... es) const
Creates a mask of the corresponding bits for the provided enum values.
Definition BitFlag.hh:186
constexpr bool onBit_(E e) const
Checks if a specific bit is on.
Definition BitFlag.hh:293
constexpr bool offAnyBit(Es... es) const
Checks if any of the corresponding bits for the provided enum values are off.
Definition BitFlag.hh:165
constexpr void resetBit_(E e)
Internal. Resets a specific bit.
Definition BitFlag.hh:267
T bits
The bit mask representing the flags.
Definition BitFlag.hh:316
constexpr TBitFlag< T, E > & set(T mask)
Sets the bits using a direct mask.
Definition BitFlag.hh:193
constexpr TBitFlag< T, E > & operator=(const TBitFlag< T, E > &rhs)
Assignment operator.
Definition BitFlag.hh:52
constexpr bool on(T mask) const
Checks if any bits are on in the specified mask.
Definition BitFlag.hh:217
constexpr bool offBit_(E e) const
Checks if a specific bit is off.
Definition BitFlag.hh:302
constexpr bool onBit(Es... es) const
Checks if any of the corresponding bits for the provided enum values are on.
Definition BitFlag.hh:110
constexpr bool onAnyBit(Es... es) const
Checks if any of the corresponding bits for the provided enum values are on.
Definition BitFlag.hh:121
constexpr TBitFlag(E e)
Constructor that initializes the bit flags with a given enum.
Definition BitFlag.hh:40
constexpr T maskBit(Es... es) const
Creates an applied mask of the corresponding bits for the provided enum values.
Definition BitFlag.hh:176
constexpr T getDirect() const
Gets the current bit mask.
Definition BitFlag.hh:242
constexpr T makeMask_(E e) const
Creates a mask for a specific bit.
Definition BitFlag.hh:311
constexpr void toggleBit_(E e)
Internal. Toggles a specific bit.
Definition BitFlag.hh:284
constexpr void setBit_(E e)
Internal. Sets a specific bit.
Definition BitFlag.hh:259