ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
bitwise.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of the module \alib_enumops of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib {
9
10/// This is the reference documentation of sub-namespace \c enumops of the \aliblink, which
11/// holds types of library module \alib_enumops.
12///
13/// Extensive documentation for this module is provided with
14/// \ref alib_mod_enums "ALib Module Enums - Programmer's Manual".
15///
16/// \attention
17/// All operators are declared in the global namespace, other than this
18/// namespace documentation indicates!
19namespace enumops {
20
21//##################################################################################################
22// struct BitwiseTraits
23//##################################################################################################
24
25//==================================================================================================
26/// Simple type trait that inherits <c>std::false_type</c> by default.
27/// If specialized for an enumeration type \p{TEnum} to inherit <c>std::true_type</c>, the
28/// following operators set of \alib operators become applicable to elements of \p{TEnum}:
29///
30/// - \alib{enumops::bitwise;operator&}
31/// - \alib{enumops::bitwise;operator&=}
32/// - \alib{enumops::bitwise;operator|}
33/// - \alib{enumops::bitwise;operator|=}
34/// - \alib{enumops::bitwise;operator^}
35/// - \alib{enumops::bitwise;operator^=}
36/// - \alib{enumops::bitwise;operator~}
37/// - \alib{enumops::bitwise;operator+} (Alias for \alib{enumops::bitwise;operator|})
38/// - \alib{enumops::bitwise;operator-} (Alias for a combination of operators
39/// \alib{enumops::bitwise;operator&} and \alib{enumops::bitwise;operator~})
40/// - \alib{enumops::bitwise;operator+=} (An alias for \alib{enumops::bitwise;operator|=})
41/// - \alib{enumops::bitwise;operator-=} (Removes given bit(s) )
42///
43/// \attention
44/// Likewise with the operators introduced with the type trait \alib{enumops;ArithmeticalTraits},
45/// this documentation "fakes" the operators into namespace <c>alib::enumops</c>,
46/// while in fact they are defined in the global namespace.<br>
47/// See \ref alib_enums_arithmetic_standard "corresponding note" in the Programmer's Manual
48/// for details.
49///
50/// <b>Restrictions</b><br>
51/// For technical reasons, this concept is not applicable to enum types that are defined as
52/// \c private or \c protected inner types of structs or classes.
53///
54/// \see
55/// - Macro \ref ALIB_ENUMS_MAKE_BITWISE, which specializes this type trait for a given
56/// enumeration type.
57/// - For details and a source code sample see chapter \ref alib_enums_arithmetic_bitwise
58/// of the Programmer's Manual of the module \alib_enumops.
59///
60/// \I{#############################################################################################}
61/// # Restrictions #
62/// For technical reasons, this concept is not applicable to enum types that are defined as
63/// \c private or \c protected inner types of structs or classes.
64///
65/// # Reference Documentation #
66///
67/// @tparam TEnum The enum type to enable bitwise operators for.
68//==================================================================================================
69template<typename TEnum>
70requires std::is_enum<TEnum>::value
71struct BitwiseTraits : std::false_type {};
72
74
75/// Concept that is satisfied if the type trait \alib{enumops;BitwiseTraits}
76/// is specialized for type \p{TEnum} to inherit <c>std::true_type</c>.
77/// @tparam TEnum The type to test.
78template<typename TEnum>
80
82
83} // namespace alib[::enumops]
84} // namespace [alib]
85
86//##################################################################################################
87// Bitwise Operators
88//##################################################################################################
89// For documentation, all operators and enum related template functions are faked into namespace
90// alib::enumops
91#if DOXYGEN
92namespace alib { namespace enumops {
93/// Operators available to elements of enumerations if \alib{enumops;BitwiseTraits} is
94/// specialized.
95///
96/// \note
97/// This namespace exits only in the documentation to collect the operators.
98/// When parsed by a C++ compiler, <b>the operators reside in the global namespace</b> and
99/// functions \alib{enumops::bitwise;HasBits}, \alib{enumops::bitwise;CountElements},
100/// \alib{enumops::bitwise;ToBitwiseEnumeration} and \alib{enumops::bitwise;ToSequentialEnumeration}
101/// reside in namespace \ref alib.
102///
103/// As required, when parsed by a C++ compiler, the operators reside in the global namespace.
105#endif
106
107
108/// Bitwise \b and operator usable with scoped enum types.<br>
109/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
110/// template enum type \p{TEnum} to inherit \c std::true_type.
111///
112/// @tparam TEnum Enumeration type.
113/// @param lhs First operand.
114/// @param rhs Second operand.
115/// @return The result of a bitwise and operation of the underlying enum values.
117template<typename TEnum>
119constexpr TEnum operator& (TEnum lhs, TEnum rhs) noexcept {
120 using TBits= typename std::underlying_type<TEnum>::type;
121 return TEnum(TBits(lhs) & TBits(rhs));
122}
123
124/// Bitwise assignment operator usable with scoped enum types.<br>
125/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
126/// template enum type \p{TEnum} to inherit \c std::true_type.
127///
128/// @tparam TEnum Enumeration type.
129/// @param[in,out] lhs Reference to the first operand. Receives the result.
130/// @param rhs Second operand.
131/// @return The new value of \p{lhs} which is set to <c>lhs & rhs</c>.
133template<typename TEnum>
135constexpr TEnum operator&= (TEnum& lhs, TEnum rhs) noexcept {
136 using TBits= typename std::underlying_type<TEnum>::type;
137 return lhs= TEnum( TBits(lhs) & TBits(rhs) );
138}
139
140/// Bitwise \b or operator usable with scoped enum types.<br>
141/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
142/// template enum type \p{TEnum} to inherit \c std::true_type.
143///
144/// @tparam TEnum Enumeration type.
145/// @param lhs First operand.
146/// @param rhs Second operand.
147/// @return The result of a bitwise or operation of the underlying enum values.
149template<typename TEnum>
151constexpr TEnum operator| (TEnum lhs, TEnum rhs) noexcept {
152 using TBits= typename std::underlying_type<TEnum>::type;
153 return TEnum(TBits(lhs) | TBits(rhs));
154}
155
156/// Bitwise <b>or assignment</b> operator usable with scoped enum types.<br>
157/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
158/// template enum type \p{TEnum} to inherit \c std::true_type.
159///
160/// @tparam TEnum Enumeration type.
161/// @param[in,out] lhs Reference to the first operand. Receives the result.
162/// @param rhs Second operand.
163/// @return The new value of \p{lhs} which is set to <c>lhs | rhs</c>.
165template<typename TEnum>
167constexpr TEnum operator|= (TEnum& lhs, TEnum rhs) noexcept {
168 using TBits= typename std::underlying_type<TEnum>::type;
169 return lhs= TEnum( TBits(lhs) | TBits(rhs) );
170}
171
172/// Bitwise \b xor operator usable with scoped enum types.<br>
173/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
174/// template enum type \p{TEnum} to inherit \c std::true_type.
175///
176/// @tparam TEnum Enumeration type.
177/// @param lhs First operand.
178/// @param rhs Second operand.
179/// @return The result of a bitwise xor operation of the underlying enum values.
181template<typename TEnum>
183constexpr TEnum operator^ (TEnum lhs, TEnum rhs) noexcept {
184 using TBits= typename std::underlying_type<TEnum>::type;
185 return TEnum(TBits(lhs) ^ TBits(rhs));
186}
187
188/// Bitwise <b>xor assignment</b> operator usable with scoped enum types.<br>
189/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
190/// template enum type \p{TEnum} to inherit \c std::true_type.
191///
192/// @tparam TEnum Enumeration type.
193/// @param[in,out] lhs Reference to the first operand. Receives the result.
194/// @param rhs Second operand.
195/// @return The new value of \p{lhs} which is set to <c>lhs ^ rhs</c>.
197template<typename TEnum>
199constexpr TEnum operator^= (TEnum& lhs, TEnum rhs) noexcept {
200 using TBits= typename std::underlying_type<TEnum>::type;
201 return lhs= TEnum( TBits(lhs) ^ TBits(rhs) );
202}
203
204/// Bitwise \b not operator usable with scoped enum types.<br>
205/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
206/// template enum type \p{TEnum} to inherit \c std::true_type.
207///
208/// \note To remove one or more bits from a scoped enum value, operator <b>&=</b> with this operator
209/// applied to \p{op} can be used.
210/// A shortcut to this is given with \ref operator-=.
211///
212/// @tparam TEnum Enumeration type.
213/// @param op The operand to be negated.
214/// @return The result of a bitwise negation of \p{op}.
216template<typename TEnum>
218constexpr TEnum operator~ (TEnum op) noexcept {
219 using TBits= typename std::underlying_type<TEnum>::type;
220 return TEnum( ~ TBits(op) );
221}
222
223
224/// Alias to bitwise \b or operator usable with scoped enum types.<br>
225/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
226/// template enum type \p{TEnum} to inherit \c std::true_type and if \alib{enumops;ArithmeticalTraits}
227/// is \b not specialized to inherit \c std::true_type. The latter is to avoid ambiguities in
228/// situations where an enum is both, arithmetical and bitwise.
229///
230/// @tparam TEnum Enumeration type.
231/// @param lhs First operand.
232/// @param rhs Second operand.
233/// @return The result of a bitwise or operation of the underlying enum values.
235template<typename TEnum>
236requires ( alib::enumops::IsBitwise <TEnum>
238constexpr TEnum operator+ (TEnum lhs, TEnum rhs) noexcept {
239 using TBits= typename std::underlying_type<TEnum>::type;
240 return TEnum(TBits(lhs) | TBits(rhs));
241}
242
243/// Alias for bitwise <b>or assignment</b> operator usable with scoped enum types.<br>
244/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
245/// template enum type \p{TEnum} to inherit \c std::true_type and if \alib{enumops;ArithmeticalTraits}
246/// is \b not specialized to inherit \c std::true_type. The latter is to avoid ambiguities in
247/// situations where an enum is both, arithmetical and bitwise.
248///
249/// @tparam TEnum Enumeration type.
250/// @param[in,out] lhs Reference to the first operand. Receives the result.
251/// @param rhs Second operand.
252/// @return The new value of \p{lhs} which is set to <c>lhs | rhs</c>.
254template<typename TEnum>
255requires ( alib::enumops::IsBitwise <TEnum>
257constexpr TEnum operator+= (TEnum& lhs, TEnum rhs) noexcept {
258 using TBits= typename std::underlying_type<TEnum>::type;
259 return lhs= TEnum( TBits(lhs) | TBits(rhs) );
260}
261
262/// Removes bit(s) found in \p{rhs} from \p{lhs} an returns result. This is a shortcut to:
263///
264/// lhs & !rhs
265///
266/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
267/// template enum type \p{TEnum} to inherit \c std::true_type and if \alib{enumops;ArithmeticalTraits}
268/// is \b not specialized to inherit \c std::true_type. The latter is to avoid ambiguities in
269/// situations where an enum is both, arithmetical and bitwise.
270///
271/// @tparam TEnum Enumeration type.
272/// @param lhs First operand.
273/// @param rhs Second operand.
274/// @return The result of <c>lhs & !rhs</c>.
276template<typename TEnum>
277requires ( alib::enumops::IsBitwise <TEnum>
279constexpr TEnum operator- (TEnum lhs, TEnum rhs) noexcept {
280 using TBits= typename std::underlying_type<TEnum>::type;
281 return TEnum( TBits(lhs) & (~TBits(rhs)) );
282}
283
284/// Removes bit(s) found in \p{rhs} from \p{lhs}. This is a shortcut to:
285///
286/// lhs &= !rhs
287///
288/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
289/// template enum type \p{TEnum} to inherit \c std::true_type and if \alib{enumops;ArithmeticalTraits}
290/// is \b not specialized to inherit \c std::true_type. The latter is to avoid ambiguities in
291/// situations where an enum is both, arithmetical and bitwise.
292///
293/// @tparam TEnum Enumeration type.
294/// @param[in,out] lhs Reference to the first operand. Receives the result.
295/// @param rhs Second operand.
296/// @return The new value of \p{lhs} which is set to <c>lhs & ( ~rhs )</c>.
298template<typename TEnum>
299requires ( alib::enumops::IsBitwise <TEnum>
301constexpr TEnum operator-= (TEnum& lhs, TEnum rhs) noexcept {
302 using TBits= typename std::underlying_type<TEnum>::type;
303 return lhs= TEnum( TBits(lhs) & (~TBits(rhs)) );
304}
305
306#if !DOXYGEN
307ALIB_EXPORT namespace alib {
308#endif
309
310/// Tests if the integral value of the given enum \p{element} contains all bits set in
311/// \p{selection}.
312/// In other words, returns result of:
313///
314/// ( element & selection ) == selection
315///
316/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
317/// template enum type \p{TEnum} to inherit \c std::true_type.
318///
319/// @tparam TEnum Enumeration type. Deduced by the compiler.
320/// @param element Bitset to be tested.
321/// @param selection Second operand.
322/// @return \c true if all bits of \p{selection} are set in \p{element}.
323template<typename TEnum>
325constexpr bool HasBits(TEnum element, TEnum selection) noexcept {
326 using TBits= typename std::underlying_type<TEnum>::type;
327 return ( TBits(element) & TBits(selection) ) == TBits(selection);
328}
329
330/// Tests if the integral value of the given enum \p{element} contains at least one of the bits
331/// set in \p{selection}.
332/// In other words, returns result of:
333///
334/// ( element & selection ) != 0
335///
336/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
337/// template enum type \p{TEnum} to inherit \c std::true_type.
338///
339/// @tparam TEnum Enumeration type. Deduced by the compiler.
340/// @param element Bitset to be tested.
341/// @param selection Second operand.
342/// @return \c true if one of the bits of \p{selection} are set in \p{element}.
343template<typename TEnum>
345constexpr bool HasOneOf(TEnum element, TEnum selection) noexcept {
346 using TBits= typename std::underlying_type<TEnum>::type;
347 return ( TBits(element) & TBits(selection) ) != TBits(0);
348}
349
350/// Returns the number of bitwise enumeration elements set in the given value.
351/// In other words, the bits given in \p{value} are counted and the number is returned.
352///
353/// Selected by the compiler only if \alib{enumops;BitwiseTraits} is specialized for
354/// template enum type \p{TEnum} to inherit \c std::true_type.
355///
356/// @param value A single or composite selection of bits.
357/// @return The result of a call to #alib::lang::BitCount().
358template<typename TEnum>
360constexpr int CountElements( TEnum value ) { return lang::BitCount(UnderlyingIntegral(value)); }
361
362#if DOXYGEN
363}}} // doxygen namespace [alib::enumops::bitwise]
364#else
365} // namespace [alib]
366#endif
#define ALIB_WARNINGS_RESTORE
Definition alib.inl:719
#define ALIB_WARNINGS_IGNORE_DOCS
Definition alib.inl:702
#define ALIB_EXPORT
Definition alib.inl:497
ALIB_EXPORT constexpr TEnum operator&=(TEnum &lhs, TEnum rhs) noexcept
Definition bitwise.inl:135
ALIB_EXPORT constexpr TEnum operator^(TEnum lhs, TEnum rhs) noexcept
Definition bitwise.inl:183
constexpr int CountElements(TEnum value)
Definition bitwise.inl:360
ALIB_EXPORT constexpr TEnum operator|=(TEnum &lhs, TEnum rhs) noexcept
Definition bitwise.inl:167
ALIB_EXPORT constexpr TEnum operator^=(TEnum &lhs, TEnum rhs) noexcept
Definition bitwise.inl:199
constexpr bool HasOneOf(TEnum element, TEnum selection) noexcept
Definition bitwise.inl:345
ALIB_EXPORT constexpr TEnum operator~(TEnum op) noexcept
Definition bitwise.inl:218
ALIB_EXPORT constexpr TEnum operator&(TEnum lhs, TEnum rhs) noexcept
Definition bitwise.inl:119
constexpr bool HasBits(TEnum element, TEnum selection) noexcept
Definition bitwise.inl:325
ALIB_EXPORT constexpr TEnum operator|(TEnum lhs, TEnum rhs) noexcept
Definition bitwise.inl:151
std::underlying_type_t< TEnum > constexpr UnderlyingIntegral(TEnum element) noexcept
constexpr int BitCount(TIntegral value)
Definition bits.inl:215