ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
arithmetical.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//==================================================================================================
9
10//##################################################################################################
11// struct ArithmeticalTraits
12//##################################################################################################
13
14//==================================================================================================
15/// A simple type trait that inherits <c>std::false_type</c> by default. If specialized for an
16/// enumeration type \p{TEnum} to inherit <c>std::true_type</c>, the following operators set of
17/// \alib operators become applicable to elements of \p{TEnum}:
18///
19/// - \alib{enumops::arithmetical;operator<}
20/// - \alib{enumops::arithmetical;operator<=}
21/// - \alib{enumops::arithmetical;operator>}
22/// - \alib{enumops::arithmetical;operator>=}
23/// - \alib{enumops::arithmetical;operator+}
24/// - \alib{enumops::arithmetical;operator-}
25/// - \alib{enumops::arithmetical;operator++}
26/// - \alib{enumops::arithmetical;operator++(TEnum&;std::underlying_type<TEnum>::type)}
27/// - \alib{enumops::arithmetical;operator--}
28/// - \alib{enumops::arithmetical;operator--(TEnum&;std::underlying_type<TEnum>::type)}
29/// - \alib{enumops::arithmetical;operator+=}
30/// - \alib{enumops::arithmetical;operator-=}
31///
32/// \attention
33/// Likewise with the operators introduced with the type trait \alib{enumops;BitwiseTraits},
34/// this documentation "fakes" the operators into namespace <c>alib::enumops</c>,
35/// while in fact they are defined in the global namespace!<br>
36/// See \ref alib_enums_arithmetic_standard "corresponding note" in the Programmer's Manual
37/// for details.
38///
39/// <b>Restrictions</b><br>
40/// For technical reasons, this concept is not applicable to enum types that are defined as
41/// \c private or \c protected inner types of structs or classes.
42///
43/// \see
44/// - Macro \ref ALIB_ENUMS_MAKE_ARITHMETICAL, which specializes this type trait for a given
45/// enumeration type.
46/// - For details and a source code sample see chapter \ref alib_enums_arithmetic_standard
47/// of the Programmer's Manual of the module \alib_enumops.
48///
49/// @tparam TEnum The enum type to enable arithmetical operators for.
50//==================================================================================================
51template<typename TEnum>
52requires std::is_enum<TEnum>::value
53struct ArithmeticalTraits : std::false_type {};
54
56
57/// Concept that is satisfied if the type trait \alib{enumops;ArithmeticalTraits}
58/// is specialized for type \p{TEnum} to inherit <c>std::true_type</c>.
59/// @tparam TEnum The type to test.
60template<typename TEnum>
62
64} // namespace [alib::enumops]
65
66
67//##################################################################################################
68// Arithmetic Operators
69//##################################################################################################
70
71// For documentation, all operators and enum related template functions are faked into namespace
72// alib::enumops
73#if DOXYGEN
74namespace alib { namespace enumops {
75
76/// Operators available to elements of enumerations if \alib{enumops;ArithmeticalTraits} is
77/// specialized.
78///
79/// \note
80/// This namespace exits only in the documentation to collect the operators.
81/// When parsed by a C++ compiler, <b>the operators reside in the global namespace</b>.
82namespace arithmetical {
83#endif
84
85
86/// Comparison operator \e less between an enum element and an integral value of underlying type.
87///
88/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
89/// template enum type \p{TEnum} to inherit \c std::true_type.
90///
91/// @tparam TEnum Enumeration type.
92/// @param lhs First operand.
93/// @param rhs Second operand.
94/// @return The result of the comparison.
96template<typename TEnum>
98constexpr bool operator< (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
99 using TValue= typename std::underlying_type<TEnum>::type;
100 return TValue(lhs) < rhs ;
101}
102
103/// Comparison operator <em>less or equal</em> between an enum element and an integral value of
104/// the underlying type.
105///
106/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
107/// template enum type \p{TEnum} to inherit \c std::true_type.
108///
109/// @tparam TEnum Enumeration type.
110/// @param lhs First operand.
111/// @param rhs Second operand.
112/// @return The result of the comparison.
114template<typename TEnum>
116constexpr bool operator<= (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
117 using TValue= typename std::underlying_type<TEnum>::type;
118 return TValue(lhs) <= rhs;
119}
120
121/// Comparison operator <em>greater</em> between an enum element and an integral value of
122/// underlying type.
123///
124/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
125/// template enum type \p{TEnum} to inherit \c std::true_type.
126///
127/// @tparam TEnum Enumeration type.
128/// @param lhs First operand.
129/// @param rhs Second operand.
130/// @return The result of the comparison.
132template<typename TEnum>
134constexpr bool operator> (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
135 using TValue= typename std::underlying_type<TEnum>::type;
136 return TValue(lhs) > rhs;
137}
138
139/// Comparison operator <em>greater or equal</em> between an enum element and an integral value of
140/// the underlying type.
141///
142/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
143/// template enum type \p{TEnum} to inherit \c std::true_type.
144///
145/// @tparam TEnum Enumeration type.
146/// @param lhs First operand.
147/// @param rhs Second operand.
148/// @return The result of the comparison.
150template<typename TEnum>
152constexpr bool operator>= (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
153 using TValue= typename std::underlying_type<TEnum>::type;
154 return TValue(lhs) >= rhs ;
155}
156
157
158/// Add-operator between two enum elements.
159///
160/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
161/// template enum type \p{TEnum} to inherit \c std::true_type.
162///
163/// @tparam TEnum Enumeration type.
164/// @param lhs First operand.
165/// @param rhs Second operand.
166/// @return The resulting enum element.
168template<typename TEnum>
170constexpr TEnum operator+ (TEnum lhs, TEnum rhs) noexcept {
171 using TValue= typename std::underlying_type<TEnum>::type;
172 return TEnum( TValue(lhs) + TValue(rhs) );
173}
174
175/// Add-operator between an enum element and an integral value of underlying type.
176///
177/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
178/// template enum type \p{TEnum} to inherit \c std::true_type.
179///
180/// @tparam TEnum Enumeration type.
181/// @param lhs First operand.
182/// @param rhs Second operand.
183/// @return The resulting enum element.
185template<typename TEnum>
187constexpr TEnum operator+ (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
188 using TValue= typename std::underlying_type<TEnum>::type;
189 return TEnum( TValue(lhs) + rhs );
190}
191
192
193/// Add-assignment-operator between two enum elements.
194///
195/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
196/// template enum type \p{TEnum} to inherit \c std::true_type.
197///
198/// @tparam TEnum Enumeration type.
199/// @param lhs First operand.
200/// @param rhs Second operand.
201/// @return The new value of \p{lhs} which is set to the resulting enum element.
203template<typename TEnum>
205constexpr TEnum operator+= (TEnum& lhs, TEnum rhs) noexcept {
206 using TValue= typename std::underlying_type<TEnum>::type;
207 return lhs= TEnum( TValue(lhs) + TValue(rhs) );
208}
209
210/// Add-assignment-operator between an enum element and an integral value of underlying type.
211///
212/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
213/// template enum type \p{TEnum} to inherit \c std::true_type.
214///
215/// @param[in,out] lhs Reference to the first operand. Receives the result.
216/// @tparam TEnum Enumeration type.
217/// @param rhs Second operand.
218/// @return The new value of \p{lhs} which is set to the resulting enum element.
220template<typename TEnum>
222constexpr TEnum operator+= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
223 using TValue= typename std::underlying_type<TEnum>::type;
224 return lhs= TEnum( TValue(lhs) + rhs );
225}
226
227/// Prefix increment operator.
228///
229/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
230/// template enum type \p{TEnum} to inherit \c std::true_type.
231///
232/// @tparam TEnum Enumeration type.
233/// @param[in,out] arg Reference to the enum value to be incremented.
234/// @return The new value of \p{lhs} which is set to the resulting enum element.
236template<typename TEnum>
238constexpr TEnum operator++ (TEnum& arg) noexcept {
239 using TValue= typename std::underlying_type<TEnum>::type;
240 return arg= TEnum( TValue(arg) + 1 );
241}
242
243/// Postfix increment operator.
244///
245/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
246/// template enum type \p{TEnum} to inherit \c std::true_type.
247///
248/// @tparam TEnum Enumeration type.
249/// @param[in,out] arg Reference to the enum value to be incremented.
250/// @return The old value of \p{arg}.
252template<typename TEnum>
254constexpr TEnum operator++ (TEnum& arg, typename std::underlying_type<TEnum>::type) noexcept {
255 using TValue= typename std::underlying_type<TEnum>::type;
256 TEnum tmp= arg;
257 arg= TEnum( TValue(arg) + 1 );
258 return tmp;
259}
260
261/// Subtract operator between two enum elements.
262///
263/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
264/// template enum type \p{TEnum} to inherit \c std::true_type.
265///
266/// @tparam TEnum Enumeration type.
267/// @param lhs First operand.
268/// @param rhs Second operand.
269/// @return The resulting enum element.
271template<typename TEnum>
273constexpr TEnum operator- (TEnum lhs, TEnum rhs) noexcept {
274 using TValue= typename std::underlying_type<TEnum>::type;
275 return TEnum( TValue(lhs) - TValue(rhs) );
276}
277
278
279/// Subtract operator between an enum element and an integral value of underlying type.
280///
281/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
282/// template enum type \p{TEnum} to inherit \c std::true_type.
283///
284/// @tparam TEnum Enumeration type.
285/// @param lhs First operand.
286/// @param rhs Second operand.
287/// @return The resulting enum element.
289template<typename TEnum>
291constexpr TEnum operator- (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
292 using TValue= typename std::underlying_type<TEnum>::type;
293 return TEnum( TValue(lhs) - rhs );
294}
295
296/// Subtract assignment operator between two enum elements.
297///
298/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
299/// template enum type \p{TEnum} to inherit \c std::true_type.
300///
301/// @tparam TEnum Enumeration type.
302/// @param lhs First operand.
303/// @param rhs Second operand.
304/// @return The new value of \p{lhs} which is set to the resulting enum element.
306template<typename TEnum>
308constexpr TEnum operator-= (TEnum& lhs, TEnum rhs) noexcept {
309 using TValue= typename std::underlying_type<TEnum>::type;
310 return lhs= TEnum( TValue(lhs) - TValue(rhs) );
311}
312
313/// Subtract assignment operator between an enum element and an integral value of underlying type.
314///
315/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
316/// template enum type \p{TEnum} to inherit \c std::true_type.
317///
318/// @tparam TEnum Enumeration type.
319/// @param[in,out] lhs Reference to the first operand. Receives the result.
320/// @param rhs Second operand.
321/// @return The new value of \p{lhs} which is set to the resulting enum element.
323template<typename TEnum>
325constexpr TEnum operator-= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
326 using TValue= typename std::underlying_type<TEnum>::type;
327 return lhs= TEnum( TValue(lhs) - rhs );
328}
329
330/// Prefix decrement operator.
331///
332/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
333/// template enum type \p{TEnum} to inherit \c std::true_type.
334///
335/// @tparam TEnum Enumeration type.
336/// @param[in,out] arg Reference to the enum value to be decremented.
337/// @return The new value of \p{lhs} which is set to the resulting enum element.
339template<typename TEnum>
341constexpr TEnum operator-- (TEnum& arg) noexcept {
342 using TValue= typename std::underlying_type<TEnum>::type;
343 return arg= TEnum( TValue(arg) - 1 );
344}
345
346
347/// Postfix decrement operator.
348///
349/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
350/// template enum type \p{TEnum} to inherit \c std::true_type.
351///
352/// @tparam TEnum Enumeration type.
353/// @param[in,out] arg Reference to the enum value to be decremented.
354/// @return The old value of \p{arg}.
356template<typename TEnum>
358constexpr TEnum operator-- (TEnum& arg, typename std::underlying_type<TEnum>::type) noexcept {
359 using TValue= typename std::underlying_type<TEnum>::type;
360 TEnum tmp= arg;
361 arg= TEnum( TValue(arg) - 1 );
362 return tmp;
363}
364
365/// Unary plus operator for enum elements.
366///
367/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
368/// template enum type \p{TEnum} to inherit \c std::true_type.
369///
370/// @tparam TEnum Enumeration type.
371/// @param arg Operand.
372/// @return Parameter \p{arg} (identical value).
374template<typename TEnum>
376constexpr TEnum operator+ (TEnum arg) noexcept { return arg; }
377
378/// Unary minus operator for enum elements.
379///
380/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
381/// template enum type \p{TEnum} to inherit \c std::true_type.
382///
383/// @tparam TEnum Enumeration type.
384/// @param arg Operand.
385/// @return The resulting enum element.
387template<typename TEnum>
389constexpr TEnum operator- (TEnum arg) noexcept {
390 using TValue= typename std::underlying_type<TEnum>::type;
391 return TEnum( - TValue(arg) );
392}
393
394
395/// Multiplication operator between an enum element and an integral value of underlying type.
396///
397/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
398/// template enum type \p{TEnum} to inherit \c std::true_type.
399///
400/// @tparam TEnum Enumeration type.
401/// @param lhs First operand.
402/// @param rhs Second operand.
403/// @return The resulting enum element.
405template<typename TEnum>
407constexpr TEnum operator* (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
408 using TValue= typename std::underlying_type<TEnum>::type;
409 return TEnum( TValue(lhs) * rhs );
410}
411
412/// Multiplication assignment operator between an enum element and an integral value of underlying
413/// type.
414///
415/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
416/// template enum type \p{TEnum} to inherit \c std::true_type.
417///
418/// @tparam TEnum Enumeration type.
419/// @param[in,out] lhs Reference to the first operand. Receives the result.
420/// @param rhs Second operand.
421/// @return The resulting enum element.
423template<typename TEnum>
425constexpr TEnum operator*= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
426 using TValue= typename std::underlying_type<TEnum>::type;
427 return lhs= TEnum( TValue(lhs) * rhs );
428}
429
430/// Division operator between an enum element and an integral value of underlying type.
431///
432/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
433/// template enum type \p{TEnum} to inherit \c std::true_type.
434///
435/// @tparam TEnum Enumeration type.
436/// @param lhs First operand.
437/// @param rhs Second operand.
438/// @return The resulting enum element.
440template<typename TEnum>
442constexpr TEnum operator/ (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
443 using TValue= typename std::underlying_type<TEnum>::type;
444 return TEnum( TValue(lhs) / rhs );
445}
446
447/// Division assignment operator between an enum element and an integral value of underlying
448/// type.
449///
450/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
451/// template enum type \p{TEnum} to inherit \c std::true_type.
452///
453/// @tparam TEnum Enumeration type.
454/// @param[in,out] lhs Reference to the first operand. Receives the result.
455/// @param rhs Second operand.
456/// @return The resulting enum element.
458template<typename TEnum>
460constexpr TEnum operator/= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
461 using TValue= typename std::underlying_type<TEnum>::type;
462 return lhs= TEnum( TValue(lhs) / rhs );
463}
464
465
466/// Modulo operator between an enum element and an integral value of underlying type.
467///
468/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
469/// template enum type \p{TEnum} to inherit \c std::true_type.
470///
471/// @tparam TEnum Enumeration type.
472/// @param lhs First operand.
473/// @param rhs Second operand.
474/// @return The resulting enum element.
476template<typename TEnum>
478constexpr TEnum operator% (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
479 using TValue= typename std::underlying_type<TEnum>::type;
480 return TEnum( TValue(lhs) % rhs );
481}
482
483/// Modulo assignment operator between an enum element and an integral value of underlying
484/// type.
485///
486/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
487/// template enum type \p{TEnum} to inherit \c std::true_type.
488///
489/// @tparam TEnum Enumeration type.
490/// @param[in,out] lhs Reference to the first operand. Receives the result.
491/// @param rhs Second operand.
492/// @return The resulting enum element.
494template<typename TEnum>
496constexpr TEnum operator%= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
497 using TValue= typename std::underlying_type<TEnum>::type;
498 return lhs= TEnum( TValue(lhs) % rhs );
499}
500
501
502/// Shift-left operator between an enum element and an integral value of underlying type.
503///
504/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
505/// template enum type \p{TEnum} to inherit \c std::true_type.
506///
507/// @tparam TEnum Enumeration type.
508/// @param lhs First operand.
509/// @param rhs Second operand.
510/// @return The resulting enum element.
512template<typename TEnum>
514constexpr TEnum operator<< (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
515 using TValue= typename std::underlying_type<TEnum>::type;
516 return TEnum( TValue(lhs) << rhs );
517}
518
519/// Shift-left assignment operator between an enum element and an integral value of underlying type.
520///
521/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
522/// template enum type \p{TEnum} to inherit \c std::true_type.
523///
524/// @tparam TEnum Enumeration type.
525/// @param[in,out] lhs Reference to the first operand. Receives the result.
526/// @param rhs Second operand.
527/// @return The resulting enum element.
529template<typename TEnum>
531constexpr TEnum operator<<= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
532 using TValue= typename std::underlying_type<TEnum>::type;
533 return lhs= TEnum( TValue(lhs) << rhs );
534}
535
536
537/// Shift-right operator between an enum element and an integral value of underlying type.
538///
539/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
540/// template enum type \p{TEnum} to inherit \c std::true_type.
541///
542/// @tparam TEnum Enumeration type.
543/// @param lhs First operand.
544/// @param rhs Second operand.
545/// @return The resulting enum element.
547template<typename TEnum>
549constexpr TEnum operator>> (TEnum lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
550 using TValue= typename std::underlying_type<TEnum>::type;
551 return TEnum( TValue(lhs) << rhs );
552}
553
554/// Shift-right assignment operator between an enum element and an integral value of
555/// the underlying type.
556///
557/// Selected by the compiler only if \alib{enumops;ArithmeticalTraits} is specialized for
558/// template enum type \p{TEnum} to inherit \c std::true_type.
559///
560/// @tparam TEnum Enumeration type.
561/// @param[in,out] lhs Reference to the first operand. Receives the result.
562/// @param rhs Second operand.
563/// @return The resulting enum element.
565template<typename TEnum>
567constexpr TEnum operator>>= (TEnum& lhs, typename std::underlying_type<TEnum>::type rhs) noexcept {
568 using TValue= typename std::underlying_type<TEnum>::type;
569 return lhs= TEnum( TValue(lhs) >> rhs );
570}
571
572// Reset documentation fake
573#if DOXYGEN
574}}}} // doxygen namespace [alib::enumops::arithmetical]
575#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, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator>>=(TEnum &lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr bool operator>(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator*(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr bool operator>=(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator>>(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator+(TEnum lhs, TEnum rhs) noexcept
ALIB_EXPORT constexpr TEnum operator*=(TEnum &lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator++(TEnum &arg) noexcept
ALIB_EXPORT constexpr bool operator<(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator%=(TEnum &lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator+=(TEnum &lhs, TEnum rhs) noexcept
ALIB_EXPORT constexpr TEnum operator<<=(TEnum &lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr bool operator<=(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator-=(TEnum &lhs, TEnum rhs) noexcept
ALIB_EXPORT constexpr TEnum operator%(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator<<(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator-(TEnum lhs, TEnum rhs) noexcept
ALIB_EXPORT constexpr TEnum operator/(TEnum lhs, typename std::underlying_type< TEnum >::type rhs) noexcept
ALIB_EXPORT constexpr TEnum operator--(TEnum &arg) noexcept