ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
records.hpp
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_enums 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_ENUMS_RECORDS
9#define HPP_ALIB_ENUMS_RECORDS 1
10
11#if !defined(HPP_ALIB_SINGLETONS_SINGLETON)
13#endif
14
16
17#if !defined (HPP_ALIB_ENUMS_UNDERLYING_INTEGRAL)
19#endif
20
21#if ALIB_STRINGS && !defined (HPP_ALIB_STRINGS_LOCALSTRING)
23#endif
24
25#if ALIB_DEBUG && !defined(HPP_ALIB_LANG_DBGTYPEDEMANGLER)
27#endif
28
29#if !defined(_GLIBCXX_UTILITY) || !defined(_UTILITY_)
30# include <utility>
31#endif
32
33#if !defined (_GLIBCXX_ITERATOR) && !defined (_ITERATOR_)
34# include <iterator>
35#endif
36
37
38namespace alib {
39
40// forwards
41#if ALIB_CAMP
42 namespace lang {class Camp; }
43 namespace lang::resources { class ResourcePool; }
44#endif
45
46namespace enums {
47
48
49// #################################################################################################
50// enums::Bootstrap()
51// #################################################################################################
52
53#if !ALIB_CAMP || defined(ALIB_DOX)
54 /** ************************************************************************************************
55 * This method initializes enum records, of built-in types i.e. those of the enumerations found
56 * in header file \alibheader{lang/commonenums.hpp}.
57 *
58 * This method needs to be called with bootstrapping a software.
59 * The \ref alib_manual_bootstrapping "standard bootstrap" code of \alib, hence the (overloaded)
60 * functions \ref alib::Bootstrap will call this function.
61 *
62 * \note
63 * In fact, if module \alib_basecamp is included, then this function is empty, because
64 * the enumeration records will in this case be resourced in singleton
65 * \ref alib::BASECAMP of type \alib{lang::basecamp;BaseCamp}.
66 *
67 * Multiple invocations of this method are ignored.
68 *
69 * \see
70 * For information about using this method, consult chapter
71 * \ref alib_manual_bootstrapping_nocamps of the \ref alib_manual.
72 * ************************************************************************************************/
74 void Bootstrap();
75#else
76 inline void Bootstrap()
77 {}
78#endif // !ALIB_CAMP
79
80
81// #################################################################################################
82// T_EnumRecords
83// #################################################################################################
84
85#if defined(ALIB_DOX)
86 /** ************************************************************************************************
87 * This TMP struct is used to associate an <b><em>"ALib Enum Record"</em></b> type to a
88 * (scoped or non-scoped) enumeration type.
89 *
90 * In the non-specialized version type definition #Type (the only entity of this struct)
91 * evaluates to <c>void</c>. To assign a record, specify a data record type, similar to what
92 * is prototyped with \alib{enums;EnumRecordPrototype}
93 *
94 * \see
95 * Please consult chapter \ref alib_enums_records "4. Enum Records" of the Programmer's Manual
96 * of \alib_enums for detailed documentation and sample code on this struct and underlying
97 * concept.
98 *
99 * \see
100 * Macro \ref ALIB_ENUMS_ASSIGN_RECORD offers a well readable alternative to specialize this
101 * struct for an enum type.
102 *
103 * @tparam TEnum The enumeration type this struct applies to.
104 * @tparam TEnableIf Internally used to ensure that given type \p{TEnum} is an enumeration.
105 * Defaulted. Please do not specify!
106 **************************************************************************************************/
107 template<typename TEnum, typename TEnableIf>
109 {
110 /** The data type associated with elements of \p{TEnum}. */
111 using Type= void;
112 };
113#else
114 template<typename TEnum,
115 typename TEnableIf= ATMP_VOID_IF( std::is_enum<TEnum>::value )>
116 struct T_EnumRecords
117 {
118 using Type= void;
119 };
120#endif
121
122// #################################################################################################
123// detail {}
124// #################################################################################################
125}} // namespace [alib::enums]
126
128namespace alib { namespace enums {
129
130
131// #################################################################################################
132// GetRecord/TryRecord
133// #################################################################################################
134
135#if defined(ALIB_DOX)
136/** ************************************************************************************************
137 * Returns the enum record for element \p{element} of enumeration type \p{TEnum} .
138 * In debug-compilations an \alib assertion is raised, if no enum record was defined for
139 * \p{element}.
140 *
141 * Internally, references to enum records are stored in a hash map. With that, this method executes
142 * in constant time <em>O(1)</em> in the average case.
143 *
144 * \see
145 * - Function \alib{enums;TryRecord} which returns a pointer to the record and \c nullptr if
146 * no record was defined for \p{element}.
147 * - Class \b Enum of module \alib_boxing and its method \alib{boxing;Enum::GetRecord},
148 * which allows to collect the necessary run-time information to defer the retrieval of
149 * enum records.
150 *
151 * @tparam TEnum The enumeration type. Deduced from given argument.
152 * @param element The enum element to search for.
153 * @return The record that is associated with \p{element}.
154 **************************************************************************************************/
155template<typename TEnum>
156inline
157const typename T_EnumRecords<TEnum>::Type& GetRecord( TEnum element );
158#else
159template<typename TEnum>
160inline
162 !ATMP_EQ(typename T_EnumRecords<TEnum>::Type, void) )
163GetRecord( TEnum element )
164{
165 static_assert( std::is_trivially_destructible<typename T_EnumRecords<TEnum>::Type>::value,
166 "Error: Enum Record types must be a trivially destructible." );
167
168 const void* result= detail::getEnumRecord( typeid(TEnum),
169 static_cast<integer>( UnderlyingIntegral(element) ) );
170 #if ALIB_STRINGS
171 ALIB_ASSERT_ERROR( result != nullptr, "ENUMS",
172 NString128() << "Enum Record for type <" << lang::DbgTypeDemangler( typeid(TEnum)).Get()
173 << ">(" << UnderlyingIntegral(element)
174 << ") not found." )
175 #else
176 ALIB_ASSERT_ERROR( result != nullptr, "ENUMS: Enum Record for not found." )
177 #endif
178 return *reinterpret_cast<const typename T_EnumRecords<TEnum>::Type*>( result );
179}
180#endif
181
182#if defined(ALIB_DOX)
183/** ************************************************************************************************
184 * If defined, returns a pointer to the enum record for element \p{element} of enumeration
185 * type \p{TEnum} .
186 * If no enum record was defined, \c nullptr is returned.
187 *
188 * \see
189 * - Function \alib{enums;GetRecord} which returns a reference and asserts in debug-compilations
190 * if no record is defined for \p{element} during bootstrap.
191 * - Class \b Enum of module \alib_boxing and its method \alib{boxing;Enum::TryRecord},
192 * which allows to collect the necessary run-time information to defer the retrieval of
193 * enum records.
194 *
195 * @tparam TEnum The enumeration type. Deduced from given argument.
196 * @param element The enum element to search for.
197 * @return A pointer to the record that is associated with \p{element}, respectively \c nullptr
198 * if no record was defined.
199 **************************************************************************************************/
200template<typename TEnum>
201inline
202const typename T_EnumRecords<TEnum>::Type* TryRecord( TEnum element );
203#else
204template<typename TEnum>
205inline
207TryRecord( TEnum element )
208{
209 static_assert( std::is_trivially_destructible<typename T_EnumRecords<TEnum>::Type>::value,
210 "Error: Enum Record types must be a trivially destructible." );
211
212 return reinterpret_cast<const typename T_EnumRecords<TEnum>::Type*>(
213 detail::getEnumRecord( typeid(TEnum), static_cast<integer>( UnderlyingIntegral(element) ) ));
214}
215#endif
216
217
218
219// #################################################################################################
220// struct EnumRecords
221// #################################################################################################
222#if defined(ALIB_DOX)
223/** ************************************************************************************************
224 * This is a pure static interface type usable with enumeration types that dispose about a
225 * specialization of TMP struct \alib{enums;T_EnumRecords}.
226 *
227 * The type has two main purposes:
228 *
229 * 1. Providing overloaded methods #Bootstrap which allow to defined enum data records during
230 * \ref alib_manual_bootstrapping "bootstrapping of ALib" and the using software.
231 * 2. Providing an iterator over all records defined for elements of \p{TEnum}.
232 *
233 * A third purpose, namely to retrieve the default (single) enumeration record for a specific enum
234 * element is not provided by this type, but instead offered with likewise templated namespace
235 * functions
236 * - \alib{enums::GetRecord} and
237 * - \alib{enums::TryRecord}.
238 *
239 * \note
240 * The rational for this is techical: Using namespace methods, the compiler can deduce
241 * template parameter \p{TEnum} from the function parameter, which was not possible if the
242 * functions were static methods of this templated type.
243 *
244 * \attention
245 * While this type becomes available with the inclusion of header file
246 * \alibheader{enums/records.hpp}, the overloaded \b Bootstrap methods, which are to be used
247 * solely during bootstrap, with single-threaded access to this backend, become available
248 * only with further inclusion of header \alibheader{enums/recordbootstrap.hpp}, which provides
249 * these method's defintion.
250 *
251 * The rational for the above is twofold: It reduces header file dependcies from the majority
252 * of code that just use enum records and not defne them. Secondly it stresses the fact that
253 * the #Bootstrap methods must be used only while bootstrapping is done.
254 *
255 * \see Chapter \ref alib_enums_records "ALib Enum Records" of the Programmer's Manual of this
256 * module.
257 *
258 * @tparam TEnum The enumeration type that the static methods of this type are to use.
259 * @tparam TEnableIf To be ignored. Used to select this struct only for enum types which have
260 * a specialization of \alib{enums;T_EnumRecords} in place.
261 **************************************************************************************************/
262template<typename TEnum, typename TEnableIf>
264#else
265template<typename TEnum, typename TEnableIf=
267struct EnumRecords
268#endif // defined(ALIB_DOX)
269{
270 static_assert( std::is_trivially_destructible<typename T_EnumRecords<TEnum>::Type>::value,
271 "Error: Enum Record types must be a trivially destructible." );
272
273 /** Defaulted constructor. */
274 EnumRecords() noexcept = default;
275
276 /** The enum's underlying integer type. */
277 using TIntegral= typename std::underlying_type<TEnum>::type;
278
279 /** The enum's associated record type. */
280 using TRecord = typename T_EnumRecords<TEnum>::Type;
281
282 #if defined(ALIB_DOX)
283 /** ********************************************************************************************
284 * Tests if \p{TEnum} has an associated record type that either is or is derived from
285 * type \p{TRecord}.
286 * @tparam TRecord The enum record base type required.
287 * @tparam TAssociated Deduced by the compiler. Must not be specified.
288 * @return Returns \c true if the given record type is the same or a base class of the
289 * record type associated with the given enum. Otherwise returns \c false.
290 **********************************************************************************************/
291 template<typename TRecord, typename TAssociated>
292 static constexpr
293 bool AreOfType();
294 #else
295 template<typename TRecord, typename TAssociated= typename T_EnumRecords<TEnum>::Type>
296 static constexpr
297 bool AreOfType()
298 {
299 return ATMP_ISOF( TAssociated, TRecord );
300 }
301 #endif
302
303 /** ****************************************************************************************
304 * Implementation of \c std::iterator_traits for enum records.
305 * Begin- and end-iterators can be received with \e static methods
306 * \alib{enums;EnumRecords::begin} and \alib{enums;EnumRecords::end}. In ranged base
307 * <c>for(:)</c> loops, a local instance of type \b EnumRecords has to be created.
308 *
309 * As the name of the class indicates, this iterator satisfies the C++ standard library
310 * concept \https{ForwardIterator,en.cppreference.com/w/cpp/concept/ForwardIterator}.
311 ******************************************************************************************/
313 {
314 private:
315 #if !defined(ALIB_DOX)
316 friend struct EnumRecords;
317 #endif
318
319
320 /** Shortcut to the record hook's inner node type (linked list). */
322
323 /** The current node this iterator refers to. */
325
326 /** Constructor.
327 * @param start Pointer to the initial element. */
328 ForwardIterator( Node* start ) noexcept
329 : node( start )
330 {}
331
332 using iterator_category = std::forward_iterator_tag; ///< Implementation of <c>std::iterator_traits</c>.
333 using value_type = const TRecord& ; ///< Implementation of <c>std::iterator_traits</c>.
334 using difference_type = integer ; ///< Implementation of <c>std::iterator_traits</c>.
335 using pointer = TRecord const* ; ///< Implementation of <c>std::iterator_traits</c>.
336 using reference = const TRecord& ; ///< Implementation of <c>std::iterator_traits</c>.
337
338 public:
339
340 // ###################### To satisfy concept of InputIterator ######################
341
342 /** Prefix increment operator.
343 * @return A reference to this object. */
345 {
346 node= node->next;
347 return *this;
348 }
349
350 /** Postfix increment operator.
351 * @return An iterator value that is not increased, yet. */
353 {
354 return ForwardIterator( node->next );
355 }
356
357 /** Comparison operator.
358 * @param other The iterator to compare ourselves to.
359 * @return \c true if this and the given iterator are pointing to the same element,
360 * \c false otherwise. */
361 bool operator==(ForwardIterator other) const
362 {
363 return node == other.node;
364 }
365
366 /** Comparison operator.
367 * @param other The iterator to compare ourselves to.
368 * @return \c true if this and given iterator are not equal, \c false otherwise. */
369 bool operator!=(ForwardIterator other) const
370 {
371 return !(*this == other);
372 }
373
374 // ###################### Member access ######################
375
376 /** Returns the enum element of the enum record that this iterator refers to.
377 * @return The enum element the current record is associated to. */
378 TEnum Enum() const
379 {
380 return TEnum( node->integral );
381 }
382
383 /** Returns the underlying integral value of the enum element of the enum record
384 * that this iterator refers to.
385 * @return The integral value of the enum element the current record is associated
386 * to. */
388 {
389 return node->integral;
390 }
391
392 /** Returns a constant reference to the enum record this iterator refers to.
393 * @return The current enum record. */
394 const TRecord& operator*() const
395 {
396 return node->record;
397 }
398
399 /** Returns a constant pointer to the enum record this iterator refers to.
400 * @return The current enum record. */
401 TRecord const* operator->() const
402 {
403 return &node->record;
404 }
405 }; // inner struct ForwardIterator
406
407 /**
408 * Returns an iterator referring to the first enum record defined for type \p{TEnum}.
409 *
410 * \note
411 * Receiving the list of enum records is internally implemented using class
412 * \alib{singletons;Singleton} and executes in constant time <em>O(1)</em>, in effect almost
413 * no time.
414 *
415 * \note
416 * Like any other entity in this class, this method is static, apart from a defaulted
417 * (empty) constructor, which is provided for the sole purpose of allowing
418 * range-based <em><c>for(:)</c></em> loops.
419 *
420 * @return An iterator to the first record defined for enumeration type \p{TEnum}.
421 */
422 static
427
428 /**
429 * Returns an iterator referring to the first element behind the list.
430 *
431 * \see The note documented with sibling method #begin.
432 * @return The end of the list. */
433 static constexpr
435 {
436 return ForwardIterator( nullptr );
437 }
438
439
440 // #############################################################################################
441 // Record initialization
442 // Method implementations are given in separated header file
443 // #############################################################################################
444
445 /**
446 * Helper struct used with bulk-initialization method #Bootstrap(std::initializer_list<Initializer>).
447 */
449 {
450 /** The enumeration element. */
451 TEnum element;
452
453 /** The static data record. */
455
456 /**
457 * Constructor taking variadic template arguments to construct the record.
458 *
459 * @tparam TArgs Types of the variadic arguments \p{args}.
460 * @param elem The enum element.
461 * @param args Variadic arguments forwarded to constructor of field #record.
462 */
463 template <typename... TArgs>
464 Initializer( TEnum elem, TArgs&&... args) noexcept
465 : element( elem )
466 , record ( std::forward<TArgs>(args)... )
467 {}
468 };
469
470 /**
471 * Defines a record for a single element of \p{TEnum}.
472 *
473 * \note
474 * This method is rather provided for completeness, than for actual use, because it is
475 * preferred to bootstrap enum records as "bulk" data.
476 * Furthermore, it is preferred to use overloaded versions that accept static string data
477 * used to parse the data from. This is more efficient in respect to the footprint of
478 * an application, and - if strings are \ref alib_basecamp_resources "resourced" -
479 * far more flexible.
480 *
481 * \see Chapter \ref alib_enums_records_firststep_init for a sample of how this method
482 * can be invoked.
483 *
484 * @tparam TArgs Types of the variadic arguments \p{args}.
485 * @param element The enum element.
486 * @param args Variadic arguments forwarded to constructor of the custom record to
487 * create and store.
488 */
489 template <typename... TArgs>
490 static inline
491 void Bootstrap( TEnum element, TArgs&&... args ) noexcept;
492
493 /**
494 * Associates elements of \p{TEnum} with records, as specified by the given list of
495 * \p{definitions}.
496 *
497 * The use of inner struct \alib{enums::EnumRecords;Initializer} allows to place
498 * the enumeration element together with the construction parameters of the custom record
499 * type into one comma-separated argument list, without the need to place extra curly braces
500 * around the arguments of the record. (Such would have been necessary if for example
501 * <c>std::pair</c> had been used).
502 *
503 * \note
504 * It is preferred to use overloaded versions that parse definitions from
505 * static string data. This is more efficient in respect to the footprint of
506 * an application, and - if strings are \ref alib_basecamp_resources "resourced" -
507 * far more flexible.
508 *
509 * \see Chapter \ref alib_enums_records_firststep_init for a sample of how this method
510 * can be invoked.
511 *
512 * @param definitions List of static enum records to store.
513 */
514 static inline
515 void Bootstrap( std::initializer_list<Initializer> definitions );
516
517
518 #if ALIB_STRINGS
519
520 /**
521 * Reads a list of enum data records from given string \p{input}.
522 *
523 * The contents (buffer) of the given substring has to be of static nature (by contract).
524 * This means that parsing will not create copies of portions of the string but still
525 * use them later. Consequently the given string's buffer has to survive the life-cycle
526 * of an application.
527 *
528 * This is due to the static nature of \ref alib_enums_records "ALib Enum Records" and their
529 * creation during bootstrap, either from C++ string literals or
530 * \ref alib_basecamp_resources "ALib Externalized Resources", which comply to the same contract.
531 *
532 * \par Availability
533 * This method is available only if \alib_strings is included in the \alibdist.
534 *
535 * \see Chapter \ref alib_enums_records_resourced_parsing for a sample of how this method
536 * can be invoked.
537 *
538 * @param input The string used for parsing the enum records to store.
539 * @param innerDelim The delimiter used for separating the fields of a record.
540 * Defaults to <c>','</c>.
541 * @param outerDelim The character delimiting enum records.
542 * Defaults to <c>','</c>.
543 */
544 static inline
545 void Bootstrap( const String& input, character innerDelim=',', character outerDelim= ',' );
546 #endif
547
548 #if ALIB_CAMP
549 /**
550 * Reads a list of enum data records from an (externalized) resource string.
551 *
552 * It is possible to provide the record data in two ways:
553 * - In one resource string: In this case, parameter \p{outerDelim} has to specify
554 * the delimiter that separates the records.
555 * - In an array of resource strings: If the resource string as given is not defined, this
556 * method appends an integral index starting with \c 0 to the resource name, parses
557 * a single record and increments the index.
558 * Parsing ends when a resource with a next higher index is not found.
559 *
560 * The second option is recommended for larger enum sets. While the separation causes
561 * some overhead in a resource backend, the external (!) management (translation,
562 * manipulation, etc.) is most probably simplified with this approach.
563 *
564 * \par Availability
565 * This method is available only if \alib_basecamp is included in the \alibdist.
566 *
567 * \see Chapter \ref alib_enums_records_resourced for a sample of how this method
568 * can be invoked.
569 *
570 * @param pool The resource pool to receive the string to parse the records from.
571 * @param category The resource category of the externalized string.
572 * @param name The resource name of the externalized name. In the case that a
573 * resource with that name does not exist, it is tried to load
574 * a resource with index number \c 0 appended to this name, aiming to
575 * parse a single record. On success, the index is incremented until
576 * no consecutive resource is found.
577 * @param innerDelim The delimiter used for separating the fields of a record.
578 * Defaults to <c>','</c>.
579 * @param outerDelim The character delimiting enum records.
580 * Defaults to <c>','</c>.
581 */
582 static
583 inline
585 const NString& category,
586 const NString& name,
587 character innerDelim= ',',
588 character outerDelim= ',' );
589
590 /**
591 * This method is available if TMP struct \alib{lang::resources;T_Resourced} is specialized for
592 * enum type \p{TEnum}.<br>
593 * Invokes #Bootstrap(ResourcePool&, const NString&, const NString&, character, character)
594 *
595 *
596 * \par Availability
597 * This method is available only if \alib_basecamp is included in the \alibdist.
598 *
599 * \see Chapter \ref alib_enums_records_resourced_tresourced of the Programmer's Manual
600 * of this module.
601 *
602 * @param innerDelim The delimiter used for separating the fields of a record.
603 * Defaults to <c>','</c>.
604 * @param outerDelim The character delimiting enum records.
605 * Defaults to <c>','</c>.
606 *
607 */
608 static inline
609 void Bootstrap( character innerDelim=',', character outerDelim= ',' );
610
611 /**
612 * This method can be used if a set of enum records is resourced using an \alib
613 * \alib{lang;Camp}'s resource instance.
614 *
615 * Invokes #Bootstrap(ResourcePool&, const NString&, const NString&, character, character)
616 * accepting a \alib{lang;Camp} and using its \alib{lang::resources;ResourcePool} and
617 * field \alib{lang;Camp::ResourceCategory}.
618 *
619 * \note
620 * This is the preferred overload taken with \alib to load built-in enum records.
621 * The only exclamation is the use of overload #Bootstrap(character, character)
622 * for enum record types that require a specialization of \alib{lang::resources;T_Resourced}
623 * to perform "recursive" acquisition of other resources defined by fields of the
624 * records.
625 *
626 * \par Availability
627 * This method is available only if module \alib_basecamp is included in the \alibdist.
628 *
629 * \see Chapters \ref alib_enums_records_resourced_tresourced and
630 * \ref alib_enums_records_resourced_from_modules for more information.
631 *
632 * @param module The module to use the resource pool and category name from.
633 * @param name The resource name of the externalized name. In the case that a
634 * resource with that name does not exist, it is tried to load
635 * a resource with index number \c 0 appended to this name, aiming to
636 * parse a single record. On success, the index is incremented until
637 * no consecutive resource is found.
638 * @param innerDelim The delimiter used for separating the fields of a record.
639 * Defaults to <c>','</c>.
640 * @param outerDelim The character delimiting enum records.
641 * Defaults to <c>','</c>.
642 */
643 static inline
644 void Bootstrap( lang::Camp& module , const NString& name,
645 character innerDelim= ',' , character outerDelim= ',' );
646 #endif // ALIB_CAMP
647
648}; // struct EnumRecords
649
650// #################################################################################################
651// ERSerializable
652// #################################################################################################
653
654#if ALIB_STRINGS
655/** ************************************************************************************************
656 * This is a <em>built-in</em> record type that can be used to equip custom enumeration types
657 * with \ref alib_enums_records "ALib Enum Records".
658 *
659 * This record has two members, #EnumElementName and #MinimumRecognitionLength which usually
660 * determines an element's name in a human readable format, respectively how many starting
661 * characters are to be read to recognize the element when parsed.
662 *
663 * Basic versions of such serialization and de-serialization is implemented with this module
664 * and documented with chapter
665 * \ref alib_enums_records_details_serialization "4.3.1 Serialization/Deserialization" of the
666 * Programmer's Manual of this \alibmod_nl. This functionality is likewise available for
667 * enumerations equipped with a custom record type that derives from this type. For this reason,
668 * all built-in record types of various \alibmods_nl derive from this type.
669 *
670 * If deserialization is not of importance, a derived type may choose to not parse member
671 * #MinimumRecognitionLength from a (resourced) string, but initialize it to fixed \c 0 value.
672 * This behavior is for example implemented with record \alib{lang;ERException} and various
673 * types found in module \alib_cli.
674 *
675 * \see For more information see:
676 * - Chapter \ref alib_enums_records "ALib Enum Records" and its sub-section
677 * \ref alib_enums_records_details_serialization "4.3.1 Serialization/Deserialization".
678 * - Specializations
679 * \alib{strings::APPENDABLES;T_Append<TEnum,TChar>;T_Append<TEnum,TChar>} and
680 * \alib{strings::APPENDABLES;T_Append<TEnumBitwise,TChar>;T_Append<TEnumBitwise,TChar>}.
681 * which allows write enumeration element names to instances of class
682 * \alib{strings;TAString;AString}.
683 * - Namespace functions of this module for parsing enum element values:
684 * - \alib{enums;Parse}
685 * - \alib{enums;ParseBitwise} and
686 * - \alib{enums;ParseEnumOrTypeBool}.
687 **************************************************************************************************/
689{
690 /** The name of the enum element. */
692
693 /**
694 * Built-in basic de-serialization functions \alib{enums;Parse}, \alib{enums;ParseBitwise} and
695 * \alib{enums;ParseEnumOrTypeBool} interpret this value as the minimum length (abbreviation)
696 * to accept when an enum element name is parsed.
697 * If \c 0 or negative, the complete #EnumElementName is expected.
698 */
700
701
702 /** Defaulted constructor leaving the record undefined. */
703 ERSerializable() noexcept = default;
704
705 /**
706 * Constructor. This is either called by descendants or by user code that omits the preferred
707 * option of parsing resourced strings for the creation of enum records.
708 *
709 * Note that parameter \p{name} has to be of "static nature", which means the buffer and
710 * contents of the string is deemed to survive the life-cycle of an application.
711 * With direct invocation, usually, C++ string literals are passed.
712 *
713 * @param name The name of this element.
714 * @param minLength The minimum length to recognise an element when de-serialized.
715 * (Assigned to field #MinimumRecognitionLength.)
716 */
717 ERSerializable( const String& name, int minLength= 0 ) noexcept
718 : EnumElementName (name)
719 , MinimumRecognitionLength(minLength)
720 {}
721
722 /**
723 * Parses the fields of this record from the \b Substring \p{parser} given as reference.
724 * In case of error an \alib exception is raised, as parsing has to succeed.
725 *
726 * @see
727 * This is the implementation of a method needed with TMP, as described in
728 * \alib{enums;EnumRecordPrototype::Parse}.
729 */
731 void Parse();
732};
733#endif // ALIB_STRINGS
734
735
736
737} // namespace alib[::enums]
738
739/// Type alias in namespace \b alib.
740template<typename TEnum>
742
743/// Type alias in namespace \b alib.
744template<typename TEnum>
746
747} // namespace [alib]
748
749// #################################################################################################
750// Helper Macros
751// #################################################################################################
752#define ALIB_ENUMS_ASSIGN_RECORD( TEnum, TRecord ) \
753namespace alib::enums { \
754template<> struct T_EnumRecords<TEnum> : public std::true_type \
755{ \
756 using Type= TRecord; \
757};}
758
759#endif // HPP_ALIB_ENUMS_RECORDS
#define ALIB_ASSERT_MODULE(modulename)
Definition alib.hpp:190
#define ATMP_VOID_IF(Cond)
Definition tmp.hpp:52
#define ATMP_ISOF( T, TBase)
Definition tmp.hpp:33
#define ALIB_API
Definition alib.hpp:538
#define ATMP_EQ( T, TEqual)
Definition tmp.hpp:32
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
#define ATMP_T_IF(T, Cond)
Definition tmp.hpp:53
ALIB_API const void * getEnumRecord(const std::type_info &rtti, integer integral)
Definition records.cpp:60
constexpr std::underlying_type< TEnum >::type UnderlyingIntegral(TEnum element) noexcept(true)
const T_EnumRecords< TEnum >::Type * TryRecord(TEnum element)
ALIB_API void Bootstrap()
const T_EnumRecords< TEnum >::Type & GetRecord(TEnum element)
Definition alib.cpp:57
NLocalString< 128 > NString128
Type alias name for TLocalString<nchar,128> .
characters::character character
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
ERSerializable() noexcept=default
typename detail::EnumRecordHook< TEnum >::Node Node
Definition records.hpp:321
std::forward_iterator_tag iterator_category
Implementation of std::iterator_traits.
Definition records.hpp:332
bool operator==(ForwardIterator other) const
Definition records.hpp:361
bool operator!=(ForwardIterator other) const
Definition records.hpp:369
const TRecord & value_type
Implementation of std::iterator_traits.
Definition records.hpp:333
integer difference_type
Implementation of std::iterator_traits.
Definition records.hpp:334
TRecord const * pointer
Implementation of std::iterator_traits.
Definition records.hpp:335
const TRecord & reference
Implementation of std::iterator_traits.
Definition records.hpp:336
Initializer(TEnum elem, TArgs &&... args) noexcept
Definition records.hpp:464
static void Bootstrap(const String &input, character innerDelim=',', character outerDelim=',')
typename std::underlying_type< TEnum >::type TIntegral
Definition records.hpp:277
static void Bootstrap(lang::Camp &module, const NString &name, character innerDelim=',', character outerDelim=',')
static void Bootstrap(TEnum element, TArgs &&... args) noexcept
static void Bootstrap(character innerDelim=',', character outerDelim=',')
static constexpr ForwardIterator end()
Definition records.hpp:434
static void Bootstrap(std::initializer_list< Initializer > definitions)
static ForwardIterator begin()
Definition records.hpp:423
static void Bootstrap(lang::resources::ResourcePool &pool, const NString &category, const NString &name, character innerDelim=',', character outerDelim=',')
EnumRecords() noexcept=default
typename T_EnumRecords< TEnum >::Type TRecord
Definition records.hpp:280
static constexpr bool AreOfType()