20template <
typename enum_type>
21constexpr std::underlying_type_t<enum_type>
to_underlying(enum_type e) {
return static_cast<std::underlying_type_t<enum_type>
>(e); }
24template <
class T>
constexpr bool is_scoped_enum_v = std::conjunction_v<std::is_enum<T>, std::negation<std::is_convertible<T, int>>>;
27template <
typename enum_type>
29 static constexpr bool value =
false;
32template <
typename enum_type>
33constexpr bool is_enum_incrementable_v = is_enum_incrementable<enum_type>::value;
40template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
52template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
65template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
77template <
typename enum_type, std::enable_if_t<is_enum_incrementable_v<enum_type>,
bool> = true>
86#define DECLARE_INCREMENT_DECREMENT_OPERATORS(enum_type) \
87 template <> struct is_enum_incrementable<enum_type> { \
88 static const bool value = true; \
92template <
typename enum_type>
94 static constexpr bool value =
false;
97template <
typename enum_type>
98constexpr bool is_enum_sequential_v = is_enum_sequential<enum_type>::value;
106template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
107inline constexpr enum_type
operator+(enum_type e,
int offset)
112template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
113inline constexpr enum_type &operator+=(enum_type &e,
int offset)
125template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
126inline constexpr enum_type
operator-(enum_type e,
int offset)
131template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
132inline constexpr enum_type &operator-=(enum_type &e,
int offset)
144template <
typename enum_type, std::enable_if_t<is_enum_sequential_v<enum_type>,
bool> = true>
145inline constexpr auto operator-(enum_type a, enum_type b)
151#define DECLARE_ENUM_AS_SEQUENTIAL(enum_type) \
152 template <> struct is_enum_sequential<enum_type> { \
153 static const bool value = true; \
157#define DECLARE_ENUM_AS_BIT_SET(enum_type) \
158 inline constexpr enum_type operator | (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) | to_underlying(m2)); } \
159 inline constexpr enum_type operator & (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) & to_underlying(m2)); } \
160 inline constexpr enum_type operator ^ (enum_type m1, enum_type m2) { return static_cast<enum_type>(to_underlying(m1) ^ to_underlying(m2)); } \
161 inline constexpr enum_type& operator |= (enum_type& m1, enum_type m2) { m1 = m1 | m2; return m1; } \
162 inline constexpr enum_type& operator &= (enum_type& m1, enum_type m2) { m1 = m1 & m2; return m1; } \
163 inline constexpr enum_type& operator ^= (enum_type& m1, enum_type m2) { m1 = m1 ^ m2; return m1; } \
164 inline constexpr enum_type operator ~(enum_type m) { return static_cast<enum_type>(~to_underlying(m)); }
167#define DECLARE_ENUM_AS_ADDABLE(EnumType) \
168 template <typename OtherEnumType, typename = typename std::enable_if<std::is_enum_v<OtherEnumType>, OtherEnumType>::type> \
169 constexpr OtherEnumType operator + (OtherEnumType m1, EnumType m2) { \
170 return static_cast<OtherEnumType>(to_underlying(m1) + to_underlying(m2)); \
179template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
180[[debug_inline]]
inline constexpr bool HasFlag(
const T x,
const T y)
190template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
191[[debug_inline]]
inline constexpr void ToggleFlag(T &x,
const T y)
201template <
typename Tstorage,
typename Tenum, Tenum Tend_value>
203 static constexpr Tstorage value = std::numeric_limits<Tstorage>::max() >> (std::numeric_limits<Tstorage>::digits -
to_underlying(Tend_value));
214template <
typename Tenum,
typename Tstorage, Tenum Tend_value = Tenum{std::numeric_limits<Tstorage>::digits}>
215class EnumBitSet :
public BaseBitSet<EnumBitSet<Tenum, Tstorage, Tend_value>, Tenum, Tstorage, EnumBitSetMask<Tstorage, Tenum, Tend_value>::value> {
218 using EnumType = BaseClass::ValueType;
220 constexpr EnumBitSet() : BaseClass() {}
221 constexpr EnumBitSet(Tenum value) : BaseClass() { this->
Set(value); }
222 explicit constexpr EnumBitSet(Tstorage
data) : BaseClass(
data) {}
228 constexpr EnumBitSet(std::initializer_list<const Tenum> values) : BaseClass()
230 for (
const Tenum &value : values) {
235 constexpr auto operator <=>(
const EnumBitSet &)
const noexcept =
default;
237 static constexpr size_t DecayValueType(
const BaseClass::ValueType &value) {
return to_underlying(value); }
246template <
typename Container,
typename Index>
249 Container::reference at(
size_t pos) {
return this->Container::at(pos); }
250 Container::reference at(
const Index &pos) {
return this->Container::at(
to_underlying(pos)); }
252 Container::const_reference at(
size_t pos)
const {
return this->Container::at(pos); }
253 Container::const_reference at(
const Index &pos)
const {
return this->Container::at(
to_underlying(pos)); }
255 Container::reference operator[](
size_t pos) {
return this->Container::operator[](pos); }
256 Container::reference operator[](
const Index &pos) {
return this->Container::operator[](
to_underlying(pos)); }
258 Container::const_reference operator[](
size_t pos)
const {
return this->Container::operator[](pos); }
259 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 ...
Tstorage data
Bitmask of values.
constexpr BaseBitSet()
Create an empty bitset.
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)
Subtract 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.