1+ #include < StormByte/type_traits.hxx>
2+
3+ using namespace StormByte ;
4+
5+ /* *
6+ * @brief Bitwise OR operator for unsigned enum classes.
7+ * @tparam E The enumeration type.
8+ * @param a First enum value.
9+ * @param b Second enum value.
10+ * @return The result of the bitwise OR operation.
11+ *
12+ * This operator allows combining flags of an unsigned enum class using the bitwise OR operator.
13+ */
14+ template <Type::UnsignedEnum E>
15+ constexpr E operator |(E a, E b) noexcept {
16+ return static_cast <E>(Type::ToUnderlying (a) | Type::ToUnderlying (b));
17+ }
18+
19+ /* *
20+ * @brief Bitwise AND operator for unsigned enum classes.
21+ * @tparam E The enumeration type.
22+ * @param a First enum value.
23+ * @param b Second enum value.
24+ * @return The result of the bitwise AND operation.
25+ *
26+ * This operator allows checking common flags of an unsigned enum class using the bitwise AND operator.
27+ */
28+ template <Type::UnsignedEnum E>
29+ constexpr E operator &(E a, E b) noexcept {
30+ return static_cast <E>(Type::ToUnderlying (a) & Type::ToUnderlying (b));
31+ }
32+
33+ /* *
34+ * @brief Bitwise XOR operator for unsigned enum classes.
35+ * @tparam E The enumeration type.
36+ * @param a First enum value.
37+ * @param b Second enum value.
38+ * @return The result of the bitwise XOR operation.
39+ *
40+ * This operator allows toggling flags of an unsigned enum class using the bitwise XOR operator.
41+ */
42+ template <Type::UnsignedEnum E>
43+ constexpr E operator ^(E a, E b) noexcept {
44+ return static_cast <E>(Type::ToUnderlying (a) ^ Type::ToUnderlying (b));
45+ }
46+
47+ /* *
48+ * @brief Bitwise NOT operator for unsigned enum classes.
49+ * @tparam E The enumeration type.
50+ * @param a Enum value to invert.
51+ * @return The result of the bitwise NOT operation.
52+ *
53+ * This operator allows inverting flags of an unsigned enum class using the bitwise NOT operator.
54+ */
55+ template <Type::UnsignedEnum E>
56+ constexpr E operator ~(E a) noexcept {
57+ return static_cast <E>(~Type::ToUnderlying (a));
58+ }
59+
60+ /* *
61+ * @namespace StormByte
62+ * @brief Main namespace for the StormByte library.
63+ *
64+ * The `StormByte` namespace serves as the root for all components and utilities in the StormByte library.
65+ * It provides foundational classes and tools for building robust, thread-safe, and efficient applications.
66+ */
67+ namespace StormByte {
68+ /* *
69+ * @brief Bitmask class template for managing enum class flags.
70+ * @tparam Derived The derived class type.
71+ * @tparam E The enumeration type representing the flags.
72+ *
73+ * This class provides bitwise operations for enum class types,
74+ * allowing easy manipulation of flag combinations.
75+ *
76+ * Example usage:
77+ * @code
78+ * enum class MyFlags : uint8_t {
79+ * FlagA = 0x01,
80+ * FlagB = 0x02,
81+ * FlagC = 0x04
82+ * };
83+ *
84+ * class MyBitmask : public Bitmask<MyBitmask, MyFlags> {
85+ * public:
86+ * using Bitmask<MyBitmask, MyFlags>::Bitmask;
87+ * };
88+ *
89+ * MyBitmask mask(MyFlags::FlagA);
90+ * mask |= MyBitmask(MyFlags::FlagB);
91+ * if (mask.Has(MyFlags::FlagA)) { ... }
92+ * @endcode
93+ */
94+ template <typename Derived, Type::UnsignedEnum E>
95+ class Bitmask {
96+ public:
97+ /* *
98+ * @brief Default constructor initializes the bitmask to zero.
99+ */
100+ constexpr Bitmask () noexcept : m_value(static_cast <E>(0 )) {}
101+
102+ /* *
103+ * @brief Constructor initializes the bitmask with a specific enum value.
104+ * @param value The initial enum value for the bitmask.
105+ */
106+ constexpr Bitmask (E value) noexcept : m_value(value) {}
107+
108+ /* *
109+ * @brief Copy constructor.
110+ * @param other The other Bitmask to copy from.
111+ */
112+ constexpr Bitmask (const Bitmask& other) noexcept = default;
113+
114+ /* *
115+ * @brief Move constructor.
116+ * @param other The other Bitmask to move from.
117+ */
118+ constexpr Bitmask (Bitmask&& other) noexcept = default;
119+
120+ /* *
121+ * @brief Destructor.
122+ */
123+ constexpr virtual ~Bitmask () noexcept = default ;
124+
125+ /* *
126+ * @brief Copy assignment operator.
127+ * @param other The other Bitmask to copy from.
128+ * @return Reference to this Bitmask.
129+ */
130+ constexpr Bitmask& operator =(const Bitmask& other) noexcept = default ;
131+
132+ /* *
133+ * @brief Move assignment operator.
134+ * @param other The other Bitmask to move from.
135+ * @return Reference to this Bitmask.
136+ */
137+ constexpr Bitmask& operator =(Bitmask&& other) noexcept = default ;
138+
139+ /* *
140+ * @brief Equality operator.
141+ * @param other The other Bitmask to compare with.
142+ * @return True if the bitmasks are equal, false otherwise.
143+ */
144+ constexpr bool operator ==(const Bitmask& other) const noexcept {
145+ return m_value == other.m_value ;
146+ }
147+
148+ /* *
149+ * @brief Inequality operator.
150+ * @param other The other Bitmask to compare with.
151+ * @return True if the bitmasks are not equal, false otherwise.
152+ */
153+ constexpr bool operator !=(const Bitmask& other) const noexcept {
154+ return m_value != other.m_value ;
155+ }
156+
157+ /* *
158+ * @brief Bitwise OR operator.
159+ * @param other The other Bitmask to combine with.
160+ * @return A new Bitmask representing the result of the bitwise OR operation.
161+ */
162+ constexpr Derived operator |(const Bitmask& other) const noexcept {
163+ return Derived (m_value | other.m_value );
164+ }
165+
166+ /* *
167+ * @brief Bitwise AND operator.
168+ * @param other The other Bitmask to combine with.
169+ * @return A new Bitmask representing the result of the bitwise AND operation.
170+ */
171+ constexpr Derived operator &(const Bitmask& other) const noexcept {
172+ return Derived (m_value & other.m_value );
173+ }
174+
175+ /* *
176+ * @brief Bitwise XOR operator.
177+ * @param other The other Bitmask to combine with.
178+ * @return A new Bitmask representing the result of the bitwise XOR operation.
179+ */
180+ constexpr Derived operator ^(const Bitmask& other) const noexcept {
181+ return Derived (m_value ^ other.m_value );
182+ }
183+
184+ /* *
185+ * @brief Bitwise NOT operator.
186+ * @return A new Bitmask representing the result of the bitwise NOT operation.
187+ */
188+ constexpr Derived operator ~() const noexcept {
189+ return Derived (~m_value);
190+ }
191+
192+ /* *
193+ * @brief Bitwise OR assignment operator.
194+ * @param other The other Bitmask to combine with.
195+ * @return Reference to this Bitmask after the operation.
196+ */
197+ constexpr Bitmask& operator |=(const Bitmask& other) noexcept {
198+ m_value = m_value | other.m_value ;
199+ return *this ;
200+ }
201+
202+ /* *
203+ * @brief Bitwise AND assignment operator.
204+ * @param other The other Bitmask to combine with.
205+ * @return Reference to this Bitmask after the operation.
206+ */
207+ constexpr Bitmask& operator &=(const Bitmask& other) noexcept {
208+ m_value = m_value & other.m_value ;
209+ return *this ;
210+ }
211+
212+ /* *
213+ * @brief Bitwise XOR assignment operator.
214+ * @param other The other Bitmask to combine with.
215+ * @return Reference to this Bitmask after the operation.
216+ */
217+ constexpr Bitmask& operator ^=(const Bitmask& other) noexcept {
218+ m_value = m_value ^ other.m_value ;
219+ return *this ;
220+ }
221+
222+ /* *
223+ * @brief Add a flag to the bitmask.
224+ * @param value The enum value to add.
225+ */
226+ constexpr void Add (E value) noexcept {
227+ m_value = m_value | value;
228+ }
229+
230+ /* *
231+ * @brief Remove a flag from the bitmask.
232+ * @param value The enum value to remove.
233+ */
234+ constexpr void Remove (E value) noexcept {
235+ m_value = m_value & ~value;
236+ }
237+
238+ /* *
239+ * @brief Get the current value of the bitmask.
240+ * @return The current enum value of the bitmask.
241+ */
242+ constexpr E Value () const noexcept {
243+ return m_value;
244+ }
245+
246+ /* *
247+ * @brief Check if the bitmask has a specific flag set.
248+ * @param value The enum value to check.
249+ * @return True if the flag is set, false otherwise.
250+ */
251+ constexpr bool Has (E value) const noexcept {
252+ return (m_value & value) == value;
253+ }
254+
255+ /* *
256+ * @brief Check if the bitmask has all flags set from another bitmask.
257+ * @param other The other Bitmask to check against.
258+ * @return True if all flags are set, false otherwise.
259+ */
260+ constexpr bool Has (const Bitmask& other) const noexcept {
261+ return Has (other.m_value );
262+ }
263+
264+ /* *
265+ * @brief Check if any of the specified flags are set in the bitmask.
266+ * @param value The enum value(s) to check.
267+ * @return True if any of the flags are set, false otherwise.
268+ */
269+ constexpr bool HasAny (E value) const noexcept {
270+ return (m_value & value) != static_cast <E>(0 );
271+ }
272+
273+ /* *
274+ * @brief Check if any of the flags from another bitmask are set in this bitmask.
275+ * @param other The other Bitmask to check against.
276+ * @return True if any of the flags are set, false otherwise.
277+ */
278+ constexpr bool HasAny (const Bitmask& other) const noexcept {
279+ return HasAny (other.m_value );
280+ }
281+
282+ /* *
283+ * @brief Check if none of the specified flags are set in the bitmask.
284+ * @param value The enum value(s) to check.
285+ * @return True if none of the flags are set, false otherwise.
286+ */
287+ constexpr bool HasNone (E value) const noexcept {
288+ return (m_value & value) == static_cast <E>(0 );
289+ }
290+
291+ /* *
292+ * @brief Check if none of the flags from another bitmask are set in this bitmask.
293+ * @param other The other Bitmask to check against.
294+ * @return True if none of the flags are set, false otherwise.
295+ */
296+ constexpr bool HasNone (const Bitmask& other) const noexcept {
297+ return HasNone (other.m_value );
298+ }
299+
300+ protected:
301+ E m_value;
302+ };
303+ }
0 commit comments