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