ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
vmeta.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header file is part of module \alib_config of the \aliblong.
4///
5/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8#ifndef HPP_ALIB_CONFIG_VMETA
9#define HPP_ALIB_CONFIG_VMETA 1
10#pragma once
15
16// forward declarations
17namespace alib::config
18{
19 class Configuration;
20 class ConfigurationPlugin;
21 class Declaration;
22 class Variable;
23}
24
25namespace alib::config::detail {
26
27/// This struct is used as the reinterpretation type of generic pointers to ones reflecting
28/// the effective custom type of a configuration variable. While reinterpretation casts do not
29/// need such templated model, its use increases readability of the code.
30/// @tparam T The variable's data type.
31template<typename T> struct VData
32{
33 T custom; ///< The custom data that this object stores.
34
35 /// Reinterprets the <c>this</c>-pointer to a <c>VData<TReinterpret>*</c> and returns
36 /// member #custom.
37 /// @tparam TReinterpret The type to reinterpret to.
38 /// @return A reference to the custom data.
39 template<typename TReinterpret> inline TReinterpret& As()
40 { return reinterpret_cast< VData<TReinterpret>*>(this)->custom; }
41
42 /// Reinterprets the <c>this</c>-pointer to a <c>const VData<TReinterpret>*</c> and returns
43 /// member #custom.
44 /// @tparam TReinterpret The type to reinterpret to.
45 /// @return A const reference to the custom data.
46 template<typename TReinterpret> inline const TReinterpret& As() const
47 { return reinterpret_cast<const VData<TReinterpret>*>(this)->custom; }
48};
49
50/// Convenience definition for "invalid" data element which is used everywhere as a generic
51/// pointer type, which is reinterpreted when to the target type, when needed.
53
54} //namespace [alib::config::detail]
55namespace alib::config {
56
57/// Abstract, virtual struct which provides meta-information about types storable in the
58/// \b StringTree nodes of class \alib{config;Configuration}. A pointer to a singleton of this
59/// type is stored together with a reinterpreted pointer to the custom data record.
60///
61/// To register a custom data type with the configuration system, this type has to inherited and
62/// all methods implemented. It is recommended to define custom derived types using macro
63/// \ref ALIB_CONFIG_VARIABLE_DEFINE_TYPE.
64/// Derived types are to be registered with the configuration instance by invoking
65/// \alib{config;Configuration::RegisterType}.
66///
67/// @see Chapter \ref alib_config_types_custom of the Programmer's Manual of camp \alib_config.
68struct VMeta
69{
70 /// Virtual empty destructor.
71 virtual ~VMeta() {}
72
73 /// Abstract virtual method. Descendants need to return the type name they care of.<br>
74 /// Types declared with macro \ref ALIB_CONFIG_VARIABLE_DEFINE_TYPE implement this method
75 /// rightfully.
76 /// @return The type's name.
77 virtual String typeName() const = 0;
78
79 #if ALIB_DEBUG
80 /// Abstract virtual method. Descendants need to return the <c>std::type_info&</c> received with
81 /// <c>typeid()</c>. This method is available only in debug-compilations and is used to assert
82 /// that the correct types are read from declared variables.<br>
83 /// Types declared with macro \ref ALIB_CONFIG_VARIABLE_DEFINE_TYPE implement this method
84 /// rightfully.
85 /// @return The C++ type ID.
86 virtual const std::type_info& dbgTypeID() = 0;
87 #endif
88
89 /// Abstract virtual method. Descendants need to return '<c>sizeof(T)</c>', with \p{T} being
90 /// the custom type. Types declared with macro \ref ALIB_CONFIG_VARIABLE_DEFINE_TYPE implement
91 /// this method rightfully. With that, it is also asserted that the alignment of the custom
92 /// type is not greater than '<c>alignof(uint64_t)</c>', respectively not greater than
93 /// what is specified with compiler symbol \ref ALIB_MONOMEM_POOLALLOCATOR_DEFAULT_ALIGNMENT.
94 /// @return The size of the variable's content type.
95 virtual size_t size() = 0;
96
97 /// Abstract virtual method. Descendants need to construct a custom instance at the given
98 /// \p{memory}. This is done using a "placement-new" as follows:
99 ///
100 /// new (memory) MyType();
101 ///
102 /// The pool allocator is \b not provided to allocate the custom type itself (this was already
103 /// done before calling this method). Instead, it may be used to allocate members
104 /// in the custom type. It may also be passed to the instance for further use during it's
105 /// lifecycle. However, in this case chapter \ref alib_config_multithreading of the
106 /// Programmer's Manual has to be considered.
107 /// @param memory The pointer to the object of custom type.
108 /// @param pool The object pool of the configuration. May be used to dispose pool objects.
109 virtual void construct(void* memory, PoolAllocator& pool) = 0;
110
111 /// Abstract virtual method. Descendants need to destruct a custom instance at the given
112 /// \p{memory}. This is done by calling the destructor as follows:
113 ///
114 /// reinterpret_cast<MyTypeName*>(memory)->~MyTypeName();
115 ///
116 /// The pool allocator is \b not provided to free the custom type itself (this will be done
117 /// automatically right after the call to this method). Instead, it may be used to free
118 /// members of the type, which had been allocated during construction or during the use.
119 ///
120 /// \note
121 /// However, for most types included with \alib, for example \alib{AStringPA}, if used as a
122 /// member of the custom type, no special action need to be taken and it is sufficient to call
123 /// the destructor of the custom type. This is because these types take a copy of the pool on
124 /// construction and thus their destructor disposes allocated pool objects autonomously.
125 /// In other words, if only such members are used, then method \c construct has to be
126 /// implemented to pass the pool object to the members, but this method simply invokes the
127 /// destructor of the custom type as shown above.
128 ///
129 /// @param memory The place to construct the custom type at.
130 /// @param pool The object pool of the configuration. May be used to allocate pool objects.
131 virtual void destruct(void* memory, PoolAllocator& pool) = 0;
132
133
134 /// Abstract virtual method. Descendants need to implement this method and de-serialize
135 /// (aka parse) the custom type from the given string value.
136 /// \attention
137 /// Types declared with macro \ref ALIB_CONFIG_VARIABLE_DEFINE_TYPE only declare this method.
138 /// An implementation needs to be provided in a compilation unit.
139 ///
140 /// @param data A pointer to the user type which is to be initialized.
141 /// @param cfg The configuration that holds the variable.
142 /// @param escaper An escaper to be used to convert external strings to C++ native strings.
143 /// @param src The source string to parse. This may be assigned to a value of type
144 /// \alib{strings;TSubstring} which already provides simple parser mechanics.
145 /// Likewise, \alib{strings::util;TTokenizer} might be an easy helper to be
146 /// used for parsing.
147 virtual void imPort( detail::VDATA* data, Configuration& cfg, const StringEscaper& escaper,
148 const String& src ) =0;
149
150 /// Abstract virtual method. Descendants need to implement this method. It is invoked when a
151 /// variable is written into an external configuration source (in this case 'drain') or
152 /// otherwise needs to be serialized.
153 ///
154 /// Note that export functions are allowed to add \alib{NEW_LINE} codes into the export string.
155 /// This allows external configuration systems to nicely format their entries, in case those
156 /// are human-readable. See chapter \ref alib_config_external_custom of the Programmer's
157 /// Manual for more information.
158 ///
159 /// \attention
160 /// Types declared with macro \ref ALIB_CONFIG_VARIABLE_DEFINE_TYPE only declare this method.
161 /// An implementation needs to be provided in a compilation unit. Otherwise linking a software
162 /// fails.
163 ///
164 /// @param data A pointer to the user type which is to be serialized.
165 /// @param cfg The configuration that holds the variable.
166 /// @param escaper An escaper to be used to escape strings.
167 /// @param dest The destination string. Must not be reset prior writing, but appended.
168 ///
169 virtual void exPort( detail::VDATA* data, Configuration& cfg, const StringEscaper& escaper,
170 AString& dest ) =0;
171};
172
173#define ALIB_CONFIG_VARIABLE_DEFINE_TYPE( Namespace, CPPName,CfgTypeString) \
174namespace alib::config::detail { \
175struct VMeta_ ## CPPName : public VMeta \
176{ \
177 ALIB_API String typeName () const override { return CfgTypeString; } \
178ALIB_DBG(ALIB_API const std::type_info& dbgTypeID() override { return typeid(Namespace CPPName); } ) \
179 ALIB_API void construct(void* obj, PoolAllocator&) override { new (obj) Namespace CPPName(); } \
180 ALIB_API void destruct (void* obj, PoolAllocator&) override { reinterpret_cast<Namespace CPPName*>(obj)->~CPPName(); } \
181 ALIB_API size_t size () override { static_assert(alignof(Namespace CPPName) <= alib::PoolAllocator::MAX_ALIGNMENT); return (std::max)( sizeof(Namespace CPPName), sizeof(void*) ); } \
182 ALIB_API void imPort (VDATA*, Configuration&, const StringEscaper&, const String&) override;\
183 ALIB_API void exPort (VDATA*, Configuration&, const StringEscaper&, AString&) override;\
184};}
185
186#define ALIB_CONFIG_VARIABLE_DEFINE_TYPE_WITH_POOL_CONSTRUCTOR( Namespace, CPPName,CfgTypeString) \
187namespace alib::config::detail { \
188struct VMeta_ ## CPPName : public VMeta \
189{ \
190 ALIB_API String typeName () const override { return CfgTypeString; } \
191ALIB_DBG(ALIB_API const std::type_info& dbgTypeID() override { return typeid(Namespace CPPName); } ) \
192 ALIB_API void construct(void* obj, PoolAllocator& pool) override { new (obj) Namespace CPPName(pool); } \
193 ALIB_API void destruct (void* obj, PoolAllocator&) override { reinterpret_cast<Namespace CPPName*>(obj)->~CPPName(); } \
194 ALIB_API size_t size () override { static_assert(alignof(Namespace CPPName) <= alib::PoolAllocator::MAX_ALIGNMENT); return (std::max)( sizeof(Namespace CPPName), sizeof(void*) ); } \
195 ALIB_API void imPort (VDATA*, Configuration&, const StringEscaper&, const String&) override;\
196 ALIB_API void exPort (VDATA*, Configuration&, const StringEscaper&, AString&) override;\
197};}
198
199
200#define ALIB_CONFIG_VARIABLE_REGISTER_TYPE(CPPName) \
201 GetConfig().RegisterType<alib::config::detail::VMeta_ ## CPPName>();
202
203
204
205} // namespace [alib::config]
206
207// =================================================================================================
208// ==== Built-in Types
209// =================================================================================================
210
211namespace alib::config
212{
213 /// Variable content type used with boolean type <c>"B"</c>. When this type is imported,
214 /// the value is tried to be parsed with the tokens in
215 /// \alib{config;Configuration::BooleanTokens}. If successful, the index of the pair of
216 /// <c>true/false</c>-tokens is stored in field #TokenIndex. When exported back to
217 /// a configuration file or otherwise serialized or printed, then the right human-readable
218 /// term, corresponding to the potentially now different #Value is used.
219 struct Bool
220 {
221 /// The boolean value. Defaults to \c false.
222 bool Value = false;
223
224 /// The index in the \alib{config;Configuration::BooleanTokens;list of tokens} found when
225 /// imported from a string. Can also be set programmatically to force a certain output
226 /// "format". Defaults to \c -1 which indicates that the value was not parsed.
227 /// On exporting, when \c -1, index \c 0 is used.
228 int8_t TokenIndex = -1;
229
230 /// Assignment operator.
231 /// @param newValue The value to set.
232 /// @return The new value.
233 bool operator=(bool newValue) { return Value= newValue; }
234
235 /// Implicit cast operator to \c bool.
236 /// @return Returns the stored value.
237 operator bool() const {return Value;}
238 };
239
240
241 /// Type definition used with configuration variables of type <c>"SV,"</c>, which stores a
242 /// string array, imported by parsing a comma-separated string list.
243 ///
244 /// \attention
245 /// When exported, \alib{NEW_LINE} codes are added after each comma. This allows external
246 /// configuration systems to smoothly format longer lists of values. However, the
247 /// new line codes usually have to be detected with writing and eliminated on import.
248 /// Built-in type \alib{config;IniFile} processes such codes correctly.
250
251 /// Type definition used with configuration variables of type <c>"SV;"</c>, which stores a
252 /// string array, imported by parsing a string list separated by character <c>';'</c>.
253 ///
254 /// \attention
255 /// When exported, \alib{NEW_LINE} codes are added after each semicolon. This allows external
256 /// configuration systems to smoothly format longer lists of values. However, the
257 /// new line codes usually have to be detected with writing and eliminated on import.
258 /// Built-in type \alib{config;IniFile} processes such codes correctly.
260
261} // namespace [alib::config]
262
263
264
265
266#if !DOXYGEN
267namespace alib::config::detail {
268
269
270struct VMeta_integer : public VMeta
271{
272 ALIB_API String typeName() const override { return A_CHAR("I"); }
274 ALIB_API const std::type_info& dbgTypeID() override { return typeid(integer); }
275)
276 ALIB_API void construct(void* dest, PoolAllocator&) override { new (dest) integer(); }
277 ALIB_API void destruct (void* , PoolAllocator&) override {}
278 ALIB_API size_t size() override { return sizeof(integer); }
279 ALIB_API void imPort( VDATA*, Configuration&, const StringEscaper&, const String& ) override;
280 ALIB_API void exPort( VDATA*, Configuration&, const StringEscaper&, AString& ) override;
281};
282
283struct VMeta_float : public VMeta
284{
285 ALIB_API String typeName() const override { return A_CHAR("F"); }
287 ALIB_API const std::type_info& dbgTypeID() override { return typeid(double); }
288)
289 ALIB_API void construct(void* dest, PoolAllocator&) override { new (dest) double(); }
290 ALIB_API void destruct (void* , PoolAllocator&) override {}
291 ALIB_API size_t size() override { return sizeof(double); }
292 ALIB_API void imPort( VDATA*, Configuration&, const StringEscaper&, const String& ) override;
293 ALIB_API void exPort( VDATA*, Configuration&, const StringEscaper&, AString& ) override;
294};
295
296struct VMeta_String : public VMeta
297{
298 ALIB_API String typeName() const override { return A_CHAR("S"); }
300 ALIB_API const std::type_info& dbgTypeID() override { return typeid(AStringPA); }
301)
302 ALIB_API void construct(void* dest, PoolAllocator& pool) override
303 { new (dest) AStringPA(pool); }
304 ALIB_API void destruct (void* dest, PoolAllocator&) override
305 { reinterpret_cast<AStringPA*>(dest)->~AStringPA(); }
306 ALIB_API size_t size() override { return sizeof(AStringPA); }
307 ALIB_API void imPort( VDATA*, Configuration&, const StringEscaper&, const String& ) override;
308 ALIB_API void exPort( VDATA*, Configuration&, const StringEscaper&, AString& ) override;
309};
310
311} //namespace [alib::config::detail]
312
313
315ALIB_CONFIG_VARIABLE_DEFINE_TYPE( alib::boxing::, Box , A_CHAR("BOX") )
317ALIB_CONFIG_VARIABLE_DEFINE_TYPE_WITH_POOL_CONSTRUCTOR( alib::config::, StringVectorComma , A_CHAR("SV,") )
318ALIB_CONFIG_VARIABLE_DEFINE_TYPE_WITH_POOL_CONSTRUCTOR( alib::config::, StringVectorSemicolon, A_CHAR("SV;") )
319
320
321#endif // ALIB_DOX
322#endif // HPP_ALIB_CONFIG_VMETA
323
#define ALIB_CONFIG_VARIABLE_DEFINE_TYPE_WITH_POOL_CONSTRUCTOR(Namespace, CPPName, CfgTypeString)
Definition vmeta.hpp:186
#define A_CHAR(STR)
#define ALIB_CONFIG_VARIABLE_DEFINE_TYPE(Namespace, CPPName, CfgTypeString)
Definition vmeta.hpp:173
#define ALIB_API
Definition alib.hpp:639
#define ALIB_DBG(...)
Definition alib.hpp:390
Definition alib.cpp:69
config::Configuration Configuration
Type alias in namespace alib.
strings::util::TStringVector< character, PoolAllocator > StringVectorPA
Type alias in namespace alib.
config::Declaration Declaration
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
config::Variable Variable
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273
strings::TAString< character, PoolAllocator > AStringPA
Type alias in namespace alib.
Definition astringpa.hpp:45
bool operator=(bool newValue)
Definition vmeta.hpp:233
bool Value
The boolean value. Defaults to false.
Definition vmeta.hpp:222
virtual const std::type_info & dbgTypeID()=0
virtual void construct(void *memory, PoolAllocator &pool)=0
virtual String typeName() const =0
virtual ~VMeta()
Virtual empty destructor.
Definition vmeta.hpp:71
virtual void imPort(detail::VDATA *data, Configuration &cfg, const StringEscaper &escaper, const String &src)=0
virtual size_t size()=0
virtual void exPort(detail::VDATA *data, Configuration &cfg, const StringEscaper &escaper, AString &dest)=0
virtual void destruct(void *memory, PoolAllocator &pool)=0
const TReinterpret & As() const
Definition vmeta.hpp:46
TReinterpret & As()
Definition vmeta.hpp:39
T custom
The custom data that this object stores.
Definition vmeta.hpp:33