16template <
typename enum_type>
17constexpr std::underlying_type_t<enum_type>
to_underlying(enum_type e) {
return static_cast<std::underlying_type_t<enum_type>
>(e); }
20template <
typename enum_type>
22 static constexpr bool value =
false;
25template <
typename enum_type>
29template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
37template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
46template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
54template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
63#define DECLARE_INCREMENT_DECREMENT_OPERATORS(enum_type) \
64 template <> struct is_enum_incrementable<enum_type> { \
65 static const bool value = true; \
70#define DECLARE_ENUM_AS_BIT_SET(enum_type) \
71 inline constexpr enum_type operator | (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) | to_underlying(m2)); } \
72 inline constexpr enum_type operator & (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) & to_underlying(m2)); } \
73 inline constexpr enum_type operator ^ (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) ^ to_underlying(m2)); } \
74 inline constexpr enum_type& operator |= (enum_type& m1, enum_type m2) { m1 = m1 | m2; return m1; } \
75 inline constexpr enum_type& operator &= (enum_type& m1, enum_type m2) { m1 = m1 & m2; return m1; } \
76 inline constexpr enum_type& operator ^= (enum_type& m1, enum_type m2) { m1 = m1 ^ m2; return m1; } \
77 inline constexpr enum_type operator ~(enum_type m) { return static_cast<enum_type>(~to_underlying(m)); }
80#define DECLARE_ENUM_AS_ADDABLE(EnumType) \
81 template <typename OtherEnumType, typename = typename std::enable_if<std::is_enum_v<OtherEnumType>, OtherEnumType>::type> \
82 constexpr OtherEnumType operator + (OtherEnumType m1, EnumType m2) { \
83 return static_cast<OtherEnumType>(to_underlying(m1) + to_underlying(m2)); \
92template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
93debug_inline
constexpr bool HasFlag(
const T x,
const T y)
103template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
114template <
typename Tstorage,
typename Tenum, Tenum Tend_value>
116 static constexpr Tstorage value = std::numeric_limits<Tstorage>::max() >> (std::numeric_limits<Tstorage>::digits -
to_underlying(Tend_value));
127template <
typename Tenum,
typename Tstorage, Tenum Tend_value = Tenum{std::numeric_limits<Tstorage>::digits}>
128class EnumBitSet :
public BaseBitSet<EnumBitSet<Tenum, Tstorage, Tend_value>, Tenum, Tstorage, EnumBitSetMask<Tstorage, Tenum, Tend_value>::value> {
143 for (
const Tenum &value : values) {
148 constexpr auto operator <=>(
const EnumBitSet &)
const noexcept =
default;
Base for bitset types that accept strong types, i.e.
Base for bit set wrapper.
Tstorage data
Bitmask of values.
Tvalue_type ValueType
Value type of this BaseBitSet.
constexpr Timpl & Set()
Set all bits.
constexpr EnumBitSet(std::initializer_list< const Tenum > values)
Construct an EnumBitSet from a list of enum values.
constexpr enum_type & operator--(enum_type &e)
Prefix decrement.
debug_inline constexpr void ToggleFlag(T &x, const T y)
Toggle a value in a bitset enum.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
constexpr enum_type & operator++(enum_type &e)
Prefix increment.
debug_inline constexpr bool HasFlag(const T x, const T y)
Checks if a value in a bitset enum is set.
Helper template structure to get the mask for an EnumBitSet from the end enum value.
Trait to enable prefix/postfix incrementing operators.