ALib C++ Library
Library Version: 2510 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 \ref mainpage_license "Boost Software 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 \alib{boxing;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 surpass 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 cased using
32/// 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 \implude{Boxing.StdFunctors}
37/// as documented with namespace #alib::boxing::compatibility::std.
38///
39/// ## Friends ##
40/// class \alib{boxing;Box}
41///
42/// @see With the inclusion of the module \alib_enumrecords in the \alibbuild, the namespace functions
43/// \alib{boxing;GetRecord} and \alib{boxing;TryRecord} become available, which receive an
44/// 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
57 /// Implicit constructor, which accepts arbitrary elements of scoped or non-scoped enum types.
58 ///
59 /// @tparam TEnum The external (user specific) enumeration type.
60 /// @param element The external (user specific) enumeration element.
61 template<typename TEnum>
62 requires std::is_enum<TEnum>::value
63 constexpr Enum( TEnum element )
64 : Box( element ) {}
65
66 /// This is a shortcut to \alib{boxing;Box::Unbox;Box::Unbox<TEnum>()} to retrieve the
67 /// original enum element in a type-safe way.
68 ///
69 /// Before invoking this, the boxed type can be checked with #IsType. If the wrong type
70 /// is tried to be received, an \alib assertion is raised.
71 ///
72 /// @tparam TEnum The external (user specific) enumeration type.
73 /// @return The underlying integral value of the encapsulated enum element.
74 template<typename TEnum>
75 requires std::is_enum<TEnum>::value
76 TEnum Get() const { return Unbox<TEnum>(); }
77
78 /// Returns the underlying integral value of the original enum element cast to type
79 /// \alib{integer}.
80 ///
81 /// \note
82 /// Boxed enum element values are always
83 /// \ref alib_boxing_enums_integer "stored as type integer", regardless of the
84 /// underlying type of the enumeration.
85 ///
86 /// @return The underlying integral value.
88 {
89 return data.Integrals.Array[0];
90 }
91
92 /// Comparison operator.
93 ///
94 /// @param rhs The right hand side argument of the comparison.
95 /// @return \c true if this object equals \p{rhs}, \c false otherwise.
96 bool operator==(const Enum& rhs) const
97 {
98 return this->CastToBox() == rhs.CastToBox();
99 }
100
101 /// Comparison operator.
102 ///
103 /// @param rhs The right hand side argument of the comparison.
104 /// @return \c true if this object does not equal \p{rhs}, \c false otherwise.
105 bool operator!=(const Enum& rhs) const
106 {
107 return this->CastToBox() != rhs.CastToBox();
108 }
109
110 #if DOXYGEN
111 /// Imports \c protected base class's method \alib{boxing;Box::TypeID}.
112 /// @return The \c std::type_info of the mapped \c enum type.
113 using Box::TypeID;
114
115 /// Imports \c protected base class's method \alib{boxing;Box::Hashcode}.
116 /// @return A hashcode for the boxed enum type and value.
117 using Box::Hashcode;
118 #else
119 using Box::TypeID;
120 using Box::Hashcode;
121 #endif
122
123 /// This method casts an instance of this class to a reference of base class \b Box.
124 /// To hide the bases class's interface, this class inherits class \b Box only as
125 /// a \c protected base. With this method, this "artificial limitation " (its a design decision)
126 /// is lifted.
127 ///
128 /// @return A mutable reference to this object.
130 {
131 return static_cast<Box&>(*this);
132 }
133
134 /// Same as overloaded version, but returns a \c const reference and consequently this method
135 /// is declared\c const itself.
136 ///
137 /// @return A constant reference to this object.
138 const Box& CastToBox() const
139 {
140 return static_cast<const Box&>(*this);
141 }
142
143
144 /// Checks if this instance has an enum element of type \p{TEnum} stored.<br>
145 /// This method is an inlined, simple alias for \c protected base class's method
146 /// \alib{boxing;Box::IsType}.
147 ///
148 ///
149 /// @tparam TEnum The external (user specific) enumeration type.
150 /// @return \c true if the encapsulated enum type of type \p{TEnum}, otherwise \c false.
151 template<typename TEnum>
152 requires std::is_enum<TEnum>::value
153 bool IsEnumType() const { return Box::IsType<TEnum>(); }
154
155 /// Comparison operator with enum elements.
156 ///
157 /// @tparam TEnum The external (user specific) enumeration type.
158 /// @param rhs The right hand side argument of the comparison.
159 /// @return \c true if this object equals \p{rhs}, \c false otherwise.
160 template<typename TEnum>
161 requires std::is_enum<TEnum>::value
162 bool operator==(TEnum rhs) const
163 {
164 return Integral() == static_cast<typename std::underlying_type<TEnum>::type>( rhs )
165 && TypeID() == typeid( TEnum );
166 }
167
168 /// Comparison operator with enum elements.
169 ///
170 /// @tparam TEnum The external (user specific) enumeration type.
171 /// @param rhs The right hand side argument of the comparison.
172 /// @return \c true if this object does not equal \p{rhs}, \c false otherwise.
173 template<typename TEnum>
174 requires std::is_enum<TEnum>::value
175 bool operator!=(TEnum rhs) const
176 {
177 return Integral() != static_cast<typename std::underlying_type<TEnum>::type>( rhs )
178 || TypeID() != typeid( TEnum );
179 }
180
181 /// Comparison operator with another \b 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 {
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]
214
215
216
Placeholder data
The data that we encapsulate.
Definition box.inl:40
bool IsType() const
TValue Unbox() const
Definition box.inl:635
const std::type_info & TypeID() const
Definition box.inl:827
Box() noexcept
Definition box.inl:225
ALIB_DLL size_t Hashcode() const
#define ALIB_EXPORT
Definition alib.inl:488
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
boxing::Enum Enum
Type alias in namespace alib.
Definition enum.inl:211
bool operator==(TEnum rhs) const
Definition enum.inl:162
bool operator==(const Enum &rhs) const
Definition enum.inl:96
integer Integral() const
Definition enum.inl:87
const Box & CastToBox() const
Definition enum.inl:138
bool operator<(Enum const &rhs) const
Definition enum.inl:198
Box & CastToBox()
Definition enum.inl:129
constexpr Enum(TEnum element)
Definition enum.inl:63
Enum()
Default constructor.
Definition enum.inl:53
const std::type_info & TypeID() const
Definition box.inl:827
bool IsEnumType() const
Definition enum.inl:153
bool operator!=(const Enum &rhs) const
Definition enum.inl:105
bool operator!=(TEnum rhs) const
Definition enum.inl:175
TEnum Get() const
Definition enum.inl:76