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)); \
172 template <typename OtherEnumType, typename = typename std::enable_if<std::is_enum_v<OtherEnumType>, OtherEnumType>::type> \
173 constexpr OtherEnumType operator -(OtherEnumType m1, EnumType m2) { \
174 return static_cast<OtherEnumType>(to_underlying(m1) - to_underlying(m2)); \
183template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
194template <
typename T,
class =
typename std::enable_if_t<std::is_enum_v<T>>>
208template <
typename Tenum>
250 return static_cast<Tenum
>(
value);
287template <
typename Tstorage,
typename Tenum, Tenum Tend_value>
289 static constexpr Tstorage value = std::numeric_limits<Tstorage>::max() >> (std::numeric_limits<Tstorage>::digits -
to_underlying(Tend_value));
300template <
typename Tenum,
typename Tstorage, Tenum Tend_value = Tenum{std::numeric_limits<Tstorage>::digits}>
301class EnumBitSet :
public BaseBitSet<EnumBitSet<Tenum, Tstorage, Tend_value>, Tenum, Tstorage, EnumBitSetMask<Tstorage, Tenum, Tend_value>::value> {
304 using EnumType = BaseClass::ValueType;
306 constexpr EnumBitSet() : BaseClass() {}
307 constexpr EnumBitSet(Tenum value) : BaseClass() { this->
Set(value); }
308 explicit constexpr EnumBitSet(Tstorage
data) : BaseClass(
data) {}
314 constexpr EnumBitSet(std::initializer_list<const Tenum> values) : BaseClass()
316 for (
const Tenum &value : values) {
321 constexpr auto operator <=>(
const EnumBitSet &)
const noexcept =
default;
323 static constexpr size_t DecayValueType(
const BaseClass::ValueType &value) {
return to_underlying(value); }
332template <
typename Container,
typename Index>
335 Container::reference at(
size_t pos) =
delete;
336 Container::reference at(
const Index &pos) {
return this->Container::at(
to_underlying(pos)); }
338 Container::const_reference at(
size_t pos)
const =
delete;
339 Container::const_reference at(
const Index &pos)
const {
return this->Container::at(
to_underlying(pos)); }
341 Container::reference operator[](
size_t pos) =
delete;
342 Container::reference operator[](
const Index &pos) {
return this->Container::operator[](
to_underlying(pos)); }
344 Container::const_reference operator[](
size_t pos)
const =
delete;
345 Container::const_reference operator[](
const Index &pos)
const {
return this->Container::operator[](
to_underlying(pos)); }
354template <
typename T,
typename Index, Index N>
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.
value_type & difference_type
C++ specification trait 'difference_type' of this Iterator.
constexpr Iterator & operator++()
Increment to the next value.
void reference
C++ specification trait 'reference' of this Iterator.
void pointer
C++ specification trait 'pointer' of this Iterator.
constexpr auto operator<=>(const Iterator &) const =default
Compare with another instance of this iterator.
Tenum value_type
C++ specification trait 'value_type' of this Iterator.
std::forward_iterator_tag iterator_category
C++ specification trait 'iterator_category' of this Iterator.
Tenum value
Current value.
Iterator(Tenum v)
Construct this iterator.
constexpr Tenum operator*() const
Deference operator.
Tenum first
The first (inclusive) value of the range.
constexpr EnumRange(Tenum last)
Construct an EnumRange from default to last.
constexpr Iterator begin() const
Get the begin iterator for this range.
Tenum last
The last (exclusive) value of the range.
constexpr EnumRange(Tenum first, Tenum last)
Construct an EnumRange from first to last.
constexpr Iterator end() const
Get the end iterator for this range.
#define T
Climate temperate.
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.
EnumClassIndexContainer< std::array< T, to_underlying(N)>, Index > EnumIndexArray
A typedef for EnumClassIndexContainer using std::array as the backing container type.
constexpr enum_type operator-(enum_type e, int offset)
Subtract integer.
constexpr enum_type operator+(enum_type e, int offset)
Add integer.
#define debug_inline
When making a (pure) debug build, the compiler will by default disable inlining of functions.
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.