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() {}
326 constexpr EnumBitSet(std::initializer_list<const Tenum> values) : BaseClass()
328 for (
const Tenum &value : values) {
336 constexpr auto operator <=>(
const EnumBitSet &)
const noexcept =
default;
338 static constexpr size_t DecayValueType(
const BaseClass::ValueType &value) {
return to_underlying(value); }
347template <
typename Container,
typename Index>
350 Container::reference at(
size_t pos) =
delete;
351 Container::reference at(
const Index &pos) {
return this->Container::at(
to_underlying(pos)); }
353 Container::const_reference at(
size_t pos)
const =
delete;
354 Container::const_reference at(
const Index &pos)
const {
return this->Container::at(
to_underlying(pos)); }
356 Container::reference operator[](
size_t pos) =
delete;
357 Container::reference operator[](
const Index &pos) {
return this->Container::operator[](
to_underlying(pos)); }
359 Container::const_reference operator[](
size_t pos)
const =
delete;
360 Container::const_reference operator[](
const Index &pos)
const {
return this->Container::operator[](
to_underlying(pos)); }
369template <
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(Tenum value)
Construct an EnumBitSet from an enum value.
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.