SlHelpers
Enum.h
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #pragma once
4 
5 #include <iterator>
6 #include <type_traits>
7 
8 namespace SlHelpers {
9 
11 template <typename Enum>
12 requires std::is_enum_v<Enum>
13 class EnumRange {
14 public:
16  using Underlying = std::underlying_type_t<Enum>;
17 
19  EnumRange() requires requires { Enum::First; Enum::Last; }
20  : EnumRange(Enum::First, Enum::Last) {}
21 
23  EnumRange(Enum first, Enum last)
24  : m_first(static_cast<Underlying>(first)),
25  m_last(static_cast<Underlying>(last)) {}
26 
28  struct iterator {
30  using iterator_category = std::forward_iterator_tag;
32  using difference_type = std::ptrdiff_t;
34  using value_type = Enum;
36  using reference = Enum;
38  using pointer = Enum *;
39 
42 
44  Enum operator*() const { return static_cast<Enum>(v); }
45 
48  ++v;
49  return *this;
50  }
51 
54  iterator temp = *this;
55  ++(*this);
56  return temp;
57  }
58 
60  bool operator==(const iterator &other) const { return v == other.v; }
62  bool operator!=(const iterator &other) const { return v != other.v; }
63  };
64 
66  using value_type = Enum;
69 
71  iterator begin() const { return { m_first }; }
73  iterator end() const { return { m_last + 1 }; }
74 private:
75  Underlying m_first;
76  Underlying m_last;
77 };
78 
79 template<typename E>
80 struct hasBitmaskOperators : std::false_type {};
81 
82 #define ENABLE_BITMASK_OPERATORS(E) \
83  template<> struct SlHelpers::hasBitmaskOperators<E> : std::true_type {}
84 
85 template<typename E>
86 concept BitmaskEnum = std::is_enum_v<E> && hasBitmaskOperators<E>::value;
87 
88 } // namespace
89 
90 template<SlHelpers::BitmaskEnum E>
91 constexpr E operator~(E lhs)
92 {
93  using underlying = std::underlying_type_t<E>;
94  return static_cast<E>(~static_cast<underlying>(lhs));
95 }
96 
97 template<SlHelpers::BitmaskEnum E>
98 constexpr E operator|(E lhs, E rhs)
99 {
100  using underlying = std::underlying_type_t<E>;
101  return static_cast<E>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
102 }
103 
104 template<SlHelpers::BitmaskEnum E>
105 constexpr E operator&(E lhs, E rhs)
106 {
107  using underlying = std::underlying_type_t<E>;
108  return static_cast<E>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
109 }
110 
111 template<SlHelpers::BitmaskEnum E>
112 constexpr E &operator|=(E &lhs, E rhs)
113 {
114  return lhs = lhs | rhs;
115 }
116 
117 template<SlHelpers::BitmaskEnum E>
118 constexpr E &operator&=(E &lhs, E rhs)
119 {
120  return lhs = lhs & rhs;
121 }
122 
123 template<SlHelpers::BitmaskEnum E>
124 constexpr bool hasFlag(E flags, E flag)
125 {
126  return (flags & flag) != E::NONE;
127 }
Enum value_type
Type of the enum values in the range.
Definition: Enum.h:66
std::underlying_type_t< Enum > Underlying
Type of the underlying enum values.
Definition: Enum.h:16
Definition: Enum.h:80
Enum * pointer
Pointer type for the enum range.
Definition: Enum.h:38
bool operator!=(const iterator &other) const
Inequality operator to compare two iterators.
Definition: Enum.h:62
std::ptrdiff_t difference_type
Difference type for the enum range.
Definition: Enum.h:32
Enum value_type
Value type for the enum range.
Definition: Enum.h:34
std::forward_iterator_tag iterator_category
Iterator category for the enum range.
Definition: Enum.h:30
Enum operator*() const
Dereference operator to get the current enum value.
Definition: Enum.h:44
iterator begin() const
Returns an iterator to the beginning of the enum range.
Definition: Enum.h:71
iterator operator++(int)
Post-increment operator to move to the next enum value.
Definition: Enum.h:53
Helper class to iterate over enum values from Enum::First to Enum::Last.
Definition: Enum.h:13
Underlying v
Current value of the iterator.
Definition: Enum.h:41
iterator end() const
Returns an iterator to the end of the enum range.
Definition: Enum.h:73
Iterator class to iterate over enum values.
Definition: Enum.h:28
bool operator==(const iterator &other) const
Equality operator to compare two iterators.
Definition: Enum.h:60
Enum reference
Reference type for the enum range.
Definition: Enum.h:36
EnumRange() requires requires
Constructs an EnumRange from Enum::First to Enum::Last.
Definition: Enum.h:19
iterator & operator++()
Pre-increment operator to move to the next enum value.
Definition: Enum.h:47
Definition: Color.h:8