ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
variabledecl.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_VARIABLEDECL
9#define HPP_ALIB_CONFIG_VARIABLEDECL 1
10
11#if !defined (HPP_ALIB_CONFIG_PRIORITIES)
13#endif
14
15#if !defined (HPP_ALIB_ENUMS_BITWISE)
16# include "alib/enums/bitwise.hpp"
17#endif
18
19#if !defined (HPP_ALIB_LANG_RESOURCES_RESOURCES)
21#endif
22
23ALIB_ASSERT_MODULE(CONFIGURATION)
24
25namespace alib { namespace config {
26
27// Forward declarations
28struct VariableDecl;
29
30/** ************************************************************************************************
31 * Denotes hints for formatting variables when storing in external configuration files
32 **************************************************************************************************/
33enum class FormatHints
34{
35 /* No hints **/
36 None = 0 ,
37
38 /* Write each argument in a new line **/
39 MultiLine = 1 << 0,
40
41 /* Suppress spaces around the delimiter (only used in single line mode) **/
42 NoDelimSpaces = 1 << 1,
43
44 /* This and upward bits are reserved for custom plug-ins **/
45 Custom = 1 << 16,
46};
47
48
49/** ************************************************************************************************
50 * A data record used to declare an \alib{config;Variable;ALib Configuration Variable}.
51 *
52 * All fields (except #Delim) support placeholders \c "%1", \c "%2" ... \c "%N", which are
53 * replaced with the constructor of class \b %Variable and method
54 * \ref alib::config::Variable::Declare "Variable::Declare".
55 * This allows to define a series of variables whose category, name, description and value is
56 * dependent on run-time information.
57 *
58 * Objects of class \b %Variable can be constructed and existing objects can be reused by invoking
59 * \ref alib::config::Variable::Declare "Variable::Declare". Both, construction and
60 * re-declaration of variables, use objects of this type.
61 *
62 * While variables can also be declared by setting their attributes "manually", it is recommended
63 * to declare all external configuration variables in a central place, this type.<br>
64 *
65 * In this C++ implementation of \alib, this class can be created from elements of enum types.
66 * For this, the concept of \ref alib_enums_records "ALib Enum Records" is used.
67 * The record associated with an enum element used for construction must be of this type itself!
68 * Consequently, equipping enum type \b MyType is performed like this:
69 *
70 * ALIB_ENUMS_ASSIGN_RECORD( MyEnum, alib::config::VariableDecl )
71 *
72 * Besides defining the enum record type, a custom enum has to have a specialization of
73 * type \alib{lang::resources;T_Resourced}. The reason for this is that enum records of this type
74 * do load fields #DefaultValue and #Comments <em>indirectly</em> from resources by
75 * adding postfixes <b>_D</b>, respectively <b>_C</b> to the variable's resource name along with
76 * the variable's underlying enumeration element's integral value.
77 * This way, both values are loaded from separated resource strings, what has the following
78 * advantages:
79 * - The values may contain the separation character used.
80 * - The values can be manipulated within the (externalized) resources more easily.
81 *
82 * With this - and the corresponding resource data! - in place, elements of custom enum type can be
83 * used to declare configuration variables by passing them to one of following constructors and
84 * methods:
85 * - \alib{config;VariableDecl::VariableDecl(TEnum)}
86 * - \alib{config;Variable::Variable(TEnum)}
87 * - \alib{config;Variable::Variable(TEnum);Variable::Variable(TEnum,const StringTypes&...)}
88 * - \alib{config;Variable::Declare(TEnum)}
89 * - \alib{config;Variable::Declare(TEnum);Variable::Declare(TEnum,const StringTypes&...)}
90 *
91 * The resource data has to provide six values in the following order:
92 * 1. The custom integral enum value (this is mandatory with every resourced enum record).
93 * 2. Field #Category.
94 * 3. Base class's field \alib{enums;ERSerializable::EnumElementName}.
95 * \note Field \alib{enums;ERSerializable::MinimumRecognitionLength} is not read from the string,
96 * but set to fixed value \c 0.
97 * 4. Field #Delim.
98 * 5. Field #FormatAttrAlignment.
99 * 6. Field #FmtHints.
100 *
101 * As already noted above, fields #DefaultValue and #Comments can be defined in two
102 * separate resource strings named like the variable's resource itself with concatenated postfixes
103 * <b>_D</b>, respectively <b>_C</b> and the variable's underlying enumeration element's integral
104 * value. Both resources are optional and not mandatory to be existent.
105 *
106 * A sample of variable resources is given with the
107 * \ref alib_ns_strings_propertyformatter_map_sample "documentation of class PropertyFormatter".
108 **************************************************************************************************/
110{
111 /** Defaulted constructor leaving the declaration undefined. */
112 VariableDecl() noexcept = default;
113
114 /** The value for field \alib{config;Variable::Category}. */
116
117 /** The value for field \alib{config;Variable::DefaultValue}.
118 * \note
119 * If TMP struct \alib{lang::resources;T_Resourced} is specialized for an enumeration,
120 * this field is interpreted as a resource name to load the description from. */
122
123 /** The value for field \alib{config;Variable::Delim}. */
125
126 /** The value for field \alib{config;Variable::FormatAttrAlignment}. */
128
129 /** The value for field \alib{config;Variable::FmtHints}. */
131
132 /** The value for field \alib{config;Variable::Comments}.
133 * \note
134 * If TMP struct \alib{lang::resources;T_Resourced} is specialized for an enumeration,
135 * this field is interpreted as a resource name to load the description from. */
137
138 /** ********************************************************************************************
139 * Constructor usually used with static variable declarations (declarations that are not
140 * using enumeration types associated with \ref alib_enums_records "ALib Enum Records" of this
141 * type).
142 *
143 * If used however to define an enum record during bootstrap of a software (by user code
144 * that omits the preferred option of parsing resourced strings to create such records), then
145 * each parameter of type \b String passed, has to be of "static nature".
146 * This means, that string buffers and their contents are deemed to survive the life-cycle of
147 * an application. Usually, C++ string literals are passed in such situation.
148 *
149 * @param category Value for field \alib{config;Variable::Category}.
150 * @param name Value for field \alib{config;Variable::Name}.
151 * @param defaultValue Value for field \alib{config;Variable::DefaultValue}.
152 * @param delim Value for field \alib{config;Variable::Delim}.
153 * @param formatAttrAlignment Value for field \alib{config;Variable::FormatAttrAlignment}.
154 * @param formatHints Value for field \alib{config;Variable::FmtHints}.
155 * @param comments Value for field \alib{config;Variable::Comments}.
156 **********************************************************************************************/
157 VariableDecl( const String& category,
158 const String& name,
159 const String& defaultValue,
160 character delim,
161 const String& formatAttrAlignment,
162 FormatHints formatHints,
163 const String& comments )
164 : ERSerializable (name )
165 , Category (category )
166 , DefaultValue (defaultValue )
167 , Delim (delim )
168 , FormatAttrAlignment(formatAttrAlignment)
169 , FmtHints (formatHints )
170 , Comments (comments )
171 {}
172
173 /**
174 * Implementation of \alib{enums;EnumRecordPrototype::Parse}.
175 * \note Field \alib{enums;ERSerializable::MinimumRecognitionLength} is not read from the string,
176 * but set to fixed value \c 0.
177 *
178 */
180 void Parse();
181
182#if defined(ALIB_DOX)
183 /** ********************************************************************************************
184 * Constructor that accepts an element of a C++ enum type equipped with
185 * \ref alib_enums_records "ALib Enum Records" of this type (\alib{config;VariableDecl}).
186 * that contains the declaration data. A copy of the enum record is created.
187 *
188 * In the case that a specialization of type \alib{lang::resources;T_Resourced} exists for the given
189 * enumeration type, fields #DefaultValue and #Comments are interpreted as a resource name
190 * and are loaded from the resource pool specified.
191 *
192 * @tparam TEnum The type of parameter \p{declaration}
193 * @tparam TEnableIf Not to be specified. Used by the compiler to select this constructor
194 * only for associated custom C++ enum types.
195 * @param declaration Element of an enum class that is representing configuration
196 * variables.
197 **********************************************************************************************/
198 template<typename TEnum, typename TEnableIf= void>
199 VariableDecl( TEnum declaration );
200#else
201 template<typename TEnum,typename TEnableIf=
202 ATMP_VOID_IF( EnumRecords<TEnum>::template AreOfType<VariableDecl>() ) >
203 VariableDecl( TEnum declaration )
204 {
205 // copy our data tuple from the enum record
206 *this= enums::GetRecord(declaration);
207
208 // try to load default value and comment from resources
209 if constexpr( T_Resourced<TEnum>::value )
210 {
212 NString128 resName;
213 resName << T_Resourced<TEnum>::Name() << "_D";
214 integer codePos = resName.Length() - 1;
215 resName << UnderlyingIntegral( declaration );
216 DefaultValue = ResourcedType<TEnum>::Get( resName ALIB_DBG( , false ) );
217
218 resName[codePos] = 'C';
219 Comments = ResourcedType<TEnum>::Get( resName ALIB_DBG( , false ) );
220 }
221
222 // check for nulled strings
224 if( Comments .IsNull() ) Comments= NullString();
225 }
226#endif
227}; // struct VariableDecl
228
229} // namespace alib::[config]
230
231/// Type alias in namespace \b alib.
233
234} // namespace [alib]
235
236
238
239
240#endif // HPP_ALIB_CONFIG_VARIABLEDECL
constexpr bool IsNull() const
Definition string.hpp:395
constexpr integer Length() const
Definition string.hpp:357
#define ALIB_ASSERT_MODULE(modulename)
Definition alib.hpp:190
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
Definition bitwise.hpp:120
#define ATMP_VOID_IF(Cond)
Definition tmp.hpp:52
#define ALIB_API
Definition alib.hpp:538
#define ALIB_DBG(...)
Definition alib.hpp:457
const T_EnumRecords< TEnum >::Type & GetRecord(TEnum element)
Definition alib.cpp:57
constexpr String NullString()
Definition string.hpp:2498
characters::character character
Type alias in namespace alib.
config::VariableDecl VariableDecl
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
VariableDecl() noexcept=default
VariableDecl(TEnum declaration)
ERSerializable() noexcept=default