4#include <initializer_list>
13 template <
typename TEnumType>
15 std::is_enum_v<TEnumType> &&
16 (
sizeof(std::underlying_type_t<TEnumType>) <= 4);
23 std::is_unsigned_v<T> &&
24 (
sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4);
33template <spk::bitmask_enum TEnumType>
34constexpr TEnumType operator|(TEnumType p_l, TEnumType p_r)
noexcept
36 using U = std::underlying_type_t<TEnumType>;
37 return static_cast<TEnumType
>(
static_cast<U
>(p_l) |
static_cast<U
>(p_r));
45template <spk::bitmask_enum TEnumType>
46constexpr TEnumType operator&(TEnumType p_l, TEnumType p_r)
noexcept
48 using U = std::underlying_type_t<TEnumType>;
49 return static_cast<TEnumType
>(
static_cast<U
>(p_l) &
static_cast<U
>(p_r));
57template <spk::bitmask_enum TEnumType>
58constexpr TEnumType operator^(TEnumType p_l, TEnumType p_r)
noexcept
60 using U = std::underlying_type_t<TEnumType>;
61 return static_cast<TEnumType
>(
static_cast<U
>(p_l) ^
static_cast<U
>(p_r));
68template <spk::bitmask_enum TEnumType>
69constexpr TEnumType operator~(TEnumType p_v)
noexcept
71 using U = std::underlying_type_t<TEnumType>;
72 return static_cast<TEnumType
>(~static_cast<U>(p_v));
75template <spk::bitmask_enum TEnumType>
76constexpr TEnumType &operator|=(TEnumType &p_l, TEnumType p_r)
noexcept
78 return p_l = (p_l | p_r);
81template <spk::bitmask_enum TEnumType>
82constexpr TEnumType &operator&=(TEnumType &p_l, TEnumType p_r)
noexcept
84 return p_l = (p_l & p_r);
87template <spk::bitmask_enum TEnumType>
88constexpr TEnumType &operator^=(TEnumType &p_l, TEnumType p_r)
noexcept
90 return p_l = (p_l ^ p_r);
109 template <bitmask_enum TFlagType,
unsigned_storage StorageT = std::u
int32_t>
112 static_assert(
sizeof(std::underlying_type_t<TFlagType>) <=
sizeof(StorageT),
"Storage type too small for enum underlying type");
149 constexpr Flags(std::initializer_list<TFlagType> p_values) :
152 for (
auto v : p_values)
171 bits &= ~static_cast<MaskType>(p_v);
210 constexpr bool has(TFlagType p_v)
const
227 constexpr bool any()
const
243 explicit constexpr operator bool()
const
264 template <bitmask_enum T,
unsigned_storage S>
265 constexpr Flags<T, S> operator|(Flags<T, S> p_l, Flags<T, S> p_r)
noexcept
267 p_l.bits |= p_r.bits;
276 template <bitmask_enum T,
unsigned_storage S>
277 constexpr Flags<T, S> operator&(Flags<T, S> p_l, Flags<T, S> p_r)
noexcept
279 p_l.bits &= p_r.bits;
288 template <bitmask_enum T,
unsigned_storage S>
289 constexpr Flags<T, S> operator^(Flags<T, S> p_l, Flags<T, S> p_r)
noexcept
291 p_l.bits ^= p_r.bits;
299 template <bitmask_enum T,
unsigned_storage S>
300 constexpr Flags<T, S> operator~(Flags<T, S> p_v)
noexcept
302 p_v.bits =
static_cast<typename Flags<T, S>::MaskType
>(~p_v.bits);
312 template <bitmask_enum T,
unsigned_storage S>
313 constexpr Flags<T, S> operator|(Flags<T, S> p_l, T p_r)
noexcept
324 template <bitmask_enum T,
unsigned_storage S>
325 constexpr Flags<T, S> operator|(T p_l, Flags<T, S> p_r)
noexcept
336 template <bitmask_enum T,
unsigned_storage S>
337 constexpr Flags<T, S> operator&(Flags<T, S> p_l, T p_r)
noexcept
339 p_l.bits &=
static_cast<typename Flags<T, S>::MaskType
>(p_r);
348 template <bitmask_enum T,
unsigned_storage S>
349 constexpr Flags<T, S> operator&(T p_l, Flags<T, S> p_r)
noexcept
360 template <bitmask_enum T,
unsigned_storage S>
361 constexpr bool operator==(Flags<T, S> p_l, Flags<T, S> p_r)
noexcept
363 return p_l.bits == p_r.bits;
371 template <bitmask_enum T,
unsigned_storage S>
372 constexpr bool operator!=(Flags<T, S> p_l, Flags<T, S> p_r)
noexcept
374 return !(p_l == p_r);
376 template <bitmask_enum T,
unsigned_storage S>
377 constexpr bool operator==(Flags<T, S> p_l, T p_r)
noexcept
379 return p_l.bits ==
static_cast<typename Flags<T, S>::MaskType
>(p_r);
381 template <bitmask_enum T,
unsigned_storage S>
382 constexpr bool operator==(T p_l, Flags<T, S> p_r)
noexcept
386 template <bitmask_enum T,
unsigned_storage S>
387 constexpr bool operator!=(Flags<T, S> p_l, T p_r)
noexcept
389 return !(p_l == p_r);
391 template <bitmask_enum T,
unsigned_storage S>
392 constexpr bool operator!=(T p_l, Flags<T, S> p_r)
noexcept
394 return !(p_r == p_l);
397 template <bitmask_enum T>
398 using Flags8 = Flags<T, std::uint8_t>;
399 template <bitmask_enum T>
400 using Flags16 = Flags<T, std::uint16_t>;
401 template <bitmask_enum T>
402 using Flags32 = Flags<T, std::uint32_t>;
405template <spk::bitmask_enum E, spk::
unsigned_storage S>
406std::ostream &operator<<(std::ostream &p_os, spk::Flags<E, S> p_f)
408 return p_os <<
"0x" << std::hex << static_cast<typename spk::Flags<E, S>::MaskType>(p_f.
bits);
410template <spk::bitmask_enum E, spk::
unsigned_storage S>
411std::wostream &operator<<(std::wostream &p_os, spk::Flags<E, S> p_f)
413 return p_os << L
"0x" << std::hex << static_cast<typename spk::Flags<E, S>::MaskType>(p_f.
bits);
Concept ensuring an enum can be used as a bitmask (size up to 32 bits).
Definition spk_flags.hpp:14
Concept restricting storage to unsigned 8/16/32-bit.
Definition spk_flags.hpp:22
constexpr MaskType raw() const
Returns the underlying bits.
Definition spk_flags.hpp:252
constexpr Flags(std::initializer_list< TFlagType > p_values)
Initializes with multiple flags.
Definition spk_flags.hpp:149
constexpr Flags & operator^=(TFlagType p_v)
In-place XOR with a flag.
Definition spk_flags.hpp:199
constexpr Flags()=default
Builds an empty flag set.
constexpr Flags(MaskType p_raw)
Initializes with raw bits.
Definition spk_flags.hpp:140
constexpr Flags & operator&=(TFlagType p_v)
In-place AND with a mask.
Definition spk_flags.hpp:189
constexpr Flags & operator|=(TFlagType p_v)
In-place OR with a flag.
Definition spk_flags.hpp:179
constexpr bool testAny(TFlagType p_v) const
Tests whether any bit in a mask is set.
Definition spk_flags.hpp:219
constexpr void clear()
Clears all flags.
Definition spk_flags.hpp:161
constexpr Flags(TFlagType p_v)
Initializes with a single flag.
Definition spk_flags.hpp:131
constexpr void reset(TFlagType p_v)
Removes specific flags.
Definition spk_flags.hpp:169
StorageT MaskType
Unsigned storage type used to hold flag bits.
Definition spk_flags.hpp:115
MaskType bits
Definition spk_flags.hpp:120
constexpr bool any() const
Checks if any flag is set.
Definition spk_flags.hpp:227
constexpr bool has(TFlagType p_v) const
Tests whether all bits in a mask are set.
Definition spk_flags.hpp:210
constexpr bool none() const
Checks if no flags are set.
Definition spk_flags.hpp:235