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