ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
resources.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_resources of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace resources {
9//==================================================================================================
10/// This purely abstract class provides an interface to store and retrieve "resourced" string data
11/// which are organized in a two-level key hierarchy named <em>"resource category"</em>
12/// and <em>"resource name"</em>. The latter are of narrow string-type.
13///
14/// \see
15/// For detailed documentation on when and how this interface is used, please consult the
16/// #"alib_mod_resources;Programmer's Manual" of this module \alib_resources_nl.
17///
18/// \see
19/// Two built-in implementations of this pure abstract interface are provided with
20/// #"LocalResourcePool" and #"ConfigResourcePool".
21/// Please consult their reference documentation for further details.
22//==================================================================================================
24{
25 public:
26
27 /// Virtual destructor.
28 virtual ~ResourcePool() =default;
29
30 /// Used to store a resource string.
31 ///
32 /// In the context of \alibmods, which usually are the only areas where instances of this
33 /// type are available (used), this method must only be invoked during the process of
34 /// #"alib_mod_bs;bootstrapping" \alib (and corresponding custom modules).
35 ///
36 /// \attention
37 /// The life-cycle of the given string's buffers, have to survive this resource instance.
38 /// Usually the strings passed here are constant C++ string literals, residing in the data
39 /// segment of an executable
40 ///
41 /// \note
42 /// Usually, the method #"Bootstrap" should be preferred, which asserts in debug-compilations
43 /// if a resource already existed.
44 /// The use of this method is for special cases, for example, to replace (patch) resources
45 /// of dependent modules.
46 ///
47 /// @param category Category string of the resource to add.
48 /// @param name Name string of the resource.
49 /// @param data The resource data.
50 /// @return \c true if the resource did exist and was replaced, \c false if it was an insertion.
51 virtual
52 bool BootstrapAddOrReplace(const NString& category, const NString& name, const String& data) =0;
53
54 /// Simple inline method that invokes virtual method #".BootstrapAddOrReplace".
55 /// In debug-compilations, it is asserted that a resource with the given key did not exist
56 /// already.
57 ///
58 /// The use of this method is preferred over a direct invocation of #".BootstrapAddOrReplace".
59 ///
60 /// @param category Category string of the resource to add.
61 /// @param name Name string of the resource.
62 /// @param data The resource data.
63 inline
64 void Bootstrap( const NString& category, const NString& name, const String& data ) {
65 #if ALIB_DEBUG
66 bool result=
67 #endif
68 BootstrapAddOrReplace(category, name, data);
69
70 ALIB_ASSERT_ERROR( result, "RESOURCES",
71 "Doubly defined resource \"{}\" in category \"{}\".", category, name )
72 }
73
74 /// Same as #"Bootstrap" but accepts an array of name/value pairs to be filled into the given
75 /// \p{category}.
76 ///
77 /// \attention
78 /// <b>The given list has to be finished with a final \c nullptr argument for the next
79 /// name!</b>
80 ///
81 /// In the context of \alibcamps, which usually are the only areas where instances of this
82 /// type are used, this method must only be invoked during the process of
83 /// #"alib_mod_bs;bootstrapping" \alib (and corresponding custom modules).
84 ///
85 /// \attention
86 /// The life-cycle of the given string's buffers, have to survive this resource instance.
87 /// Usually the strings passed here are constant C++ string literals, residing in the data
88 /// segment of an executable
89 ///
90 /// \note
91 /// The use of variadic C-style arguments <c>"..."</c> in general is \b not recommended
92 /// to be used.
93 /// We still do it here, because, as the name of this method indicates, usually a large
94 /// nummber of resources is loaded with one call.
95 /// This approach saves a lot of otherwise necessary single invocations (reduces code size)
96 /// and allows a rather clean code for the init methods.<br>
97 /// For technical reasons, parameter \p{category } is declared as type <c>const nchar*</c>.
98 ///
99 /// @param category The category of the resources given.
100 /// @param ... A list of pairs of <b>const nchar*</b> and <b>const character*</b>
101 /// keys and data, including a terminating \c nullptr value.
102 virtual
103 void BootstrapBulk( const nchar* category, ... ) =0;
104
105#if DOXYGEN
106 //==============================================================================================
107 /// Returns a resource.
108 /// On failure (resource not found), a \e nulled string is returned.
109 ///
110 /// \note
111 /// Usually resource pools are associated with #"ResourceHolder" objects and
112 /// resources should be loaded using its "shortcut methods"
113 /// #"ResourceHolder::TryResource" and
114 /// #"ResourceHolder::GetResource".
115 /// If used directly, the argument \p{dbgAssert} has to be enclosed in macro #"ALIB_DBG"
116 /// (including the separating comma).
117 ///
118 /// @param category Category string of the resource.
119 /// @param name Name string of the resource
120 /// @param dbgAssert This parameter is available (and to be passed) only in debug mode.
121 /// If \c true, an #"alib_mod_assert;error is raised" if the resource
122 /// was not found.
123 /// @return The resource string, respectively a \e nulled string on failure.
124 //==============================================================================================
125 virtual
126 const String& Get( const NString& category, const NString& name, bool dbgAssert ) = 0;
127#else
128 virtual
129 const String& Get( const NString& category, const NString& name ALIB_DBG(,bool dbgAssert)) =0;
130#endif
131
132#if DOXYGEN
133 //==============================================================================================
134 /// Convenience inlined method that accepts parameter name as #"characters::character"
135 /// instead of #"characters::nchar" based string-type. The rationale for this is that often,
136 /// resource name keys are read from other resourced strings and need conversion if used.
137 /// This avoids external conversion before invoking this method.
138 ///
139 /// This method is available only when \alib is compiled with type #"characters::character"
140 /// not being equivalent to #"characters::nchar".
141 ///
142 /// After the string conversion, this method simply returns the result of the virtual method
143 /// #".Get(const NString&, const NString&, bool)".
144 ///
145 /// @param category Category string of the resource.
146 /// @param name Name string of the resource
147 /// @param dbgAssert This parameter is available (and to be passed) only in debug mode.
148 /// If \c true, an #"alib_mod_assert;error is raised" if the resource
149 /// was not found.
150 /// @return The resource string, respectively a \e nulled string on failure.
151 //==============================================================================================
152 const String& Get( const NString& category, const String& name, bool dbgAssert );
153#else
154 #if ALIB_CHARACTERS_WIDE
155 const String& Get( const NString& category, const String& name ALIB_DBG(,bool dbgAssert) )
156 {
157 NString128 nName( name );
158 return Get( category, nName ALIB_DBG(, dbgAssert ) );
159 }
160 #endif
161#endif
162
163 #if ALIB_DEBUG_RESOURCES
164 //==========================================================================================
165 /// Returns a vector of tuples for each resourced element. Each tuple contains:
166 /// 0. The category name
167 /// 1. The resource name
168 /// 2. The resource value
169 /// 3. The number of requests for the resource performed by a using data.
170 ///
171 /// While being useful to generaly inspect the resources, a high number of requests
172 /// might indicate a performance penalty for a using software. Such can usually be
173 /// mitigated in a very simple fashion by "caching" a resource string in a local
174 /// or global/static string variable.
175 ///
176 /// \par Availability
177 /// Available only if the configuration macro #"ALIB_DEBUG_RESOURCES" is set.
178 ///
179 /// \attention
180 /// This method is implemented only with the default pool instance of type
181 /// #"LocalResourcePool".
182 /// Other implementations raise an \alib_warning and return an empty vector.
183 ///
184 /// \see
185 /// Method #"DbgGetCategories" and namespace function #"resources::DbgDump".
186 ///
187 /// @return The externalized resource string.
188 //==========================================================================================
190 virtual
191 std::vector<std::tuple<NString, NString, String, integer>> DbgGetList();
192
193 //==========================================================================================
194 /// Implements abstract method #"ResourcePool::DbgGetCategories;*".
195 ///
196 /// \par Availability
197 /// Available only if the configuration macro #"ALIB_DEBUG_RESOURCES" is set.
198 ///
199 /// \attention
200 /// This method is implemented only with the default pool instance of type
201 /// #"LocalResourcePool".
202 /// Other implementations raise an \alib_warning and return an empty vector.
203 ///
204 /// \see
205 /// Method #"DbgGetList" and namespace function #"resources::DbgDump".
206 ///
207 /// @return The externalized resource string.
208 //==========================================================================================
210 virtual
211 std::vector<std::pair<NString, integer>> DbgGetCategories();
212 #endif //ALIB_DEBUG_RESOURCES
213}; // class ResourcePool
214
215//==================================================================================================
216/// A type serving as the base for types that hold a pointer to a #"LocalResourcePool"
217/// and a fixed category string.
218/// \note The most prominent descendant of this type is class #"Camp".
219//==================================================================================================
221 public:
222 /// Type definition used for sharing resource-pool instances. With default-bootstrapping,
223 /// an instance of type #"LocalResourcePool" is used here, which is
224 /// created with allocator instance #"GLOBAL_ALLOCATOR".
226
227 protected:
228 /// Shared pointer to the resource pool.
230
231 public:
232 /// The name of the resource category of externalized string resources defined and used by
233 /// this resource holder.<br>
235
236 /// Constructor.
237 /// @param resourceCategory Value for field #".ResourceCategory".
238 ResourceHolder( const NCString& resourceCategory= nullptr )
239 : ResourceCategory(resourceCategory) {}
240
241 /// Constructor.
242 /// @param pool Value for the field #"resourcePool".
243 /// @param resourceCategory Value for the field #".ResourceCategory".
244 ResourceHolder( SPResourcePool& pool, const NCString& resourceCategory )
245 : resourcePool (pool)
246 , ResourceCategory(resourceCategory) {}
247
248 /// Constructor.
249 /// @param pool Value for the field #resourcePool.
250 /// @param resourceCategory Value for field #".ResourceCategory". If not given (<em>nulled</em>),
251 /// then the old value is preserved.
252 void Set( SPResourcePool& pool, const NCString& resourceCategory= nullptr ) {
253 resourcePool= pool;
254 if ( resourceCategory.IsNotNull() )
255 ResourceCategory= resourceCategory;
256 }
257
258 /// Determines if a resource pool is set.
259 /// @return \c true if the field #resourcePool is not \e nulled, \c false otherwise.
260 bool HasPool() { return resourcePool.Get() != nullptr; }
261
262 /// Shortcut method that invokes #"ResourcePool::Bootstrap;*" on field
263 /// #resourcePool providing field #".ResourceCategory" as a parameter.
264 /// @param name The resource name.
265 /// @param data The resource data string.
266 inline
267 void BootstrapResource( const NString& name, const String& data ) {
269 }
270
271 /// Returns a reference (!) to the shared pointer holding the resource pool.
272 /// @return The resource pool instance.
274
275 /// Returns a reference (not the shared-pointer!) to the resource pool held in our \b SharedPtr.
276 /// @return The resource pool instance.
278
279 /// Shortcut method that invokes #"ResourcePool::Get;*" on field
280 /// #resourcePool providing field #ResourceCategory as parameter.
281 ///
282 /// With debug-builds, this method asserts that a resource was found. If this is not
283 /// wanted, use #TryResource.
284 /// @param name The resource name.
285 /// @return The resource string, respectively a \e nulled string on failure.
286 inline
287 const String& GetResource( const NString& name ) {
288 return resourcePool->Get( ResourceCategory, name ALIB_DBG(, true) );
289 }
290
291 /// Shortcut method that invokes #"ResourcePool::Get;*" on field
292 /// #resourcePool providing field #ResourceCategory as parameter.
293 ///
294 /// \note
295 /// Usually, it is recommended to use #GetResource, which asserts with debug-builds
296 /// if a resource was not found.
297 ///
298 /// @param name The resource name.
299 /// @return The resource string, respectively a \e nulled string on failure.
300 inline
301 const String& TryResource( const NString& name ) {
302 return resourcePool->Get( ResourceCategory, name ALIB_DBG(, false) );
303 }
304};
305
306//==================================================================================================
307/// A simple type trait that associates resource information to the given type \p{T} .
308///
309/// Extends <c>std::false_type</c> by default to indicate that it is not specialized for a specific
310/// type. Specializations need to extend <c>std::true_type</c> instead.
311///
312/// \see
313/// - Helper macros #"ALIB_RESOURCED" and ALIB_RESOURCED_IN_CAMP that specialize this struct.
314/// - Helper-type #"ResourcedType".
315/// - Manual chapter #"alib_resources_t_resourced"
316/// of the Programmer's Manual of this module.
317///
318/// @tparam T The type to define resource information for.
319//==================================================================================================
320template<typename T>
321struct ResourcedTraits : std::false_type
322{
323 /// Returns a pointer to the resource pool associated with \p{T}.
324 /// @return The resource pool of \p{T}.
325 static constexpr ResourcePool* Pool() { return nullptr; }
326
327 /// Returns a resource category associated with \p{T}.
328 /// @return The resource category.
329 static constexpr NString Category() { return NULL_NSTRING; }
330
331 /// Returns a resource name associated with \p{T}.
332 /// @return The resource category.
333 static constexpr NString Name() { return NULL_NSTRING; }
334};
335
337
338/// A concept to identify whether resources are associated with type \p{T}.
339/// These are types for which a specialization of type trait #"ResourcedTraits"
340/// is defined.
341/// @tparam T The type to be tested.
342template <typename T>
344
346
347//==================================================================================================
348/// Static helper-struct used to access resources of types that dispose of a specialization of
349/// the type trait #"ResourcedTraits".
350///
351/// @see
352/// - Type trait #"ResourcedTraits"
353/// - Manual chapter #"alib_resources_t_resourced_resourced" of the
354/// Programmer's Manual of this module.
355///
356/// @tparam T A type equipped with resource information by a specialization of
357/// #"ResourcedTraits".
358//==================================================================================================
359template<typename T>
361{
362 /// Static method that receives a resource string for a type which has a specialization
363 /// of #"ResourcedTraits" defined.
364 ///
365 /// @tparam TRequires Not to be specified.
366 /// Used by the compiler to select the availability of this method.
367 /// @return The externalized resource string.
368 template<typename TRequires= T>
370 static const String& Get() {
373 ALIB_DBG(, true) );
374 }
375
376 #if DOXYGEN
377 /// Variant of the parameterless version #"ResourcedType::Get()" that
378 /// ignores the resource name given for a type with a specialization of
379 /// #"ResourcedTraits", but instead uses the name provided.
380 ///
381 /// @tparam TRequires Not to be specified. Used by the compiler to select the availability
382 /// of this method.
383 /// @param name The resource name to use, given as string of narrow character width.
384 /// @param dbgAssert This parameter is available (and to be passed) only in debug mode.
385 /// If \c true, an #"alib_mod_assert;error is raised" if the resource
386 /// was not found.
387 /// Use the macro ALIB_DBG with calls to this method.
388 /// @return The externalized resource string.
389 template<typename TRequires= T>
391 static const String& Get( const NString& name, bool dbgAssert );
392 #else
393 template<typename TRequires= T>
395 static const String& Get( const NString& name ALIB_DBG(, bool dbgAssert) ) {
397 name
398 ALIB_DBG(, dbgAssert) );
399 }
400 #endif
401
402 #if DOXYGEN
403 /// Variant of the method #"ResourcedType::Get(const NString&; bool)" that
404 /// accepts a character string of standard character width instead of a narrow type.
405 ///
406 /// \par Availability
407 /// Available only if #"ALIB_CHARACTERS_WIDE" evaluates to \c true.
408 ///
409 /// @tparam TRequires Not to be specified. Used by the compiler to select the availability
410 /// of this method.
411 /// @param resourceName The resource name to use, given as a string of standard character width.
412 /// @param dbgAssert This parameter is available (and to be passed) only in debug mode.
413 /// If \c true, an #"alib_mod_assert;error is raised" if the resource
414 /// was not found.
415 /// @return The externalized resource string.
416 template<typename TRequires= T>
418 static const String& Get( const String& resourceName, bool dbgAssert );
419 #else
420 #if ALIB_CHARACTERS_WIDE
421 template<typename TRequires= T>
423 static const String& Get( const String& resourceName ALIB_DBG(, bool dbgAssert) ) {
425 resourceName
426 ALIB_DBG(, dbgAssert) );
427 }
428 #endif
429 #endif
430
431 /// Together with sibling method #TypeNamePostfix, this method may be used to receive the
432 /// first portion of a type's human-readable name.
433 ///
434 /// The method tries to standardize resourcing names of C++ types along with the resource string
435 /// that is defined with the type trait #"ResourcedTraits" for a type.
436 ///
437 /// The prefix is tried to be retrieved by extending the resource name returned by the method
438 /// #"ResourcedTraits::Name;*" by character <c>'<'</c>.
439 ///
440 /// \alib uses this method internally, for example, with specializations
441 /// #"AppendableTraits<TEnum,TChar,TAllocator>"
442 /// #"AppendableTraits<TBitwiseEnum,TChar,TAllocator>"
443 /// used to write element names of enum types.
444 ///
445 /// If either #"ResourcedTraits" is \e not specialized for \p{TEnum},
446 /// or a resource named \"\p{name}<b>></b>\" is not found, an empty string is returned.<br>
447 ///
448 /// @return The prefix string.
449 static const String& TypeNamePrefix() {
450 if constexpr( HasResources<T> ) {
451 NString256 resourceName( ResourcedTraits<T>::Name() );
452 resourceName << "<";
453 auto* pool= ResourcedTraits<T>::Pool();
454 const auto& category= ResourcedTraits<T>::Category();
455 auto& pf= pool->Get( category, resourceName ALIB_DBG(, false) );
456 if( pf.IsNotNull() )
457 return pf;
458 }
459
460 return EMPTY_STRING;
461 }
462
463 /// Same as #TypeNamePrefix but for the postfix string of a types name.
464 /// Consequently, extends the resource string's name searched by character <c>'>'</c>.
465 ///
466 /// @return The postfix string.
467 static const String& TypeNamePostfix() {
469 if constexpr( HasResources<T> ) {
470 NString256 resourceName( ResourcedTraits<T>::Name() );
471 resourceName << ">";
472 auto& pf= ResourcedTraits<T>::Pool()->Get( ResourcedTraits<T>::Category(), resourceName
473 ALIB_DBG(, false) );
474 if( pf.IsNotNull() )
475 return pf;
476 }
478
479 return EMPTY_STRING;
480 }
481
482}; // struct ResourcedType
483
484/// Utility type that may be used to store resourcing information.
485///
486/// Besides constructor #ResourceInfo(ResourcePool*, NString, NString) and corresponding #Set method,
487/// templated alternatives exist, which are applicable if #"ResourcedTraits"
488/// is specialized for the template type.
490{
491 /// The resource pool.
493
494 /// The resource category within #Pool.
496
497 /// The resource category within #Pool.
499
500 /// Defaulted constructor leaving the fields uninitialized.
501 ResourceInfo() noexcept =default;
502
503 /// Constructor setting the fields of this object as given.
504 ///
505 /// @param pool The resource pool.
506 /// @param category The resource category.
507 /// @param name The resource name.
508 template<typename T>
510 : Pool (pool )
511 , Category(category)
512 , Name (name ) {}
513
514 /// Templated constructor which sets the fields of this object according to the values provided
515 /// with a specialization of #"ResourcedTraits" for type \p{T}.
516 ///
517 /// @tparam T Type that disposes of a specialization of \b ResourcedTraits.
518 /// Deduced by the compiler
519 /// @param sample A sample instance of type \p{T}. Exclusively used to have the compiler
520 /// deduce type \p{T} (otherwise ignored).
521 template<typename T>
522 ResourceInfo(const T& sample) { Set( sample ); }
523
524 /// Sets the fields of this object as given.
525 ///
526 /// @param pool The resource pool.
527 /// @param category The resource category.
528 /// @param name The resource name.
529 void Set( resources::ResourcePool* pool, NString category, NString name ) {
530 Pool = pool;
531 Category = category;
532 Name = name;
533 }
534
535 /// Sets the fields of this object according to the values provided with a specialization of
536 /// #"ResourcedTraits" for type \p{T}.
537 ///
538 /// @tparam T Type that disposes of a specialization of \b ResourcedTraits.
539 /// Deduced by the compiler
540 /// @param sample A sample instance of type \p{T}. Exclusively used to have the compiler
541 /// deduce type \p{T} (otherwise ignored).
542 template<typename T>
544 void Set(const T& sample) {
545 (void) sample;
549 }
550
551 /// Receives the resource string according to this info object.
552 /// @return The externalized resource string.
553 const String& Get() { return Pool->Get( Category, Name ALIB_DBG(, true) ); }
554
555
556 #if DOXYGEN
557 /// Variant of parameterless version #Get() that ignores field #Name and instead uses given
558 /// argument \p{name} .
559 ///
560 /// @param name The resource name to use, given as string of narrow character width.
561 /// @param dbgAssert This parameter is available (and to be passed) only in debug mode.
562 /// If \c true, an #"alib_mod_assert;error is raised" if the resource
563 /// was not found.
564 /// @return The externalized resource string.
565 inline
566 const String& Get( const NString& name, bool dbgAssert );
567 #else
568 const String& Get( const NString& name ALIB_DBG(, bool dbgAssert) )
569 { return Pool->Get( Category, name ALIB_DBG(, dbgAssert) ); }
570 #endif
571
572
573 #if DOXYGEN
574 /// Variant of mehtod Get(const NString&, bool) that accepts a character string of standard
575 /// character width instead of a narrow type.
576 ///
577 /// \par Availability
578 /// Available only if #"ALIB_CHARACTERS_WIDE" evaluates to \c true.
579 ///
580 /// @param name The resource name to use, given as string of standard character width.
581 /// @param dbgAssert This parameter is available (and to be passed) only in debug mode.
582 /// If \c true, an #"alib_mod_assert;error is raised" if the
583 /// resource was not found.
584 /// @return The externalized resource string.
585 inline
586 const String& Get( const String& name, bool dbgAssert );
587 #else
588 #if ALIB_CHARACTERS_WIDE
589 const String& Get( const String& name ALIB_DBG(, bool dbgAssert) )
590 { return Pool->Get( Category, name ALIB_DBG(, dbgAssert) ); }
591 #endif
592 #endif
593}; // ResourceInfo
594
595
596} // namespace alib[::resources]
597
598/// Type alias in namespace \b alib.
600
601/// Type alias in namespace \b alib.
602template<typename T>
604
605/// Type alias in namespace \b alib.
607
608} // namespace [alib]
609
610
611#if ALIB_ENUMRECORDS
612//==================================================================================================
613//==== enumrecords::Bootstrap() functions
614//==================================================================================================
617
618/// Reads a list of enum data records from an (externalized) resource string.
619///
620/// It is possible to provide the record data in two ways:
621/// - In one resource string: In this case, parameter \p{outerDelim} has to specify
622/// the delimiter that separates the records.
623/// - In an array of resource strings: If the resource string as given is not defined, this
624/// method appends an integral index starting with \c 0 to the resource name, parses
625/// a single record and increments the index.
626/// Parsing ends when a resource with a next higher index is not found.
627///
628/// The second option is recommended for larger enum sets. While the separation causes
629/// some overhead in a resource backend, the external (!) management (translation,
630/// manipulation, etc.) is most probably simplified with this approach.
631///
632/// \par Availability
633/// This namespace function is available only if \alib_enumrecords is included in the \alibbuild.
634///
635/// \see Chapter #"alib_enums_records_resourced" for a sample of how this method
636/// can be invoked.
637///
638/// @tparam TEnum The enumeration type to load resourced records for.
639/// @param pool The resource pool to receive the string to parse the records from.
640/// @param category The resource category of the externalized string.
641/// @param name The resource name of the externalized name. In the case that a
642/// resource with that name does not exist, it is tried to load
643/// a resource with index number \c 0 appended to this name, aiming to
644/// parse a single record. On success, the index is incremented until
645/// no consecutive resource is found.
646/// @param innerDelim The delimiter used for separating the fields of a record.
647/// Defaults to <c>','</c>.
648/// @param outerDelim The character delimiting enum records.
649/// Defaults to <c>','</c>.
650template<typename TEnum>
653 const NString& category,
654 const NString& name,
655 character innerDelim= ',',
656 character outerDelim= ',' ) {
657 // resources given in the standard, non-indexed way?
658 String input= pool.Get( category, name ALIB_DBG(, false) );
659 if( input.IsNotNull() ) {
660 // Note:
661 // The parser is initialized here already. The "inner" call to Bootstrap() will not have
662 // the resource information otherwise.
663 // Double initialization is checked inside the parser's initialize method.
664 // (A little crude but OK!)
665 EnumRecordParser::Initialize(input, innerDelim, outerDelim, category, name );
666 Bootstrap<TEnum>( input, innerDelim, outerDelim );
667 return;
668 }
669
670 // resources given as name0, name1, name2...
671 NString64 nameNr( name);
672 int nr= 0;
674 auto** lastP = records.getPointerToLast();
675 while( (input= pool.Get( category, nameNr.Reset( name)._(nr) ALIB_DBG(, false))).IsNotNull()
676 || nr== 0 )
677 {
678 EnumRecordParser::Initialize(input, innerDelim, outerDelim, category, nameNr );
679
680 auto* element= (*lastP= monomem::GLOBAL_ALLOCATOR().New<typename detail::EnumRecordHook<TEnum>::Node>());
681
682 EnumRecordParser::Get( element->integral );
683 element->record.Parse();
684
685 detail::setEnumRecord( typeid(TEnum), integer(element->integral), &element->record );
686
688 // next
689 lastP= &element->next;
690 ++nr;
691 }
692 (*lastP)= nullptr;
693
694 // check if there are more coming (a gap in numbered definition)
695 #if ALIB_DEBUG
696 for( int i= 0 ; i < 35 ; ++i ) {
697 ++nr;
698 if( pool.Get( category, nameNr.Reset( name)._( nr) ALIB_DBG(, false)).IsNotNull() ) {
699 ALIB_ERROR( "ENUMS",
700 "Detected a \"gap\" in numbering of enum records for type <{}>: "
701 "From index {} to {}.\n Resource: {}/{}",
702 &typeid(TEnum), nr - i - 1, nr - 1, category, name )
703 } }
704 #endif
705}
706
707/// This namespace function is available if the type trait #"ResourcedTraits"
708/// is specialized for the enum type \p{TEnum}.<br>
709/// Invokes #Bootstrap(ResourcePool&, const NString&, const NString&, character, character)
710///
711/// \par Availability
712/// This method is available only if \alib_resources is included in the \alibbuild.
713///
714/// \see Chapter #"alib_enums_records_resourced_tresourced" of the Programmer's Manual
715/// of this module.
716///
717/// @tparam TEnum The enumeration type to load resourced records for.
718/// @param innerDelim The delimiter used for separating the fields of a record.
719/// Defaults to <c>','</c>.
720/// @param outerDelim The character delimiting enum records.
721/// Defaults to <c>','</c>.
722template<typename TEnum>
724void Bootstrap( character innerDelim=',', character outerDelim= ',' ) {
725 static_assert( resources::HasResources<TEnum>,
726 "No specialization for ResourcedTraits<TEnum> given. Method not applicable." );
727
731 innerDelim, outerDelim );
732}
733#include "ALib.Lang.CIMethods.H"
734} // namespace [alib::enumrecords::bootstrap]
735#endif // ALIB_ENUMRECORDS
#define ALIB_DLL
Definition alib.inl:573
#define ALIB_ALLOW_DOCS
Definition alib.inl:662
#define ALIB_ERROR(domain,...)
Definition alib.inl:1140
#define ALIB_POP_ALLOWANCE
Definition alib.inl:673
#define ALIB_ALLOW_NULL_POINTER_PASSING
Definition alib.inl:584
#define ALIB_EXPORT
Definition alib.inl:562
#define ALIB_DBG(...)
Definition alib.inl:931
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1144
ResourceHolder(SPResourcePool &pool, const NCString &resourceCategory)
const String & GetResource(const NString &name)
SPResourcePool & GetResourcePoolSP()
const String & TryResource(const NString &name)
SPResourcePool resourcePool
Shared pointer to the resource pool.
void BootstrapResource(const NString &name, const String &data)
void Set(SPResourcePool &pool, const NCString &resourceCategory=nullptr)
ResourceHolder(const NCString &resourceCategory=nullptr)
SharedPtr< resources::ResourcePool, MonoAllocator > SPResourcePool
virtual bool BootstrapAddOrReplace(const NString &category, const NString &name, const String &data)=0
virtual std::vector< std::pair< NString, integer > > DbgGetCategories()
void Bootstrap(const NString &category, const NString &name, const String &data)
Definition resources.inl:64
const String & Get(const NString &category, const String &name, bool dbgAssert)
virtual ~ResourcePool()=default
Virtual destructor.
virtual const String & Get(const NString &category, const NString &name, bool dbgAssert)=0
virtual void BootstrapBulk(const nchar *category,...)=0
virtual std::vector< std::tuple< NString, NString, String, integer > > DbgGetList()
TAString & _(const TAppendable &src)
constexpr bool IsNotNull() const
Definition string.inl:343
void Bootstrap(camp::Camp &camp, const NString &name, character innerDelim=',', character outerDelim=',')
Definition camp.inl:265
void setEnumRecord(const std::type_info &rtti, integer elementValue, const void *record)
Definition records.cpp:62
TMonoAllocator< lang::HeapAllocator > GLOBAL_ALLOCATOR
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2181
constexpr NString NULL_NSTRING
A nulled string of the narrow character type.
Definition string.inl:2263
resources::ResourcePool ResourcePool
Type alias in namespace alib.
strings::TCString< nchar > NCString
Type alias in namespace alib.
Definition cstring.inl:408
resources::ResourcedType< T > ResourcedType
Type alias in namespace alib.
constexpr const String EMPTY_STRING
An empty string of the default character type.
Definition string.inl:2234
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
containers::SharedPtr< T, TAllocator > SharedPtr
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2172
characters::nchar nchar
Type alias in namespace alib.
resources::ResourceInfo ResourceInfo
Type alias in namespace alib.
NLocalString< 256 > NString256
Type alias name for #"TLocalString;TLocalString<nchar,256>".
NLocalString< 128 > NString128
Type alias name for #"TLocalString;TLocalString<nchar,128>".
characters::character character
Type alias in namespace alib.
NLocalString< 64 > NString64
Type alias name for #"TLocalString;TLocalString<nchar,64>".
static void Get(String &result, bool isLastField=false)
static void Initialize(const String &input, character innerDelim, character outerDelim, const NString &resourceCategory, const NString &resourceName)
A node of the forward list that contains the custom record data.
Definition records.inl:110
ResourceInfo(const T &sample)
NString Category
The resource category within Pool.
ResourcePool * Pool
The resource pool.
void Set(const T &sample)
ResourceInfo() noexcept=default
Defaulted constructor leaving the fields uninitialized.
NString Name
The resource category within Pool.
const String & Get(const String &name, bool dbgAssert)
void Set(resources::ResourcePool *pool, NString category, NString name)
const String & Get(const NString &name, bool dbgAssert)
static constexpr NString Category()
static constexpr NString Name()
static constexpr ResourcePool * Pool()
static const String & Get()
static const String & Get(const String &resourceName, bool dbgAssert)
static const String & TypeNamePostfix()
static const String & Get(const NString &name, bool dbgAssert)
static const String & TypeNamePrefix()