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 <
class T>
constexpr bool is_scoped_enum_v = std::conjunction_v<std::is_enum<T>, std::negation<std::is_convertible<T, int>>>;
23template <
typename enum_type>
25 static constexpr bool value =
false;
28template <
typename enum_type>
32template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
40template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
49template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
57template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
66#define DECLARE_INCREMENT_DECREMENT_OPERATORS(enum_type) \
67 template <> struct is_enum_incrementable<enum_type> { \
68 static const bool value = true; \
72template <
typename enum_type>
74 static constexpr bool value =
false;
77template <
typename enum_type>
81template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
82inline constexpr enum_type
operator+(enum_type e,
int offset)
87template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
88inline constexpr enum_type &operator+=(enum_type &e,
int offset)
95template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
96inline constexpr enum_type
operator-(enum_type e,
int offset)
101template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
102inline constexpr enum_type &operator-=(enum_type &e,
int offset)
109template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
110inline constexpr auto operator-(enum_type a, enum_type b)
116#define DECLARE_ENUM_AS_SEQUENTIAL(enum_type) \
117 template <> struct is_enum_sequential<enum_type> { \
118 static const bool value = true; \
122#define DECLARE_ENUM_AS_BIT_SET(enum_type) \
123 inline constexpr enum_type operator | (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) | to_underlying(m2)); } \
124 inline constexpr enum_type operator & (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) & to_underlying(m2)); } \
125 inline constexpr enum_type operator ^ (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) ^ to_underlying(m2)); } \
126 inline constexpr enum_type& operator |= (enum_type& m1, enum_type m2) { m1 = m1 | m2; return m1; } \
127 inline constexpr enum_type& operator &= (enum_type& m1, enum_type m2) { m1 = m1 & m2; return m1; } \
128 inline constexpr enum_type& operator ^= (enum_type& m1, enum_type m2) { m1 = m1 ^ m2; return m1; } \
129 inline constexpr enum_type operator ~(enum_type m) { return static_cast<enum_type>(~to_underlying(m)); }
132#define DECLARE_ENUM_AS_ADDABLE(EnumType) \
133 template <typename OtherEnumType, typename = typename std::enable_if<std::is_enum_v<OtherEnumType>, OtherEnumType>::type> \
134 constexpr OtherEnumType operator + (OtherEnumType m1, EnumType m2) { \
135 return static_cast<OtherEnumType>(to_underlying(m1) + to_underlying(m2)); \
144template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
145[[debug_inline]]
inline constexpr bool HasFlag(
const T x,
const T y)
155template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
156[[debug_inline]]
inline constexpr void ToggleFlag(T &x,
const T y)
166template <
typename Tstorage,
typename Tenum, Tenum Tend_value>
168 static constexpr Tstorage value = std::numeric_limits<Tstorage>::max() >> (std::numeric_limits<Tstorage>::digits -
to_underlying(Tend_value));
179template <
typename Tenum,
typename Tstorage, Tenum Tend_value = Tenum{std::numeric_limits<Tstorage>::digits}>
180class EnumBitSet :
public BaseBitSet<EnumBitSet<Tenum, Tstorage, Tend_value>, Tenum, Tstorage, EnumBitSetMask<Tstorage, Tenum, Tend_value>::value> {
195 for (
const Tenum &value : values) {
200 constexpr auto operator <=>(
const EnumBitSet &)
const noexcept =
default;
211template <
typename Container,
typename Index>
214 Container::reference at(
size_t pos) {
return this->Container::at(pos); }
215 Container::reference at(
const Index &pos) {
return this->Container::at(
to_underlying(pos)); }
217 Container::const_reference at(
size_t pos)
const {
return this->Container::at(pos); }
218 Container::const_reference at(
const Index &pos)
const {
return this->Container::at(
to_underlying(pos)); }
220 Container::reference operator[](
size_t pos) {
return this->Container::operator[](pos); }
221 Container::reference operator[](
const Index &pos) {
return this->Container::operator[](
to_underlying(pos)); }
223 Container::const_reference operator[](
size_t pos)
const {
return this->Container::operator[](pos); }
224 Container::const_reference operator[](
const Index &pos)
const {
return this->Container::operator[](
to_underlying(pos)); }
Base for bitset types that accept strong types, ones that need some casting like StrongType and enum ...
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.
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific enum class.
constexpr enum_type & operator--(enum_type &e)
Prefix decrement.
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.
constexpr bool is_scoped_enum_v
Implementation of std::is_scoped_enum_v (from C++23)
constexpr bool HasFlag(const T x, const T y)
Checks if a value in a bitset enum is set.
constexpr enum_type operator-(enum_type e, int offset)
Sub integer.
constexpr enum_type operator+(enum_type e, int offset)
Add integer.
Helper template structure to get the mask for an EnumBitSet from the end enum value.
Trait to enable prefix/postfix incrementing operators.
Trait to enable prefix/postfix incrementing operators.