ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
enum.inl
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/// \emoji :copyright: 2013-2025 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 run-time type-information is added.
17/// Having the "original" element stored in protected base class \b Box, has the following
18/// advantages:
19///
20/// \note
21/// The implementation of this class, by deriving from class \b 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 \b 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{
48 #if !DOXYGEN
49 friend class Box;
50 #endif
51
52 /// Default constructor.
54 : Box(nullptr) {}
55
56 /// Implicit constructor, which accepts arbitrary elements of scoped or non-scoped enum types.
57 ///
58 /// @tparam TEnum The external (user specific) enumeration type.
59 /// @param element The external (user specific) enumeration element.
60 template<typename TEnum>
61 requires std::is_enum<TEnum>::value
62 constexpr Enum( TEnum element )
63 : Box( element ) {}
64
65 /// This is a shortcut to #"Box::Unbox;Box::Unbox<TEnum>()" to retrieve the
66 /// original enum element in a type-safe way.
67 ///
68 /// Before invoking this, the boxed type can be checked with #"IsType". If the wrong type
69 /// is tried to be received, an \alib_assertion is raised.
70 ///
71 /// @tparam TEnum The external (user specific) enumeration type.
72 /// @return The underlying integral value of the encapsulated enum element.
73 template<typename TEnum>
74 requires std::is_enum<TEnum>::value
75 TEnum Get() const { return Unbox<TEnum>(); }
76
77 /// Returns the underlying integral value of the original enum element cast to type
78 /// \p{TIntegral}.
79 ///
80 /// \note
81 /// Boxed enum element values are always
82 /// #"alib_boxing_enums_integer;stored as type integer", regardless of the
83 /// underlying type of the enumeration.
84 ///
85 /// @tparam TIntegral The requested width of the return type. Defaults to #"lang::integer".
86 /// @return The underlying integral value.
87 template<typename TIntegral= integer>
88 TIntegral Integral() const { return static_cast<TIntegral>(data.Integrals.Array[0]); }
89
90 /// Comparison operator.
91 ///
92 /// @param rhs The right-hand side argument of the comparison.
93 /// @return \c true if this object equals \p{rhs}, \c false otherwise.
94 bool operator==(const Enum& rhs) const {
95 return Data().VoidP == rhs.Data().VoidP
96 && TypeID() == rhs.TypeID();
97 }
98
99 /// Comparison operator.
100 ///
101 /// @param rhs The right-hand side argument of the comparison.
102 /// @return \c true if this object does not equal \p{rhs}, \c false otherwise.
103 bool operator!=(const Enum& rhs) const { return !((*this) == rhs); }
104
105 #if DOXYGEN
106 /// Imports \c protected base class's method #"Box::TypeID".
107 /// @return The \c std::type_info of the mapped \c enum type.
108 using Box::TypeID;
109
110 /// Imports \c protected base class's method #"Box::Hashcode".
111 /// @return A hashcode for the boxed enum type and value.
112 using Box::Hashcode;
113 #else
114 using Box::TypeID;
115 using Box::Hashcode;
116 #endif
117
118 /// This method casts an instance of this class to a reference of base class \b Box.
119 /// To hide the bases class's interface, this class inherits class \b Box only as
120 /// a \c protected base. With this method, this "artificial limitation " (its a design decision)
121 /// is lifted.
122 ///
123 /// @return A mutable reference to this object.
124 Box& CastToBox() { return static_cast<Box&>(*this); }
125
126 /// Same as overloaded version, but returns a \c const reference and consequently this method
127 /// is declared\c const itself.
128 ///
129 /// @return A constant reference to this object.
130 const Box& CastToBox() const { return static_cast<const Box&>(*this); }
131
132
133 /// Checks if this instance has an enum element of type \p{TEnum} stored.<br>
134 /// This method is an inlined, simple alias for \c protected base class's method
135 /// #"Box::IsType".
136 ///
137 ///
138 /// @tparam TEnum The external (user specific) enumeration type.
139 /// @return \c true if the encapsulated enum type of type \p{TEnum}, otherwise \c false.
140 template<typename TEnum>
141 requires std::is_enum<TEnum>::value
142 bool IsEnumType() const { return Box::IsType<TEnum>(); }
143
144 /// \note This method overrides the otherwise protected inherited method of class \b Box
145 /// but also changes its meaning slightly. Here, no boxing function is called, instead
146 /// it is checked whether the box is set at all. Specifically, this method returns
147 /// <c>Box::IsType<void>()</c>.
148 ///
149 /// @return \c false if this object contains an enumeration element, \c true otherwise.
150 bool IsNull() const { return IsType<void>(); }
151
152 /// Returns the negated result #"IsNull".
153 /// @return \c true if this object contains with an enumeration element, \c false otherwise.
155 bool IsNotNull() const { return !IsNull(); }
156
157
158 /// Comparison operator with enum elements.
159 ///
160 /// @tparam TEnum The external (user specific) enumeration type.
161 /// @param rhs The right-hand side argument of the comparison.
162 /// @return \c true if this object equals \p{rhs}, \c false otherwise.
163 template<typename TEnum>
164 requires std::is_enum<TEnum>::value
165 bool operator==(TEnum rhs) const {
166 return Integral() == static_cast<typename std::underlying_type<TEnum>::type>( rhs )
167 && TypeID() == typeid( TEnum );
168 }
169
170 /// Comparison operator with enum elements.
171 ///
172 /// @tparam TEnum The external (user specific) enumeration type.
173 /// @param rhs The right-hand side argument of the comparison.
174 /// @return \c true if this object does not equal \p{rhs}, \c false otherwise.
175 template<typename TEnum>
176 requires std::is_enum<TEnum>::value
177 bool operator!=(TEnum rhs) const {
178 return Integral() != static_cast<typename std::underlying_type<TEnum>::type>( rhs )
179 || TypeID() != typeid( TEnum );
180 }
181
182 /// Comparison operator with another \b Enum object.
183 /// The sort order is primarily determined by the enum types that were boxed.
184 /// If those are the same, then the underlying integral value of the enum elements is compared.
185 ///
186 /// This leads to a nested sort order, with the type information being the outer order and
187 /// the integral value of the enum being the inner one.
188 ///
189 /// \note
190 /// It is a matter of the compiler how the outer sort of types is performed and thus this
191 /// cannot be determined by the user code.
192 ///
193 ///
194 /// @param rhs The right-hand side argument of the comparison.
195 /// @return If the encapsulated type of this instance is the same as that of \p{rhs}, this
196 /// methods returns \c true if #".Integral()" of this object is smaller than the one of
197 /// \p{rhs} and otherwise \c false. If the types are not the same, than the result is
198 /// dependent on the tool chain (compiler) used for compiling \alib.
199 bool operator< (Enum const& rhs) const {
200 return ( std::type_index( TypeID() )
201 < std::type_index(rhs.TypeID() ) )
202 || ( TypeID() == rhs.TypeID()
203 && Integral() < rhs.Integral() );
204 }
205
206}; // class Enum
207
208} // namespace alib[::boxing]
209
210/// Type alias in namespace \b alib.
212
213} // namespace [alib]
#define ALIB_DLL
Definition alib.inl:573
#define ALIB_EXPORT
Definition alib.inl:562
Placeholder data
The data that we encapsulate.
Definition box.inl:40
size_t Hashcode() const
bool IsType() const
const std::type_info & TypeID() const
Definition box.inl:766
const Placeholder & Data() const
Definition box.inl:681
Box() noexcept
Definition box.inl:229
boxing::Enum Enum
Type alias in namespace alib.
Definition enum.inl:211
bool operator==(const Enum &rhs) const
Definition enum.inl:94
bool IsNull() const
Definition enum.inl:150
bool operator!=(TEnum rhs) const
Definition enum.inl:177
TIntegral Integral() const
Definition enum.inl:88
bool IsNotNull() const
Definition enum.inl:155
bool IsEnumType() const
Definition enum.inl:142
const Box & CastToBox() const
Definition enum.inl:130
bool operator<(Enum const &rhs) const
Definition enum.inl:199
Box & CastToBox()
Definition enum.inl:124
Enum()
Default constructor.
Definition enum.inl:53
constexpr Enum(TEnum element)
Definition enum.inl:62
const std::type_info & TypeID() const
Definition box.inl:766
bool operator!=(const Enum &rhs) const
Definition enum.inl:103
bool operator==(TEnum rhs) const
Definition enum.inl:165
TEnum Get() const
Definition enum.inl:75
void * VoidP
Just a void pointer.