CommonLibSSE (powerof3)
Loading...
Searching...
No Matches
EnumSet.h
Go to the documentation of this file.
1#pragma once
2
3namespace REX
4{
5 template <
6 class E,
7 class U = std::underlying_type_t<E>>
8 class EnumSet
9 {
10 public:
11 using enum_type = E;
12 using underlying_type = U;
13
14 static_assert(std::is_enum_v<E>, "EnumSet<E, ...> must be an enum");
15 static_assert(std::is_integral_v<U>, "EnumSet<..., U> must be an integral");
16
17 constexpr EnumSet() noexcept = default;
18 constexpr EnumSet(const EnumSet&) noexcept = default;
19 constexpr EnumSet(EnumSet&&) noexcept = default;
20
21 template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
22 constexpr EnumSet(EnumSet<E, U2> a_rhs) noexcept :
23 _impl(static_cast<U>(a_rhs.get()))
24 {}
25
26 template <class... Args>
27 constexpr EnumSet(Args... a_values) noexcept
28 requires(std::same_as<Args, E> && ...)
29 :
30 _impl((static_cast<U>(a_values) | ...))
31 {}
32
33 ~EnumSet() noexcept = default;
34
35 constexpr EnumSet& operator=(const EnumSet&) noexcept = default;
36 constexpr EnumSet& operator=(EnumSet&&) noexcept = default;
37
38 template <class U2>
39 constexpr EnumSet& operator=(EnumSet<E, U2> a_rhs) noexcept
40 {
41 _impl = static_cast<U>(a_rhs.get());
42 }
43
44 constexpr EnumSet& operator=(E a_value) noexcept
45 {
46 _impl = static_cast<U>(a_value);
47 return *this;
48 }
49
50 public:
51 [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
52
53 [[nodiscard]] constexpr E operator*() const noexcept { return get(); }
54 [[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
55 [[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
56
57 public:
58 template <class... Args>
59 constexpr EnumSet& set(Args... a_args) noexcept
60 requires(std::same_as<Args, E> && ...)
61 {
62 _impl |= (static_cast<U>(a_args) | ...);
63 return *this;
64 }
65
66 template <class... Args>
67 constexpr EnumSet& set(bool a_set, Args... a_args) noexcept
68 requires(std::same_as<Args, E> && ...)
69 {
70 if (a_set)
71 _impl |= (static_cast<U>(a_args) | ...);
72 else
73 _impl &= ~(static_cast<U>(a_args) | ...);
74
75 return *this;
76 }
77
78 template <class... Args>
79 constexpr EnumSet& reset(Args... a_args) noexcept
80 requires(std::same_as<Args, E> && ...)
81 {
82 _impl &= ~(static_cast<U>(a_args) | ...);
83 return *this;
84 }
85
86 constexpr EnumSet& reset() noexcept
87 {
88 _impl = 0;
89 return *this;
90 }
91
92 template <class... Args>
93 [[nodiscard]] constexpr bool any(Args... a_args) const noexcept
94 requires(std::same_as<Args, E> && ...)
95 {
96 return (_impl & (static_cast<U>(a_args) | ...)) != static_cast<U>(0);
97 }
98
99 template <class... Args>
100 [[nodiscard]] constexpr bool all(Args... a_args) const noexcept
101 requires(std::same_as<Args, E> && ...)
102 {
103 return (_impl & (static_cast<U>(a_args) | ...)) == (static_cast<U>(a_args) | ...);
104 }
105
106 template <class... Args>
107 [[nodiscard]] constexpr bool none(Args... a_args) const noexcept
108 requires(std::same_as<Args, E> && ...)
109 {
110 return (_impl & (static_cast<U>(a_args) | ...)) == static_cast<U>(0);
111 }
112
113 public:
114 friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
115 friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
116 friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
117
118 friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); }
119 friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast<U>(a_rhs); }
120 friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) <=> a_rhs.underlying(); }
121
122 friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & a_rhs.underlying()); }
123 friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & static_cast<U>(a_rhs)); }
124 friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) & a_rhs.underlying()); }
125
126 friend constexpr EnumSet& operator&=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
127 friend constexpr EnumSet& operator&=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
128
129 friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | a_rhs.underlying()); }
130 friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | static_cast<U>(a_rhs)); }
131 friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) | a_rhs.underlying()); }
132
133 friend constexpr EnumSet& operator|=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
134 friend constexpr EnumSet& operator|=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
135
136 friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ a_rhs.underlying()); }
137 friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ static_cast<U>(a_rhs)); }
138 friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) ^ a_rhs.underlying()); }
139
140 friend constexpr EnumSet& operator^=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
141 friend constexpr EnumSet& operator^=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
142
143 friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + a_rhs.underlying()); }
144 friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + static_cast<U>(a_rhs)); }
145 friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) + a_rhs.underlying()); }
146
147 friend constexpr EnumSet& operator+=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
148 friend constexpr EnumSet& operator+=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
149
150 friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - a_rhs.underlying()); }
151 friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - static_cast<U>(a_rhs)); }
152 friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) - a_rhs.underlying()); }
153
154 friend constexpr EnumSet& operator-=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
155 friend constexpr EnumSet& operator-=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
156
157 friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << a_rhs.underlying()); }
158 friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << static_cast<U>(a_rhs)); }
159 friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) << a_rhs.underlying()); }
160
161 friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
162 friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
163
164 friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> a_rhs.underlying()); }
165 friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> static_cast<U>(a_rhs)); }
166 friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) >> a_rhs.underlying()); }
167
168 friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
169 friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
170
171 friend constexpr EnumSet& operator~(EnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); }
172
173 private:
174 U _impl{ 0 };
175 };
176
177 template <class... Args>
178 EnumSet(Args...) -> EnumSet<
179 std::common_type_t<Args...>,
180 std::underlying_type_t<
181 std::common_type_t<Args...>>>;
182}
Definition EnumSet.h:9
friend constexpr EnumSet & operator&=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:126
constexpr EnumSet() noexcept=default
constexpr U underlying() const noexcept
Definition EnumSet.h:55
friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:123
friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:129
constexpr EnumSet & reset(Args... a_args) noexcept
Definition EnumSet.h:79
friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:131
friend constexpr EnumSet & operator&=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:127
constexpr E get() const noexcept
Definition EnumSet.h:54
constexpr EnumSet & reset() noexcept
Definition EnumSet.h:86
friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:165
friend constexpr EnumSet & operator-=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:154
friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:120
friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:166
friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:159
constexpr bool all(Args... a_args) const noexcept
Definition EnumSet.h:100
friend constexpr EnumSet & operator>>=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:169
friend constexpr EnumSet & operator+=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:147
friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:136
friend constexpr EnumSet & operator-=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:155
friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:157
friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:145
friend constexpr EnumSet & operator|=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:134
friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:143
friend constexpr EnumSet & operator~(EnumSet &a_lhs) noexcept
Definition EnumSet.h:171
friend constexpr EnumSet & operator<<=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:162
constexpr bool none(Args... a_args) const noexcept
Definition EnumSet.h:107
constexpr EnumSet(Args... a_values) noexcept
Definition EnumSet.h:27
friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:151
friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:138
friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:122
friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:137
friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:115
U underlying_type
Definition EnumSet.h:12
~EnumSet() noexcept=default
friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:114
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:118
friend constexpr EnumSet & operator>>=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:168
friend constexpr EnumSet & operator+=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:148
friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:124
friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:164
friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:150
friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:144
constexpr EnumSet & operator=(E a_value) noexcept
Definition EnumSet.h:44
friend constexpr EnumSet & operator^=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:141
constexpr EnumSet & set(bool a_set, Args... a_args) noexcept
Definition EnumSet.h:67
friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:158
constexpr E operator*() const noexcept
Definition EnumSet.h:53
constexpr EnumSet & set(Args... a_args) noexcept
Definition EnumSet.h:59
friend constexpr EnumSet & operator|=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:133
friend constexpr EnumSet & operator^=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:140
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:119
friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:152
friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:130
constexpr bool any(Args... a_args) const noexcept
Definition EnumSet.h:93
friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:116
friend constexpr EnumSet & operator<<=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:161
E enum_type
Definition EnumSet.h:11
Definition BSDirectInputManager.h:8