ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
enum.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_boxing of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace boxing {
9
10//==================================================================================================
11/// This class is useful to pass and accept enum values of arbitrary C++ scoped enum types.
12/// Based on class #"Box", all interfaces are inherited, including type guessing and
13/// unboxing.
14///
15/// In the constructor, enum elements of an arbitrary type are accepted.
16/// The element's underlying integral value is boxed, and thus runtime type-information is added.
17/// Having the "original" element stored in protected base class #"%Box", has the following
18/// advantages:
19///
20/// \note
21/// The implementation of this class, by deriving from class #"%Box", introduces a
22/// small memory overhead (usually 8 bytes per instance on 64-bit system), in respect to a
23/// possible alternative "direct" implementation. This is due to the fact that boxing allows
24/// one-dimensional array types to be boxed as well as scalar types - which is never the case
25/// with this class.<br>
26/// But the advantages of doing so certainly surpasses this small drawback.
27///
28/// \note
29/// Class #"%Box" is inherited \c protected instead of public, to hide bigger portions of
30/// the base class's interface. While some functions are explicitly made visible with
31/// keyword \c using, for others, instances of this class have to be cast first.
32/// Casting is done with overloaded methods #"CastToBox".
33///
34/// ## Functors In Namespace std ##
35/// Functors <c>std::hash</c>, <c>std::equal_to</c> and <c>std::less</c> are specialized for this
36/// type with the inclusion of the header-file #"F;ALib.Boxing.StdFunctors.H"
37/// as documented with namespace #"alib::boxing;2"::compatibility::std.
38///
39/// ## Friends ##
40/// class #"Box"
41///
42/// @see With the inclusion of the module \alib_enumrecords in the \alibbuild, the namespace
43/// functions #"enumrecords::GetRecord" and #"enumrecords::TryRecord" become available, which
44/// receive an enum record for a value of this class.
45//==================================================================================================
46struct Enum : protected Box {
47 #if !DOXYGEN
48 friend class Box;
49 #endif
50
51 /// Default constructor.
53 : Box(nullptr) {}
54
55 /// Implicit constructor, which accepts arbitrary elements of scoped or non-scoped enum types.
56 ///
57 /// @tparam TEnum The external (user specific) enumeration type.
58 /// @param element The external (user specific) enumeration element.
59 template<typename TEnum>
60 requires std::is_enum<TEnum>::value
61 constexpr Enum( TEnum element )
62 : Box( element ) {}
63
64 /// This is a shortcut to #"Box::Unbox;Box::Unbox<TEnum>()" to retrieve the
65 /// original enum element in a type-safe way.
66 ///
67 /// Before invoking this, the boxed type can be checked with #"IsType". If the wrong type
68 /// is tried to be received, an \alib_assertion is raised.
69 ///
70 /// @tparam TEnum The external (user specific) enumeration type.
71 /// @return The underlying integral value of the encapsulated enum element.
72 template<typename TEnum>
73 requires std::is_enum<TEnum>::value
74 TEnum Get() const { return Unbox<TEnum>(); }
75
76 /// Returns the underlying integral value of the original enum element cast to type
77 /// \p{TIntegral}.
78 ///
79 /// \note
80 /// Boxed enum element values are always
81 /// #"alib_boxing_enums_integer;stored as type integer", regardless of the
82 /// underlying type of the enumeration.
83 ///
84 /// @tparam TIntegral The requested width of the return type. Defaults to #"lang::integer".
85 /// @return The underlying integral value.
86 template<typename TIntegral= integer>
87 TIntegral Integral() const { return static_cast<TIntegral>(data.Integrals.Array[0]); }
88
89 /// Comparison operator.
90 ///
91 /// @param rhs The right-hand side argument of the comparison.
92 /// @return \c true if this object equals \p{rhs}, \c false otherwise.
93 bool operator==(const Enum& rhs) const {
94 return Data().VoidP == rhs.Data().VoidP
95 && TypeID() == rhs.TypeID();
96 }
97
98 /// Comparison operator.
99 ///
100 /// @param rhs The right-hand side argument of the comparison.
101 /// @return \c true if this object does not equal \p{rhs}, \c false otherwise.
102 bool operator!=(const Enum& rhs) const { return !((*this) == rhs); }
103
104 #if DOXYGEN
105 /// Imports \c protected base class's method #"Box::TypeID".
106 /// @return The \c std::type_info of the mapped \c enum type.
107 using Box::TypeID;
108
109 /// Imports \c protected base class's method #"Box::Hashcode".
110 /// @return A hashcode for the boxed enum type and value.
111 using Box::Hashcode;
112 #else
113 using Box::TypeID;
114 using Box::Hashcode;
115 #endif
116
117 /// This method casts an instance of this class to a reference of base class #"%Box".
118 /// To hide the bases class's interface, this class inherits class #"%Box" only as
119 /// a \c protected base. With this method, this "artificial limitation " (its a design decision)
120 /// is lifted.
121 ///
122 /// @return A mutable reference to this object.
123 Box& CastToBox() { return static_cast<Box&>(*this); }
124
125 /// Same as overloaded version, but returns a \c const reference and consequently this method
126 /// is declared\c const itself.
127 ///
128 /// @return A constant reference to this object.
129 const Box& CastToBox() const { return static_cast<const Box&>(*this); }
130
131
132 /// Checks if this instance has an enum element of type \p{TEnum} stored.<br>
133 /// This method is an inlined, simple alias for \c protected base class's method
134 /// #"Box::IsType".
135 ///
136 ///
137 /// @tparam TEnum The external (user specific) enumeration type.
138 /// @return \c true if the encapsulated enum type of type \p{TEnum}, otherwise \c false.
139 template<typename TEnum>
140 requires std::is_enum<TEnum>::value
141 bool IsEnumType() const { return Box::IsType<TEnum>(); }
142
143 /// \note This method overrides the otherwise protected inherited method of class #"%Box"
144 /// but also changes its meaning slightly. Here, no boxing function is called, instead
145 /// it is checked whether the box is set at all. Specifically, this method returns
146 /// <c>Box::IsType<void>()</c>.
147 ///
148 /// @return \c false if this object contains an enumeration element, \c true otherwise.
149 bool IsNull() const { return IsType<void>(); }
150
151 /// Returns the negated result #"IsNull".
152 /// @return \c true if this object contains with an enumeration element, \c false otherwise.
154 bool IsNotNull() const { return !IsNull(); }
155
156
157 /// Comparison operator with enum elements.
158 ///
159 /// @tparam TEnum The external (user specific) enumeration type.
160 /// @param rhs The right-hand side argument of the comparison.
161 /// @return \c true if this object equals \p{rhs}, \c false otherwise.
162 template<typename TEnum>
163 requires std::is_enum<TEnum>::value
164 bool operator==(TEnum rhs) const {
165 return Integral() == static_cast<typename std::underlying_type<TEnum>::type>( rhs )
166 && TypeID() == typeid( TEnum );
167 }
168
169 /// Comparison operator with enum elements.
170 ///
171 /// @tparam TEnum The external (user specific) enumeration type.
172 /// @param rhs The right-hand side argument of the comparison.
173 /// @return \c true if this object does not equal \p{rhs}, \c false otherwise.
174 template<typename TEnum>
175 requires std::is_enum<TEnum>::value
176 bool operator!=(TEnum rhs) const {
177 return Integral() != static_cast<typename std::underlying_type<TEnum>::type>( rhs )
178 || TypeID() != typeid( TEnum );
179 }
180
181 /// Comparison operator with another #"%Enum" object.
182 /// The sort order is primarily determined by the enum types that were boxed.
183 /// If those are the same, then the underlying integral value of the enum elements is compared.
184 ///
185 /// This leads to a nested sort order, with the type information being the outer order and
186 /// the integral value of the enum being the inner one.
187 ///
188 /// \note
189 /// It is a matter of the compiler how the outer sort of types is performed and thus this
190 /// cannot be determined by the user code.
191 ///
192 ///
193 /// @param rhs The right-hand side argument of the comparison.
194 /// @return If the encapsulated type of this instance is the same as that of \p{rhs}, this
195 /// methods returns \c true if #".Integral()" of this object is smaller than the one of
196 /// \p{rhs} and otherwise \c false. If the types are not the same, than the result is
197 /// dependent on the tool chain (compiler) used for compiling \alib.
198 bool operator< (Enum const& rhs) const {
199 return ( std::type_index( TypeID() )
200 < std::type_index(rhs.TypeID() ) )
201 || ( TypeID() == rhs.TypeID()
202 && Integral() < rhs.Integral() );
203 }
204
205}; // class Enum
206
207} // namespace alib[::boxing]
208
209/// Type alias in namespace #"%alib".
211
212} // namespace [alib]
#define ALIB_DLL
#define ALIB_EXPORT
Placeholder data
The data that we encapsulate.
Definition box.hpp:39
size_t Hashcode() const
bool IsType() const
const std::type_info & TypeID() const
Definition box.hpp:759
const Placeholder & Data() const
Definition box.hpp:674
Box() noexcept
Definition box.hpp:222
DOXYGEN.
Definition box.cpp:17
Definition alox.cpp:14
boxing::Enum Enum
Type alias in namespace #"%alib".
Definition enum.hpp:210
bool operator==(const Enum &rhs) const
Definition enum.hpp:93
bool IsNull() const
Definition enum.hpp:149
bool operator!=(TEnum rhs) const
Definition enum.hpp:176
TIntegral Integral() const
Definition enum.hpp:87
bool IsNotNull() const
Definition enum.hpp:154
bool IsEnumType() const
Definition enum.hpp:141
const Box & CastToBox() const
Definition enum.hpp:129
bool operator<(Enum const &rhs) const
Definition enum.hpp:198
Box & CastToBox()
Definition enum.hpp:123
Enum()
Default constructor.
Definition enum.hpp:52
constexpr Enum(TEnum element)
Definition enum.hpp:61
const std::type_info & TypeID() const
Definition box.hpp:759
bool operator!=(const Enum &rhs) const
Definition enum.hpp:102
bool operator==(TEnum rhs) const
Definition enum.hpp:164
TEnum Get() const
Definition enum.hpp:74
void * VoidP
Just a void pointer.