CommonLibVR
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 _impl((static_cast<U>(a_values) | ...))
30 {}
31
32 ~EnumSet() noexcept = default;
33
34 constexpr EnumSet& operator=(const EnumSet&) noexcept = default;
35 constexpr EnumSet& operator=(EnumSet&&) noexcept = default;
36
37 template <class U2>
38 constexpr EnumSet& operator=(EnumSet<E, U2> a_rhs) noexcept
39 {
40 _impl = static_cast<U>(a_rhs.get());
41 }
42
43 constexpr EnumSet& operator=(E a_value) noexcept
44 {
45 _impl = static_cast<U>(a_value);
46 return *this;
47 }
48
49 public:
50 [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<U>(0); }
51
52 [[nodiscard]] constexpr E operator*() const noexcept { return get(); }
53 [[nodiscard]] constexpr E get() const noexcept { return static_cast<E>(_impl); }
54 [[nodiscard]] constexpr U underlying() const noexcept { return _impl; }
55
56 public:
57 template <class... Args>
58 constexpr EnumSet& set(Args... a_args) noexcept
59 requires(std::same_as<Args, E>&&...)
60 {
61 _impl |= (static_cast<U>(a_args) | ...);
62 return *this;
63 }
64
65 template <class... Args>
66 constexpr EnumSet& set(bool a_set, Args... a_args) noexcept
67 requires(std::same_as<Args, E>&&...)
68 {
69 if (a_set)
70 _impl |= (static_cast<U>(a_args) | ...);
71 else
72 _impl &= ~(static_cast<U>(a_args) | ...);
73
74 return *this;
75 }
76
77 template <class... Args>
78 constexpr EnumSet& reset(Args... a_args) noexcept
79 requires(std::same_as<Args, E>&&...)
80 {
81 _impl &= ~(static_cast<U>(a_args) | ...);
82 return *this;
83 }
84
85 constexpr EnumSet& reset() noexcept
86 {
87 _impl = 0;
88 return *this;
89 }
90
91 template <class... Args>
92 [[nodiscard]] constexpr bool any(Args... a_args) const noexcept
93 requires(std::same_as<Args, E>&&...)
94 {
95 return (_impl & (static_cast<U>(a_args) | ...)) != static_cast<U>(0);
96 }
97
98 template <class... Args>
99 [[nodiscard]] constexpr bool all(Args... a_args) const noexcept
100 requires(std::same_as<Args, E>&&...)
101 {
102 return (_impl & (static_cast<U>(a_args) | ...)) == (static_cast<U>(a_args) | ...);
103 }
104
105 template <class... Args>
106 [[nodiscard]] constexpr bool none(Args... a_args) const noexcept
107 requires(std::same_as<Args, E>&&...)
108 {
109 return (_impl & (static_cast<U>(a_args) | ...)) == static_cast<U>(0);
110 }
111
112 public:
113 friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); }
114 friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast<U>(a_rhs); }
115 friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) == a_rhs.underlying(); }
116
117 friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return a_lhs.underlying() <=> a_rhs.underlying(); }
118 friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept { return a_lhs.underlying() <=> static_cast<U>(a_rhs); }
119 friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<U>(a_lhs) <=> a_rhs.underlying(); }
120
121 friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & a_rhs.underlying()); }
122 friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() & static_cast<U>(a_rhs)); }
123 friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) & a_rhs.underlying()); }
124
125 friend constexpr EnumSet& operator&=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
126 friend constexpr EnumSet& operator&=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs & a_rhs; }
127
128 friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | a_rhs.underlying()); }
129 friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() | static_cast<U>(a_rhs)); }
130 friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) | a_rhs.underlying()); }
131
132 friend constexpr EnumSet& operator|=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
133 friend constexpr EnumSet& operator|=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs | a_rhs; }
134
135 friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ a_rhs.underlying()); }
136 friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() ^ static_cast<U>(a_rhs)); }
137 friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) ^ a_rhs.underlying()); }
138
139 friend constexpr EnumSet& operator^=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
140 friend constexpr EnumSet& operator^=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs ^ a_rhs; }
141
142 friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + a_rhs.underlying()); }
143 friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() + static_cast<U>(a_rhs)); }
144 friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) + a_rhs.underlying()); }
145
146 friend constexpr EnumSet& operator+=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
147 friend constexpr EnumSet& operator+=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs + a_rhs; }
148
149 friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - a_rhs.underlying()); }
150 friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() - static_cast<U>(a_rhs)); }
151 friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) - a_rhs.underlying()); }
152
153 friend constexpr EnumSet& operator-=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
154 friend constexpr EnumSet& operator-=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs - a_rhs; }
155
156 friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << a_rhs.underlying()); }
157 friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() << static_cast<U>(a_rhs)); }
158 friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) << a_rhs.underlying()); }
159
160 friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
161 friend constexpr EnumSet& operator<<=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs << a_rhs; }
162
163 friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> a_rhs.underlying()); }
164 friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept { return static_cast<E>(a_lhs.underlying() >> static_cast<U>(a_rhs)); }
165 friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept { return static_cast<E>(static_cast<U>(a_lhs) >> a_rhs.underlying()); }
166
167 friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, EnumSet a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
168 friend constexpr EnumSet& operator>>=(EnumSet& a_lhs, E a_rhs) noexcept { return a_lhs = a_lhs >> a_rhs; }
169
170 friend constexpr EnumSet& operator~(EnumSet& a_lhs) noexcept { return a_lhs = ~a_lhs.underlying(); }
171
172 private:
173 U _impl{ 0 };
174 };
175
176 template <class... Args>
177 EnumSet(Args...) -> EnumSet<
178 std::common_type_t<Args...>,
179 std::underlying_type_t<
180 std::common_type_t<Args...>>>;
181}
Definition EnumSet.h:9
friend constexpr EnumSet & operator&=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:125
constexpr EnumSet() noexcept=default
constexpr bool any(Args... a_args) const noexcept
Definition EnumSet.h:92
constexpr U underlying() const noexcept
Definition EnumSet.h:54
constexpr EnumSet & reset(Args... a_args) noexcept
Definition EnumSet.h:78
friend constexpr EnumSet operator&(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:122
friend constexpr EnumSet operator|(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:128
friend constexpr EnumSet operator|(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:130
friend constexpr EnumSet & operator&=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:126
constexpr E get() const noexcept
Definition EnumSet.h:53
constexpr EnumSet & reset() noexcept
Definition EnumSet.h:85
friend constexpr EnumSet operator>>(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:164
friend constexpr EnumSet & operator-=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:153
friend constexpr std::strong_ordering operator<=>(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:119
friend constexpr EnumSet operator>>(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:165
friend constexpr EnumSet operator<<(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:158
friend constexpr EnumSet & operator>>=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:168
constexpr bool none(Args... a_args) const noexcept
Definition EnumSet.h:106
constexpr bool all(Args... a_args) const noexcept
Definition EnumSet.h:99
friend constexpr EnumSet & operator+=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:146
friend constexpr EnumSet operator^(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:135
friend constexpr EnumSet & operator-=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:154
friend constexpr EnumSet operator<<(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:156
friend constexpr EnumSet operator+(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:144
friend constexpr EnumSet & operator|=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:133
friend constexpr EnumSet operator+(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:142
friend constexpr EnumSet & operator~(EnumSet &a_lhs) noexcept
Definition EnumSet.h:170
constexpr EnumSet & set(Args... a_args) noexcept
Definition EnumSet.h:58
constexpr EnumSet & set(bool a_set, Args... a_args) noexcept
Definition EnumSet.h:66
friend constexpr EnumSet & operator<<=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:161
friend constexpr EnumSet operator-(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:150
friend constexpr EnumSet operator^(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:137
friend constexpr EnumSet operator&(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:121
constexpr EnumSet(Args... a_values) noexcept
Definition EnumSet.h:27
friend constexpr EnumSet operator^(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:136
friend constexpr bool operator==(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:114
U underlying_type
Definition EnumSet.h:12
~EnumSet() noexcept=default
friend constexpr bool operator==(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:113
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:117
friend constexpr EnumSet & operator>>=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:167
friend constexpr EnumSet & operator+=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:147
friend constexpr EnumSet operator&(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:123
friend constexpr EnumSet operator>>(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:163
friend constexpr EnumSet operator-(EnumSet a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:149
friend constexpr EnumSet operator+(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:143
constexpr EnumSet & operator=(E a_value) noexcept
Definition EnumSet.h:43
friend constexpr EnumSet & operator^=(EnumSet &a_lhs, E a_rhs) noexcept
Definition EnumSet.h:140
friend constexpr EnumSet operator<<(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:157
constexpr E operator*() const noexcept
Definition EnumSet.h:52
friend constexpr EnumSet & operator|=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:132
friend constexpr EnumSet & operator^=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:139
friend constexpr std::strong_ordering operator<=>(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:118
friend constexpr EnumSet operator-(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:151
friend constexpr EnumSet operator|(EnumSet a_lhs, E a_rhs) noexcept
Definition EnumSet.h:129
friend constexpr bool operator==(E a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:115
friend constexpr EnumSet & operator<<=(EnumSet &a_lhs, EnumSet a_rhs) noexcept
Definition EnumSet.h:160
E enum_type
Definition EnumSet.h:11
Definition BSDirectInputManager.h:8