ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
string.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_strings of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8
9//##################################################################################################
10// forward declarations
11//##################################################################################################
12ALIB_EXPORT namespace alib::strings {
13template<typename TChar>
14requires alib::characters::IsCharacter<TChar> class TString;
15template<typename TChar> class TCString;
16template<typename TChar> class TSubstring;
17template<typename TChar, typename TAllocator>
18requires alib::lang::IsAllocator<TAllocator> class TAString;
19template<typename TChar> struct TNumberFormat;
20}
21
22ALIB_EXPORT namespace alib::strings {
23
24/// This the type trait is tested by implicit "auto cast" operators.
25/// Those might be disabled for specific combinations of types.
26///
27/// For example, implicit casting from class \b AString to sibling types \b CString and
28/// \b Substring has to be forbidden, because both are also constructible implicitly from
29/// this class and hence an ambiguity between implicit cast and implicit construction would
30/// arise.
31///
32/// Custom classes (i.e., if derived from class #"str TAString") might encounter
33/// similar problems.
34/// In that case, this type-traits type may be specialized to mitigate compilation issues.
35///
36/// @tparam TFrom The type that allows implicit auto-casts.
37/// @tparam TImOrExplict Denotes if implicit or explicit casts are suppressed.
38/// @tparam TTo The destination type that auto-casts should be suppressed for.
39template<typename TFrom,
40 characters::Policy TImOrExplict,
41 typename TTo>
42struct NoAutoCastTraits : std::false_type {};
43
44// specializations for AString and CString
45template<typename TChar, typename TAllocator> struct NoAutoCastTraits<TAString<TChar, TAllocator>, characters::Policy::Implicit, TCString<TChar> > : std::true_type {};
46template<typename TChar, typename TAllocator> struct NoAutoCastTraits<TAString<TChar, TAllocator>, characters::Policy::Implicit, TSubstring<TChar> > : std::true_type {};
47template<typename TChar> struct NoAutoCastTraits<TCString<TChar> , characters::Policy::Implicit, TSubstring<TChar> > : std::true_type {};
48
49
50/// The maximum length of an \alib string.
51inline constexpr integer MAX_LEN = (std::numeric_limits<integer>::max)();
52
53//==================================================================================================
54/// This class is the base class of all #"alib_strings_classes;ALib string classes".
55/// Objects of this type represent character strings whose data is allocated outside their scope.
56/// In particular, the class does not allocate a character array buffer to store and manipulate
57/// string data.
58///
59/// Once constructed, objects of this class are immutable, except for the possibility to assign
60/// a complete new object value.
61/// This means there is no interface to change the single two data members #".buffer" and
62/// #".length".
63/// The immutable nature of this type is lifted by derived types. While class
64/// #"TSubstring;Substring" allows changing the start and
65/// length of the string represented, class #"TAString;AString" holds a copy of the
66/// data and consequently allows modifying the string stored.<br>
67///
68/// \see
69/// For an introduction into the \alib string classes see this module's
70/// #"alib_mod_strings;Programmer's Manual".
71///
72/// @tparam TChar The #"alib_characters_chars;character type" of this string.
73/// Alias names for specializations along the different character types
74/// are provided in namespace #"alib" with type definitions
75/// #"alib::String",
76/// #"alib::NString",
77/// #"alib::WString",
78/// #"alib::XString",
79/// #"alib::ComplementString", and
80/// #"alib::StrangeString".
81//==================================================================================================
82template<typename TChar>
85{
86 public:
87 /// Exposes template parameter \p{TChar} to the outer world in a \c std compatible way.
88 using value_type = TChar;
89
90 /// The type defining sizes of strings.
92
93 // Debug warnings
94 #if ALIB_DEBUG_STRINGS && !DOXYGEN
95 void dbgCheck() const;
96 #endif
97
98 //################################################################################################
99 // protected fields
100 //################################################################################################
101 protected:
102 #if !DOXYGEN
103 union
104 {
105 const TChar* buffer;
106 TChar* vbuffer;
107 };
108 #else
109 /// Pointer to an array of constant character values.
110 /// This array holds the string that an instance of this type is representing.<br>
111 /// Read access to this field is granted with the method #"Buffer".
112 ///
113 /// For technical reasons, this documentation unfortunately omits the important fact that
114 /// this field is part of an anonymous union declared like this:
115 ///
116 /// union
117 /// {
118 /// const TChar* buffer;
119 /// TChar* vbuffer;
120 /// };
121 ///
122 /// Hence, the field can also be interpreted as a pointer to an array of <b>non-constant</b>
123 /// character values.
124 /// Derived classes might use the sibling version \b vbuffer to modify the contents of
125 /// the string if it is assured that such memory is writable.
126 /// This is, for example, done extensively by the implementation of class
127 /// #"TAString;AString".
128 ///
129 /// \note
130 /// It might not be considered pure/nice OO-design to prepare a feature of specialized
131 /// classes in a non-abstract base class, as done here. But the alternative would have
132 /// been to force derived classes to perform re-interpret casts or even worse tricks
133 /// to rightfully access a writeable buffer.
134 const TChar* buffer;
135 #endif
136
137 /// The length of the character string represented.
138 /// Read access to this field is granted with the method #".Length".
140
141 //################################################################################################
142 // Constructors
143 //################################################################################################
144 public:
145
146 /// Defaulted default constructor. Leaves this instance \b uninitialized and undefined.
147 /// In other words, the methods #"Buffer" and #".Length" give random results.
148 constexpr TString() noexcept =default;
149
150 /// Defaulted copy constructor
151 constexpr TString(const TString&) noexcept =default;
152
153 /// Defaulted move constructor
154 constexpr TString( TString&&) noexcept =default;
155
156 /// Defaulted copy assignment operator.
157 /// @return A reference to <c>this</c> instance.
158 constexpr TString& operator=(const TString&) noexcept =default;
159
160 /// Defaulted move assignment operator.
161 /// @return A reference to <c>this</c> instance.
162 constexpr TString& operator=( TString&&) noexcept =default;
163
164
165 /// Constructor accepting a pointer to a character array and a string length.
166 ///
167 /// @param pBuffer Pointer to the start of the character string to represent.
168 /// @param pLength The length of the character string to represent.
169 constexpr TString( const TChar* pBuffer, integer pLength ) noexcept
170 : buffer(pBuffer)
171 , length(pLength) {}
172
173 /// Constructor accepting \c nullptr. Constructs a nulled string.
174 constexpr TString(lang::IsNullptr auto const &) noexcept
175 : buffer( nullptr ), length( 0 ) {}
176
177// Doxygen (V1.15) would create identical entries in its tag-file, so those are not reachable.
178// On the other hand, it complains if the methods are not doxed. So, we hide them from doxygen.
179#if DOXYGEN
180 /// Templated \b implicit constructor accepting a \c const reference to an object of a
181 /// type that satisfies the concepts #"IsImplicitArraySource" or
182 /// #"IsExplicitArraySource".
183 ///
184 /// Custom types can be enabled for this constructor by specializing the traits-type
185 /// #"ArrayTraits", which is used for both;
186 /// the implementation of the concept, and
187 /// the implementation of this constructor itself.
188 ///
189 /// @tparam T The type of the given \p{src}.
190 /// Requires satisfying the concept #"IsImplicitArraySource".
191 /// Deduced by the compiler.
192 /// @param src The source of the string data to copy.
193 template <typename T>
194 constexpr TString(const T& src) noexcept;
195#else
196 template <typename T>
198 constexpr TString(const T& src) noexcept
199 : buffer( characters::ArrayTraits<std::remove_cv_t<T>,TChar>::Buffer( src ) )
200 , length( characters::ArrayTraits<std::remove_cv_t<T>,TChar>::Length( src ) ) {}
201
202 template<typename T>
204 constexpr explicit TString(const T& src) noexcept
205 : buffer( characters::ArrayTraits<std::remove_cv_t<T>,TChar>::Buffer( src ) )
206 , length( characters::ArrayTraits<std::remove_cv_t<T>,TChar>::Length( src ) ) {}
207#endif
208 /// Templated \b explicit constructor accepting a \b mutable reference to an object of a
209 /// type that satisfies the concept #"IsMutableArraySource".
210 ///
211 /// Custom types can be enabled for this constructor by specializing the traits-type
212 /// #"ArrayTraits", which is used for both;
213 /// the implementation of the concept, and
214 /// the implementation of this constructor itself.
215 ///
216 /// @tparam T The type of the given \p{src}.
217 /// Requires satisfying the concept #"IsMutableArraySource".
218 /// Deduced by the compiler.
219 /// @param src The source of the string data to copy.
220 template<typename T>
222 constexpr explicit TString( T& src) noexcept
223 : buffer( characters::ArrayTraits<std::remove_cv_t<T>,TChar>::Buffer( src ) )
224 , length( characters::ArrayTraits<std::remove_cv_t<T>,TChar>::Length( src ) ) {}
225
226 /// Constructor which allocates memory, copies the given string's contents, and
227 /// lets this string represent this new character array.<br>
228 /// Note that it is up to the using code to duly deallocate the memory, because the
229 /// destructor of this type does not do so.
230 /// @see Methods #".Allocate" and #".Free" for information how to use allocated string objects.
231 ///
232 /// @tparam TAllocator The type of the given \p{allocator}, as prototyped with class
233 /// #"lang::Allocator".
234 /// Requires satisfying the concept #"IsAllocator".
235 /// Deduced by the compiler.
236 /// @param allocator The allocator to use.
237 /// @param copy The string to copy to the new memory allocated.
238 template<typename TAllocator>
240 TString( TAllocator& allocator, const TString<TChar>& copy ) {
241 if( (length= copy.length) == 0 ) {
242 buffer= copy.buffer;
243 return;
244 }
245
246 auto* newBuf= allocator().template AllocArray<TChar>( copy.length);
247 copy.CopyTo( newBuf );
248 buffer= newBuf;
249 }
250
251 //######################################### casting back ########################################
252 // Doxygen (V1.15) would create identical entries in its tag-file, so those are not reachable.
253 // On the other hand, it complains if the methods are not doxed. So, we hide them from doxygen.
254 #if DOXYGEN
255 /// Templated \b implicit <c>cast operator</c> constructing an instance of type \p{T} from
256 /// this string instance.
257 /// This operator requires the type \p{T} satisfying the concepts
258 /// #"IsImplicitArrayCast" and #"IsExplicitArrayCast".
259 ///
260 /// Custom types can be enabled for this operator by specializing the traits-type
261 /// #"ArrayTraits", which is used for both;
262 /// the implementation of the concept, and
263 /// the implementation of this operator itself.
264 ///
265 /// @tparam T The type to implicitly cast this instance to.
266 /// Requires satisfying the concept #"IsImplicitArrayCast".
267 /// Deduced by the compiler.
268 /// @return A value of type \p{T}.
269 template< typename T>
270 constexpr operator T() const;
271#else
272 template< typename T>
276 std::remove_cv_t<T> >::value )
277
278 constexpr operator T() const
280
281 template< typename T>
285 std::remove_cv_t<T> >::value )
286 constexpr explicit operator T() const
288#endif
289
290 //##############################################################################################
291 // Buffer Access, Length, and State
292 //##############################################################################################
293
294 /// Returns a pointer to the first character of the string we are representing.
295 /// \note The string is not guaranteed to be zero-terminated.
296 ///
297 /// @return The start of the character array comprising the string represented by this
298 /// object.
299 constexpr const TChar* Buffer() const { return buffer; }
300
301 /// Returns the length of the string that this object represents.
302 ///
303 /// @return The length of the string represented by this object.
304 constexpr integer Length() const { return length; }
305
306 /// Returns the length of the string if represented as a wide character string.
307 /// If template parameter \p{TChar} equals \c wchar, then this is identical with #Length.
308 /// Otherwise the calculation is done using
309 /// - <em>mbsnrtowcs()</em>
310 /// (without providing a conversion buffer) on glibc platforms (e.g., Linux)
311 /// - <em>MultiByteToWideChar()</em>
312 /// (without providing a conversion buffer) on the Windows platform.
313 ///
314 /// If the conversion fails, \c -1 is returned.
315 ///
316 /// \note
317 /// On GNU/Linux and Mac OS, it might be necessary to invoke standard C method
318 /// <em>setlocale()</em> once, before using this method, to successfully calculate
319 /// the length.
320 /// This by default is done during #"alib_mod_bs;library initialization",
321 /// if performed on class #"Basecamp".
322 ///
323 /// @return The length of string when it was converted to wide characters.
324 /// If counting failed (what means that a corresponding conversion would also fail)
325 /// the #Length is returned.
327
328
329 /// Returns \c true if field #buffer equals \c nullptr, \c false otherwise.
330 /// Note that a \e nulled string is also considered #"IsEmpty;empty".
331 ///
332 /// \see
333 /// Details on the concept of \e nulled and \e empty strings are documented in chapter
334 /// #"alib_strings_details_nulled_vsempty" of this module's
335 /// #"alib_mod_strings;Programmer's Manual".
336 ///
337 /// @return \c true if no buffer is allocated.
338 constexpr bool IsNull() const { return buffer == nullptr; }
339
340 /// Returns \c true if field #buffer does not equal \c nullptr, \c false otherwise.
341 ///
342 /// @return The negated value of method #IsNull.
343 constexpr bool IsNotNull() const { return buffer != nullptr; }
344
345 /// Returns \c true if this string is of zero length.
346 /// Note that a \e nulled string is also considered empty.
347 ///
348 /// \see
349 /// Details on the concept of \e nulled and \e empty strings are documented in chapter
350 /// #"alib_strings_details_nulled_vsempty" of this module's
351 /// #"alib_mod_strings;Programmer's Manual".
352 /// @return \c true if the actual length equals zero.
353 constexpr bool IsEmpty() const { return length == 0; }
354
355 /// Returns \c true if this string has a length of \c 1 or more.
356 /// @return \c true if the actual length does not equal zero.
357 constexpr bool IsNotEmpty() const { return length != 0; }
358
359
360
361
362 /// Returns a new string object representing a substring of the string that this object
363 /// represents.
364 ///
365 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
366 /// If \c false is given, no range check is performed.
367 /// @param regionStart The start of the substring within this string.
368 /// @param regionLength The length of the substring to return.
369 /// Defaults to #"str MAX_LEN".
370 /// @return A string representing a region of this string.
371 template <typename TCheck= CHK>
372 TString<TChar> Substring(integer regionStart, integer regionLength =MAX_LEN ) const {
374
375 if constexpr ( TCheck::value ) {
376 AdjustRegion( regionStart, regionLength );
377 } else {
378 #if ALIB_DEBUG
379 integer rs= regionStart;
380 integer rl= regionLength;
381 AdjustRegion( rs, rl );
382 ALIB_ASSERT_ERROR( rs == regionStart && rl == regionLength, "STRINGS",
383 "Non-checking invocation: ", "Invalid region {}/{} given. Adjusted: {}/{}",
384 regionStart, regionLength, rs, rl )
385 #endif
386 }
387
388 return TString<TChar>( buffer + regionStart, regionLength );
389 }
390
391 //##############################################################################################
392 // Character Access
393 //##############################################################################################
394
395 /// Retrieves the character at the given index. A range check is performed. If this fails,
396 /// \c '\0' is returned.
397 ///
398 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
399 /// If \c false is given, no range check is performed.
400 /// @param idx The index of the character to read.
401 /// @return The character at the given index, or '\0' if index out of range.
402 template <typename TCheck= CHK>
403 TChar CharAt( integer idx ) const {
404 if constexpr ( TCheck::value )
405 return ( idx >= 0 && idx < length ) ? *(buffer + idx )
406 : '\0' ;
407 ALIB_ASSERT_ERROR( idx >= 0 && idx < length, "STRINGS",
408 "Non checking version: Index out of range: 0 <= {} < {}.", idx, length )
409
410 return *(buffer + idx );
411 }
412
413 /// Retrieves the first character.
414 /// In the case of an empty or \e nulled string, '\0' is returned.
415 ///
416 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
417 /// If #"NC" is given, no check for an empty string object is performed.
418 /// @return The first character of the %String.
419 /// If this instance's length is zero, '\0' is returned.
420 template <typename TCheck= CHK>
421 TChar CharAtStart() const {
422 if constexpr ( TCheck::value )
423 return length > 0 ? *(buffer)
424 : '\0';
425
426 ALIB_ASSERT_ERROR( length > 0, "STRINGS", "Non checking invocation on empty string" )
427 return *(buffer);
428 }
429
430
431 /// Retrieves the last character. In the case of an empty string, '\0' is returned.
432 ///
433 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
434 /// If #"NC" is given, no check for an empty or \e nulled object is
435 /// performed.
436 ///
437 /// @return The last character of the %String.
438 /// If this instance's length is zero, '\0' is returned.
439 template <typename TCheck= CHK>
440 TChar CharAtEnd() const {
441 if constexpr ( TCheck::value )
442 return length > 0 ? *(buffer + length - 1)
443 : '\0';
444
445 ALIB_ASSERT_ERROR( length > 0, "STRINGS", "Non checking invocation on empty string" )
446 return *(buffer + length - 1);
447 }
448
449 /// Reads a character at a given index.
450 ///
451 /// \note
452 /// Unlike method #CharAt, this operator does <em>not</em> perform do range check on
453 /// parameter \p{idx}.
454 /// The rationale for this is that derived mutable types (e.g., class %AString),
455 /// may provide a mutable (non-<c>const</c>) version of this operator, returning a
456 /// reference to the character to provide write access. Such reference
457 /// to a character could not be given if the index was out of range.
458 /// This way, a check in the derived type could likewise not be implemented.
459 ///
460 /// \note
461 /// As a result, this operator is equivalent to the non-checking version of method
462 /// #CharAt<\c false>. For safe access to characters in the buffer use #CharAt
463 /// (with template parameter \p{TCheck} being #"CHK") which returns <c>'\0'</c> in the
464 /// case of that \p{idx} is out of bounds.
465 ///
466 /// \note
467 /// Still, in debug-compilations this operator #"alib_mod_assert;raises an ALib error"
468 /// if \p{idx} is out of bounds.
469 ///
470 /// @param idx The index of the character within this object's buffer.
471 /// @returns If the character contained at index \p{idx}.
472 TChar operator[] (integer idx) const {
473 ALIB_ASSERT_ERROR( idx >= 0 && idx < length, "STRINGS",
474 "Index out of bounds: 0 <= {} < {}.", idx, length )
475 return buffer[idx];
476 }
477
478 //##############################################################################################
479 // Hashing
480 //##############################################################################################
481 /// Computes a hash number for the contained string.
482 ///
483 /// \note
484 /// If this library is compiled using C++17, internally this method is using
485 /// <c>std::hash<std::string_view<TChar>></c>. Otherwise a compatible hash function
486 /// is used.
487 /// \see Alternative method #HashcodeIgnoreCase.
488 ///
489 /// @return A hash number which is equal for two instances with the same content.
490 std::size_t Hashcode() const;
491
492 /// Computes a hash number for the contained string converted to upper case letters.
493 ///
494 /// \see Alternative method #Hashcode.
495 ///
496 /// @return A hash number which is equal for two instances with have the same content
497 /// if converted to upper case letters.
498 std::size_t HashcodeIgnoreCase() const;
499
500 //##############################################################################################
501 // Comparison Methods
502 //##############################################################################################
503 /// Compares this string with a
504 /// #"alib_strings_cc_construction_string;string-like object".
505 ///
506 /// \c true is returned if this and the compared string are \e nulled or empty.
507 /// If only one is \e nulled or empty, \c false is returned.
508 ///
509 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
510 /// If #"NC" is given, no check for a \e nulled is performed
511 /// on this string as well as on \p{rhs}.
512 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
513 /// @param rhs The object to compare.
514 ///
515 /// @return \c true, if the contents of this string and the string representation of the
516 /// given \p{rhs} are equal.
517 template <typename TCheck = CHK,
518 lang::Case TSensitivity = lang::Case::Sensitive>
519 bool Equals( const TString<TChar>& rhs ) const {
521
522 if constexpr ( TCheck::value ) {
523 if ( IsNull() && rhs.IsNull() )
524 return true;
525
526 if ( ( IsNull() != rhs.IsNull() ) )
527 return false;
528 }
529 #if ALIB_DEBUG
530 else
531 { // we do not use IsNull() here, for not having a call noted in performance tools
532 ALIB_ASSERT_ERROR( buffer != nullptr,"STRINGS", "Non checking but this is nulled." )
533 ALIB_ASSERT_ERROR( rhs.buffer != nullptr,"STRINGS", "Non checking but rhs is nulled." )
534 }
535 #endif
536
537 if ( length != rhs.length )
538 return false;
539
540 if ( length == 0 )
541 return true;
542
543 if constexpr (TSensitivity == lang::Case::Sensitive ) {
544 // note: this warning 'suddenly' needed to be silenced with GCC 14.2.1, but only in
545 // release builds, in cases where TCheck was true, and thus null-checks
546 // were performed, and in fact this code was not reached.
548 return characters::Equal ( buffer, rhs.buffer, length );
550 }
551 else
553 }
554
555 /// Compares this string with a
556 /// #"alib_strings_cc_construction_string;string-like object".
557 ///
558 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
559 /// If #"NC" is given, no check for a \e nulled object (this) is
560 /// performed and this string must not be of zero length
561 /// (while \p{rhs} might be of zero length).
562 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
563 /// @param rhs The object to compare.
564 ///
565 /// @return
566 /// - 0 if this and \p{rhs} are \e nulled or if both have a length of 0 or if both
567 /// share the same content
568 /// - <0 if this is \e nulled and \p{rhs} is not or if this is smaller than \p{rhs}.
569 /// - >0 if this is not \e nulled but \p{rhs} is or if this is greater than \p{rhs}.
570 template <typename TCheck = CHK,
571 lang::Case TSensitivity = lang::Case::Sensitive>
572 int CompareTo( const TString<TChar>& rhs ) const {
574
575 // check \c nullptr arguments
576 if (TCheck::value && IsNull() ) return rhs.IsNull() ? 0 : -1;
577 if (TCheck::value && rhs.IsNull() ) return +1;
578
579 // zero length ?
580 if ( TCheck::value && length == 0 ) return rhs.length == 0 ? 0 : -1;
581 if ( rhs.length == 0 ) return +1;
582
583 bool thisIsShorter= ( length < rhs.length);
584 integer shortLen = thisIsShorter ? length : rhs.length;
585
586 int cmpVal= (TSensitivity == lang::Case::Sensitive)
587 ? characters::Compare ( buffer, rhs.buffer, shortLen )
588 : characters::CompareIgnoreCase( buffer, rhs.buffer, shortLen );
589
590 if ( cmpVal != 0 || length == rhs.length )
591 return cmpVal;
592 return thisIsShorter ? -1 : 1;
593 }
594
595 /// Compares this string with a region of another
596 /// #"alib_strings_cc_construction_string;string-like object".
597 ///
598 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
599 /// If #"NC" is given, no check for a \e nulled comparison
600 /// object is performed and this string must not be empty.
601 /// Furthermore, no check is performed whether the given region
602 /// fits to parameter \p{rhs}. This also means that the default
603 /// value must not be used with <em>TCheck==#"NC"</em>.
604 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
605 /// @param rhs The string to compare this string with.
606 /// @param rhsRegionStart The start of the region in \p{rhs} to compare this object
607 /// with.
608 /// @param rhsRegionLength The length of the region in \p{rhs} to compare this object
609 /// with.
610 /// Defaults to #"str MAX_LEN".
611 ///
612 /// @return
613 /// - 0 if this and \p{rhs} are \e nulled or if both have a length of 0 or if both
614 /// share the same content
615 /// - <0 if this is \e nulled and \p{rhs} is not or if this is smaller than \p{rhs}.
616 /// - >0 if this is not \e nulled but \p{rhs} is or if this is greater than \p{rhs}.
617 template < typename TCheck = CHK,
618 lang::Case TSensitivity = lang::Case::Sensitive>
619 int CompareTo( const TString& rhs,
620 integer rhsRegionStart,
621 integer rhsRegionLength =MAX_LEN ) const {
622 if constexpr ( TCheck::value ) {
623 TString cmpSub( rhs.buffer, 0);
624 rhs.AdjustRegion( rhsRegionStart, rhsRegionLength );
625 cmpSub.buffer+= rhsRegionStart;
626 cmpSub.length= rhsRegionLength;
627
628 return CompareTo<CHK, TSensitivity>( cmpSub );
629 }
630 else
631 return CompareTo<NC, TSensitivity>( TString( rhs.buffer + rhsRegionStart,
632 rhsRegionLength ) );
633 }
634
635 /// Compares a region of this object with a region of another
636 /// #"alib_strings_cc_construction_string;string-like object".
637 ///
638 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
639 /// If #"NC" is given, no check for a \e nulled comparison
640 /// object is performed and this string must not be empty.
641 /// Furthermore, no check is performed whether the given regions fit
642 /// to this object respectively the other region to the object given
643 /// with parameter \p{rhs}.
644 /// This also means that the default value of \p{regionLength} must
645 /// not be used in this case.
646 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
647 /// @param rhs The string to compare this string with.
648 /// @param rhsRegionStart The start of the region in \p{rhs} to compare this object
649 /// with.
650 /// @param rhsRegionLength The length of the region in \p{rhs} to compare this object
651 /// with.
652 /// @param regionStart The start of the region in this object to compare with
653 /// @param regionLength The length of the region in this object to compare with.
654 /// Defaults to #"str MAX_LEN".
655 ///
656 /// @return
657 /// - 0 if this and \p{rhs} are \e nulled or if both have a length of 0 or if both
658 /// share the same content
659 /// - <0 if this is \e nulled and \p{rhs} is not or if this is smaller than \p{rhs}.
660 /// - >0 if this is not \e nulled but \p{rhs} is or if this is greater than \p{rhs}.
661 template < typename TCheck = CHK,
662 lang::Case TSensitivity = lang::Case::Sensitive>
663 int CompareTo( const TString& rhs,
664 integer rhsRegionStart,
665 integer rhsRegionLength,
666 integer regionStart,
667 integer regionLength =MAX_LEN ) const {
668 if constexpr ( TCheck::value ) {
669 TString cmpSub( rhs.buffer, 0);
670 rhs.AdjustRegion( rhsRegionStart, rhsRegionLength );
671 cmpSub.buffer+= rhsRegionStart;
672 cmpSub.length= rhsRegionLength;
673
674 AdjustRegion( regionStart, regionLength );
675 return TString( buffer + regionStart, regionLength ).CompareTo<CHK, TSensitivity>( cmpSub );
676 }
677
678 return TString( buffer + regionStart, regionLength )
679 .CompareTo<NC, TSensitivity>( TString( rhs.buffer + rhsRegionStart,
680 rhsRegionLength ) );
681 }
682
683 /// Returns \c true, if the contents of the given
684 /// #"alib_strings_cc_construction_string;string-like object" is found at the given
685 /// position.
686 ///
687 /// \note
688 /// The following rules apply:
689 /// - If \p{pos} is out of range or \p{needle} is \e nulled, \c false is returned.
690 /// (This check only done if \p{TCheck} equals #"CHK".)
691 /// - Otherwise, if the length of \p{needle} is 0, \c true is returned.
692 ///
693 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
694 /// If \c <false> is given, no check on parameter
695 /// \p{pos} is performed and \p{needle} must not be \e nulled.
696 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
697 /// @param needle The string to compare with. If it is #"IsEmpty;empty", \c true
698 /// is returned.
699 /// @param pos The position to search for needle.
700 /// @return \c true if \p{needle} is found at the given position. False otherwise.
701 template< typename TCheck = CHK,
702 lang::Case TSensitivity = lang::Case::Sensitive >
703 bool ContainsAt( const TString& needle, integer pos ) const {
704 integer needleLength= needle.length;
706 if constexpr ( TCheck::value ) {
707 if ( pos < 0 || pos + needleLength > length || needle.IsNull () )
708 return false;
709 if ( needleLength == 0 )
710 return true;
711 } else {
712 ALIB_ASSERT_ERROR( pos >= 0 && pos + needleLength <= length,
713 "STRINGS", "Non checking and index out of range: 0 <= {}, {} <= {}.",
714 pos, pos + needleLength, length )
715 ALIB_ASSERT_ERROR( needleLength != 0,
716 "STRINGS", "Non checking and emtpy compare string" )
717 }
718
719 return TSensitivity == lang::Case::Sensitive
720 ? characters::Equal ( buffer + pos, needle.buffer, needleLength )
721 : characters::CompareIgnoreCase( buffer + pos, needle.buffer, needleLength ) == 0 ;
722 }
723
724 /// Returns \c true, if this string starts with the contents of the
725 /// #"alib_strings_cc_construction_string;string-like object" given with parameter
726 /// \p{needle}.
727 /// In the special case that \p{needle} is #"IsEmpty;empty", \c true is returned.
728 ///
729 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
730 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
731 /// If \c <false> is given, the given needle must not be empty
732 /// and must not be longer than this string!
733 /// \p{pos} is performed and \p{needle} must not be \e nulled.
734 /// @param needle The string to compare the start of this string with.
735 /// If \e nulled or empty, \c true is returned.
736 /// @return \c true if \p{needle} is found at the start of this string, \c false otherwise.
737 template<typename TCheck = CHK,
738 lang::Case TSensitivity =lang::Case::Sensitive>
739 bool StartsWith( const TString& needle ) const {
740 if constexpr ( TCheck::value ) {
741 if ( needle.length > length )
742 return false;
743 if ( needle.length == 0 )
744 return true;
745 } else {
746 ALIB_ASSERT_ERROR( needle.length <= length, "STRINGS",
747 "Non checking and needle longer than this string: {} > {}",
748 needle.length, length )
749 ALIB_ASSERT_ERROR( needle.length != 0 , "STRINGS",
750 "Non checking and emtpy needle given." )
751 }
752
753 if constexpr ( TSensitivity == lang::Case::Sensitive )
754 return characters::Equal ( buffer, needle.buffer, needle.length );
755 else
756 return characters::CompareIgnoreCase( buffer, needle.buffer, needle.length ) == 0;
757 }
758
759 /// Returns \c true, if this string ends with the string found in parameter \p{needle}.
760 /// If \p{needle} is #"IsEmpty;empty", \c true is returned.
761 ///
762 /// @tparam TSensitivity Determines if comparison is case-sensitive (the default) or not.
763 /// @param needle The string to compare the end of this string with.
764 /// If \e nulled or empty, \c true is returned.
765 /// @return \c true if \p{needle} is found at the end of this, \c false otherwise.
766 template<typename TCheck = CHK,
767 lang::Case TSensitivity =lang::Case::Sensitive>
768 bool EndsWith( const TString& needle ) const {
769 if constexpr ( TCheck::value ) {
770 if ( needle.length > length )
771 return false;
772 if ( needle.length == 0 )
773 return true;
774 } else {
775 ALIB_ASSERT_ERROR( needle.length <= length, "STRINGS",
776 "Non checking and needle longer than this string: {} > {}",
777 needle.length, length )
778 ALIB_ASSERT_ERROR( needle.length != 0 , "STRINGS",
779 "Non checking and emtpy needle given." )
780 }
781
782 if constexpr ( TSensitivity == lang::Case::Sensitive )
783 return characters::Equal ( buffer + length - needle.length, needle.buffer, needle.length );
784 else
785 return characters::CompareIgnoreCase( buffer + length - needle.length, needle.buffer, needle.length ) == 0;
786 }
787
788 //##############################################################################################
789 // Search
790 //##############################################################################################
791
792 /// Searches a character starting from a given position.
793 ///
794 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
795 /// If \c false is given, no range check is performed.
796 /// @param needle The character to search for.
797 /// @param startIdx The index in this to start searching the character.
798 /// Defaults to \c 0.
799 ///
800 /// @return \c -1 if the character \p{needle} is not found.
801 /// Otherwise the index of its first occurrence.
802 template <typename TCheck= CHK>
803 integer IndexOf( TChar needle, integer startIdx = 0 ) const {
805
806 if constexpr ( TCheck::value ) {
807 // adjust range, if empty return -1
808 if ( startIdx < 0 ) startIdx= 0;
809 else if ( startIdx >= length ) return -1;
810 } else {
811 ALIB_ASSERT_ERROR( startIdx >= 0 && startIdx < length, "STRINGS",
812 "Non checking and index out of range: 0 <= {} < {}.", startIdx, length )
813 }
814
815 const TChar* result= characters::Search( buffer + startIdx, length - startIdx, needle );
816
817 return result != nullptr ? result - buffer
818 : -1;
819 }
820
821 /// Searches a character within a region of this.
822 ///
823 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
824 /// If \c false is given, no range check is performed.
825 /// @param needle The character to search for.
826 /// @param regionStart The start of the region to search the character in.
827 /// @param regionLength The length of the region to search the character in.
828 /// @return \c -1 if the character \p{needle} is not found.
829 /// Otherwise the index of its first occurrence.
830 template <typename TCheck= CHK>
831 integer IndexOf( TChar needle, integer regionStart, integer regionLength ) const {
833
834 if constexpr ( TCheck::value ) {
835 // adjust range, if empty return -1
836 if ( AdjustRegion( regionStart, regionLength ) )
837 return -1;
838 } else {
839 #if ALIB_DEBUG
840 integer rs= regionStart;
841 integer rl= regionLength;
843 && rs == regionStart && rl == regionLength, "STRINGS",
844 "Non-checking invocation: ", "Invalid region {}/{} given. Adjusted: {}/{}",
845 regionStart, regionLength, rs, rl )
846 #endif
847 }
848
849 const TChar* result= characters::Search( buffer + regionStart, regionLength, needle );
850
851 return result != nullptr ? result - buffer
852 : -1;
853 }
854
855 /// Like #"TString::IndexOf(TChar, integer, integer)" but in case the character is not found,
856 /// this method returns the length of this string instead of \c -1.
857 /// Depending on the invocation context, the choice for the right version of this method may
858 /// lead to shorter and more efficient code.
859 ///
860 /// @param needle The character to search for.
861 /// @return This string's #Length if character \p{needle} is not found.
862 /// Otherwise, the index of first occurrence.
863 integer IndexOfOrLength( TChar needle ) const {
865 const TChar* result= characters::Search( buffer, length, needle );
866
867 return result != nullptr ? result - buffer
868 : length;
869 }
870
871 /// Like #"TString::IndexOf(TChar, integer)" but in case the character is not found, this
872 /// method returns the length of this string instead of \c -1.
873 /// Depending on the invocation context, the choice for the right version of this method may
874 /// lead to shorter and more efficient code.
875 ///
876 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
877 /// If \c false is given, no range check is performed.
878 /// @param needle The character to search for.
879 /// @param startIdx The index in this to start searching the character.
880 /// @return This string's #Length if character \p{needle} is not found.
881 /// Otherwise the index of first occurrence.
882 template <typename TCheck= CHK>
883 integer IndexOfOrLength( TChar needle, integer startIdx ) const {
885 if constexpr ( TCheck::value ) {
886 // adjust range, if empty return -1
887 if ( startIdx < 0 ) startIdx= 0;
888 else if ( startIdx >= length ) return length;
889 } else {
890 ALIB_ASSERT_ERROR( startIdx >= 0 && startIdx < length, "STRINGS",
891 "Non checking and index out of range: 0 <= {} < {}.", startIdx, length )
892 }
893
894 const TChar* result= characters::Search( buffer + startIdx, length - startIdx, needle );
895 return result != nullptr ? result - buffer
896 : length;
897 }
898
899 /// Searches a character starting backwards from the end or a given start index.
900 ///
901 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
902 /// If \c false is given, no range check is performed.
903 /// Consequently, in this case, optional parameter startIndex must be
904 /// provided.
905 ///
906 /// @param needle The character to search for.
907 /// @param startIndex The index within this string to start searching the character.
908 /// Defaults to #"str MAX_LEN".
909 ///
910 /// @return \c -1 if the character \p{needle} is not found.
911 /// Otherwise, the index of its last occurrence.
912 template <typename TCheck= CHK>
913 integer LastIndexOf( TChar needle, integer startIndex =MAX_LEN ) const {
915
916 if constexpr ( TCheck::value ) {
917 // adjust range, if empty return -1
918 if ( startIndex < 0 ) return -1;
919 if ( startIndex >= length ) startIndex= length-1;
920 } else {
921 ALIB_ASSERT_ERROR( startIndex >= 0 && startIndex < length, "STRINGS",
922 "Non checking and index out of range: 0 <= {} < {}.", startIndex, length )
923 }
924
925 while( startIndex >= 0 && buffer[ startIndex ] != needle )
926 --startIndex;
927
928 return startIndex;
929 }
930
931 /// Returns the index of the first character which is included, respectively <em>not</em>
932 /// included in a set of characters given as a
933 /// #"alib_strings_cc_construction_string;string-like object".
934 ///
935 /// \note
936 /// In derived class \b %CString, a faster version of this method (using \c std::strpbrk()
937 /// respectively \c std::strspn()) is available.
938 /// So, if performance is important and repetitive calls are performed, it might be
939 /// advisable to hold this string and the needles in a zero-terminated string buffer,
940 /// for example, in an \b AString.
941 ///
942 /// This method searches forwards. For backwards search, see #LastIndexOf.
943 ///
944 /// @tparam TInclusion Denotes whether the search returns the first index that holds a value
945 /// that is included or that is not excluded in the set of needle
946 /// characters.
947 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
948 /// If \c <false> is given, no parameter checks are performed.
949 /// @param needles Pointer to a zero-terminated set of characters to be taken into
950 /// account.
951 /// @param startIdx The index to start the search at. If the given value is less than 0,
952 /// it is set to 0. If it exceeds the length of the string, the length of
953 /// the string is returned.
954 /// Defaults to 0.
955 ///
956 /// @return The index of the first character found which is included, respectively not
957 /// included, in the given set of characters.
958 /// If nothing is found, -1 is returned.
959 template <lang::Inclusion TInclusion,
960 typename TCheck = CHK>
961 integer IndexOfAny( const TString& needles, integer startIdx= 0 ) const {
962 if constexpr ( TCheck::value ) {
963 if ( startIdx < 0 ) startIdx= 0;
964 if ( startIdx >= length ) return -1;
965 } else {
966 ALIB_ASSERT_ERROR( startIdx >= 0 && startIdx < length && needles.Length() != 0,
967 "STRINGS", "Non checking and illegal parameters: 0 <= {} < {}. Needles: {}",
968 startIdx, length, needles.Length() )
969 }
970
971
972 integer idx= TInclusion == lang::Inclusion::Include
973 ? characters::IndexOfAnyIncluded( buffer + startIdx, length - startIdx, needles.Buffer(), needles.Length() )
974 : characters::IndexOfAnyExcluded( buffer + startIdx, length - startIdx, needles.Buffer(), needles.Length() );
975
976 return idx == -1 ? -1 : startIdx + idx;
977 }
978
979 /// Returns the index of the last character which is included, respectively <em>not</em>
980 /// included in set of characters given as a
981 /// #"alib_strings_cc_construction_string;string-like object".
982 ///
983 /// This method searches backwards starting at the given index. For forwards search, see
984 /// #IndexOfAny.
985 ///
986 /// @tparam TInclusion Denotes whether the search returns the first index that holds a value
987 /// that is included or that is not excluded in the set of needle
988 /// characters.
989 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
990 /// If \c <false> is given, no parameter checks are performed.
991 /// @param needles Pointer to a zero-terminated set of characters to be searched for.
992 /// @param startIdx The index to start the search at. The value is cropped to be in
993 /// the bounds of 0 and the length of this object minus one.
994 /// Defaults to #"str MAX_LEN".
995 ///
996 /// @return The index of the first character found which is included, respectively not
997 /// included, in the given set of characters.
998 /// If nothing is found, -1 is returned.
999 template <lang::Inclusion TInclusion,
1000 typename TCheck = CHK>
1001 integer LastIndexOfAny( const TString& needles, integer startIdx =MAX_LEN ) const {
1002 if constexpr ( TCheck::value ) {
1003 if ( startIdx < 0 ) return -1;
1004 if ( startIdx >= length ) startIdx= length - 1;
1005 } else {
1006 ALIB_ASSERT_ERROR( startIdx >= 0 && startIdx < length && needles.Length() != 0,
1007 "STRINGS", "Non checking and illegal parameters: 0 <= {} < {}. Needles: {}",
1008 startIdx, length, needles.Length() )
1009 }
1010
1011 if constexpr ( TInclusion == lang::Inclusion::Include )
1012 return characters::LastIndexOfAnyInclude( Buffer(), startIdx, needles.Buffer(), needles.Length() );
1013 else
1014 return characters::LastIndexOfAnyExclude( Buffer(), startIdx, needles.Buffer(), needles.Length() );
1015 }
1016
1017 /// Searches the given #"alib_strings_cc_construction_string;string-like object"
1018 /// in this string.
1019 ///
1020 /// If \p{needle} is empty, the adjusted value of \p{startIdx} is returned.
1021 ///
1022 /// @tparam TSensitivity Case sensitivity of the comparison.
1023 /// Optional and defaults to \b Case::Sensitive.
1024 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
1025 /// If \c false is given, parameter \p{needle} must not be empty and
1026 /// \p{startIdx} must be in the range of [0 ... #Length() - needle.Length()].
1027 /// This also implies that this string must not be empty.
1028 /// @param needle The string to search for.
1029 /// @param startIdx The index to start the search at. Optional and defaults to \c 0.
1030 /// @param endIdx The index where the search ends. Precisely, the index of the
1031 /// first character that is not found.
1032 /// Defaults to #"str MAX_LEN".
1033 ///
1034 /// @return If the checking of parameters failed or the string is not found, \c -1 is
1035 /// returned. Otherwise the index of the first occurrence of \p{needle}.
1036 template<typename TCheck = CHK,
1037 lang::Case TSensitivity = lang::Case::Sensitive>
1038 integer IndexOf( const TString& needle,
1039 integer startIdx= 0,
1040 integer endIdx = strings::MAX_LEN ) const {
1041 if constexpr ( TCheck::value ) {
1042 if ( needle.IsNull() )
1043 return -1;
1044 if ( startIdx < 0 ) startIdx= 0;
1045 endIdx= (std::min) (endIdx, length - needle.Length() + 1 );
1046 if ( startIdx >= endIdx ) return -1;
1047 } else {
1048 // this default parameter is still corrected. Optimized out anyhow.
1049 if( endIdx == strings::MAX_LEN)
1050 endIdx= length - needle.Length() + 1;
1051
1052 ALIB_ASSERT_ERROR( startIdx >= 0 && startIdx <= length
1053 && endIdx <= length
1054 && needle.IsNotNull(),
1055 "STRINGS", "Non checking and illegal parameters: 0 <= {} <= {}, {} <= {}. Needles: {}",
1056 startIdx, length, endIdx, length, needle.Length() )
1057 }
1058
1059
1060 return indexOfString<TSensitivity>(needle, startIdx, endIdx);
1061 }
1062
1063 /// Searches the first difference of a substring of this string and a
1064 /// #"alib_strings_cc_construction_string;string-like object" given with parameter
1065 /// \p{needle}.
1066 /// If no difference is found, then the index of the first character behind the substring
1067 /// is returned.
1068 ///
1069 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
1070 /// If \c false is given, no range check is performed.
1071 /// @param needle The substring to search for.
1072 /// @param sensitivity Letter case sensitivity of the comparison.
1073 /// Optional and defaults to \b Case::Sensitive.
1074 /// @param startIdx The index in this string to start the comparison with \p{needle}.
1075 /// Optional and defaults to \c 0.
1076 ///
1077 /// @return The index of the first difference found or \p{idx} plus the length of \p{needle}.
1078 template <typename TCheck= CHK>
1080 lang::Case sensitivity = lang::Case::Sensitive,
1081 integer startIdx = 0 ) const {
1083
1084 if constexpr ( TCheck::value ) {
1085 // adjust range, if empty return -1
1086 if ( startIdx < 0 ) startIdx= 0;
1087 else if ( startIdx >= length ) return startIdx;
1088 } else {
1089 ALIB_ASSERT_ERROR( startIdx >= 0 && startIdx < length, "STRINGS",
1090 "Non checking and index out of range: 0 <= {} < {}.", startIdx, length )
1091 }
1092
1093 return characters::IndexOfFirstDifference( buffer + startIdx, length - startIdx,
1094 needle.buffer , needle.length,
1095 sensitivity );
1096 }
1097
1098 /// The method searches the next matching \p{closer}-character while taking nested pairs of
1099 /// \p{opener} and \p{closer} characters into account.
1100 ///
1101 /// Before the invocation of this method, the initial \p{opener} has to be known already,
1102 /// and the given \p{idx} has to point to the first character behind the opener, where the
1103 /// search for an according \p{closer} is to be started.
1104 ///
1105 /// This method is useful to scan a string for pairs of opening and closing brackets, while
1106 /// the found segment may contain nested pairs of the same brackets.
1107 ///
1108 /// @param opener The character that represents the opening bracket, e.g., <c>'{'</c>.
1109 /// @param closer The character that represents the closing bracket, e.g., <c>'}'</c>.
1110 /// @param idx Index pointing to the first character behind the (first) \p{opener}.
1111 ///
1112 /// @return The index of the corresponding closing character. If none was found, a negative
1113 /// value is returned.
1114 /// In the latter case the negated (absolute) value is indicating the number of
1115 /// still open (nested) brackets.
1116 integer IndexOfSegmentEnd( TChar opener, TChar closer, integer idx ) const;
1117
1118
1119 /// Counts all occurrences of character \p{needle} in the range from \p{startPos} to the end
1120 /// of the string.
1121 ///
1122 /// For empty strings \p{needle}, \c 0 is returned.
1123 ///
1124 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
1125 /// If \c false is given, no range check is performed.
1126 /// @param needle The character to search for.
1127 /// @param startPos The index to start the counting.
1128 /// Optional and defaults to \c 0.
1129 ///
1130 /// @return The index of the first difference in \p{needle}.
1131 template <typename TCheck= CHK>
1132 integer CountChar( TChar needle,
1133 integer startPos = 0 ) const {
1135 if constexpr ( TCheck::value ) {
1136 // adjust range, if empty return -1
1137 if ( startPos < 0 ) startPos= 0;
1138 else if ( startPos >= length ) return 0;
1139 } else {
1140 ALIB_ASSERT_ERROR( startPos >= 0 && startPos < length, "STRINGS",
1141 "Non checking and index out of range: 0 <= {} < {}.", startPos, length )
1142 }
1143
1144
1145 int result= 0;
1146 while( startPos < length && (startPos= IndexOf<NC>( needle, startPos )) >= 0 ) {
1147 ++startPos;
1148 ++result;
1149 }
1150
1151 return result;
1152 }
1153
1154 /// Counts all occurrences of character \p{needle}, unless followed by character \p{omit}
1155 /// in the range from \p{startPos} to the end of the string.
1156 ///
1157 /// For empty strings \p{needle}, \c 0 is returned.
1158 /// Also, for empty strings \p{omit}, \c 0 is returned.
1159 ///
1160 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
1161 /// If \c false is given, no range check is performed.
1162 /// @param needle The character to search for.
1163 /// @param omit Omit occurrence if the given character follows.
1164 /// @param startPos The index to start the counting.
1165 ///
1166 /// @return The index of the first difference in \p{needle}.
1167 template <typename TCheck= CHK>
1168 integer CountChar( TChar needle,
1169 TChar omit,
1170 integer startPos ) const {
1172 if constexpr ( TCheck::value ) {
1173 // adjust range, if empty return -1
1174 if ( startPos < 0 ) startPos= 0;
1175 else if ( startPos >= length ) return 0;
1176 } else {
1177 ALIB_ASSERT_ERROR( startPos >= 0 && startPos < length, "STRINGS",
1178 "Non checking and index out of range: 0 <= {} < {}.", startPos, length )
1179 }
1180
1181 int result= 0;
1182 while( startPos < length && (startPos= IndexOf<NC>( needle, startPos )) >= 0 ) {
1183 ++startPos;
1184 if( startPos < Length() && *(buffer + startPos) == omit )
1185 continue;
1186
1187 ++result;
1188 }
1189
1190 return result;
1191 }
1192
1193 /// Counts all occurrences of \p{needle} from \p{startPos} to the end of the string.
1194 ///
1195 /// For empty strings \p{needle}, \c 0 is returned.
1196 ///
1197 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
1198 /// If \c false is given, parameter \p{startIdx} must be valid and
1199 /// \p{needle} must not be empty.
1200 /// @tparam TSensitivity Case sensitivity of the comparison.
1201 /// Optional and defaults to \b Case::Sensitive.
1202 /// @param needle The string to search for.
1203 /// @param startPos The index to start the counting.
1204 /// Optional and defaults to \c 0.
1205 ///
1206 /// @return The index of the first difference in \p{needle}.
1207 template< typename TCheck = CHK,
1208 lang::Case TSensitivity = lang::Case::Sensitive >
1209 integer Count( const TString& needle,
1210 integer startPos = 0 ) const {
1212 integer nLen= needle.Length();
1213 if( nLen == 0 )
1214 return 0;
1215 if constexpr ( TCheck::value ) {
1216 if ( startPos < 0 ) startPos= 0;
1217 if ( startPos + nLen > length ) return 0;
1218 } else {
1219 ALIB_ASSERT_ERROR( startPos >= 0 && startPos < length, "STRINGS",
1220 "Non checking and index out of range: 0 <= {} < {}.", startPos, length )
1221 }
1222
1223 int result= 0;
1224 while( (startPos= IndexOf<NC, TSensitivity>( needle, startPos )) >= 0 ) {
1225 startPos+= needle.Length();
1226 ++result;
1227 }
1228
1229 return result;
1230 }
1231
1232 /// Counts all occurrences of \p{needle}, unless followed by \p{omit}, starting at
1233 /// \p{startPos} to the end of the string.
1234 ///
1235 /// For empty strings \p{needle}, \c 0 is returned.
1236 /// Also, for empty strings \p{omit}, \c 0 is returned.
1237 ///
1238 /// @tparam TSensitivity Case sensitivity of the comparison.
1239 /// Optional and defaults to \b Case::Sensitive.
1240 /// @tparam TCheck Defaults to #"CHK", which is the normal invocation mode.
1241 /// If \c false is given, parameter \p{startPos} must be valid and
1242 /// \p{needle} must not be empty.
1243 /// @param needle The string to search for.
1244 /// @param omit Omit occurrence if the given string follows.
1245 /// @param startPos The index to start the counting.
1246 /// Optional and defaults to \c 0.
1247 ///
1248 /// @return The index of the first difference in \p{needle}.
1249 template<typename TCheck = CHK,
1250 lang::Case TSensitivity = lang::Case::Sensitive>
1251 integer Count( const TString& needle,
1252 const TString& omit,
1253 integer startPos = 0 ) const {
1255 integer nLen= needle.Length();
1256 if ( nLen == 0 )
1257 return 0;
1258 if constexpr ( TCheck::value ) {
1259 if ( startPos < 0 ) startPos= 0;
1260 if ( startPos + nLen > length ) return 0;
1261 } else {
1262 ALIB_ASSERT_ERROR( startPos >= 0 && startPos < length, "STRINGS",
1263 "Non checking and index out of range: 0 <= {} < {}.", startPos, length )
1264 }
1265
1266
1267 int result= 0;
1268 while( (startPos= IndexOf<NC , TSensitivity>( needle, startPos )) >= 0 ) {
1269 startPos+= nLen;
1270 if( startPos + omit.Length() <= Length()
1271 && ( omit.IsEmpty()
1272 || ContainsAt<NC>( omit, startPos ) ) )
1273 continue;
1274
1275 ++result;
1276 }
1277
1278 return result;
1279 }
1280
1281 //##############################################################################################
1282 // Parsing Numbers
1283 //##############################################################################################
1284
1285 /// Parses an integral value consisting of characters \c '0' to \c '9' from this string.
1286 /// <br>Unlike with #ParseInt or #ParseDec, no sign, whitespaces, or group characters are
1287 /// accepted.
1288 ///
1289 /// @param startIdx The start index from where the integral value is tried to be parsed.
1290 /// Optional and defaults to \c 0.
1291 /// @param[out] newIdx Optional output variable that will point to the first character
1292 /// in this string after the float number that was parsed.
1293 /// If parsing fails, it will be set to the value of parameter startIdx.
1294 /// Therefore, this parameter can be used to check if a value was found.
1295 ///
1296 /// @return The parsed value. In addition, the parameter \p{newIdx} is set to point
1297 /// to the first character behind any found integer number.
1298 ALIB_DLL
1299 uint64_t ParseDecDigits( integer startIdx =0, integer* newIdx= nullptr ) const;
1300
1301
1302 /// Parses an integral value in decimal, binary, hexadecimal or octal format from
1303 /// the string
1304 ///
1305 /// Parameter \p{numberFormat} defaults to \c nullptr. This denotes static singleton
1306 /// #"TNumberFormat::Computational;NumberFormat::Computational"
1307 /// which is configured to not using - and therefore also not parsing - grouping characters.
1308 ///
1309 /// Optional output parameter \p{newIdx} may be used to detect if parsing was successful.
1310 /// If not, it receives the value of \p{startIdx}, even if leading whitespaces had been
1311 /// read.
1312 ///
1313 /// For more information on number conversion, see class
1314 /// #"TNumberFormat;NumberFormat". All of its interface methods
1315 /// have a corresponding implementation within class \b %AString.
1316 ///
1317 /// @param startIdx The start index for parsing.
1318 /// Optional and defaults to \c 0.
1319 /// @param numberFormat The format definition. Defaults to \c nullptr.
1320 /// @param[out] newIdx Optional output variable that will point to the first
1321 /// character in this string after the number parsed.
1322 /// On failure, it will be set to the initial value \p{startIdx}.
1323 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1324 /// point to the first character behind the parsed number.
1325 ALIB_DLL
1326 int64_t ParseInt( integer startIdx =0, TNumberFormat<TChar>* numberFormat= nullptr,
1327 integer* newIdx= nullptr ) const;
1328
1329 /// Overloaded version of
1330 /// #"TString::ParseInt(integer, TNumberFormat<TChar>*, integer*)"
1331 /// providing default values for omitted parameters.
1332 ///
1333 /// @param numberFormat The format definition. Defaults to \c nullptr.
1334 /// @param[out] newIdx Optional output variable that will point to the first
1335 /// character in this string after the number parsed.
1336 /// On failure, it will be set to the initial value \c 0.
1337 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1338 /// point to the first character behind the parsed number.
1339 int64_t ParseInt( TNumberFormat<TChar>* numberFormat, integer* newIdx= nullptr ) const
1340 { return ParseInt( 0, numberFormat, newIdx ); }
1341
1342 /// Overloaded version of
1343 /// #"TString::ParseInt(integer, TNumberFormat<TChar>*, integer*)"
1344 /// providing default values for omitted parameters.
1345 ///
1346 /// @param[out] newIdx Optional output variable that will point to the first
1347 /// character in this string after the number parsed.
1348 /// On failure, it will be set to the initial value \c 0.
1349 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1350 /// point to the first character behind the parsed number.
1351 int64_t ParseInt( integer* newIdx ) const { return ParseInt( 0, nullptr, newIdx ); }
1352
1353
1354 /// Overloaded version of
1355 /// #"TString::ParseInt(integer, TNumberFormat<TChar>*, integer*)"
1356 /// providing default values for omitted parameters.
1357 ///
1358 /// @param startIdx The start index for parsing.
1359 /// Optional and defaults to \c 0.
1360 /// @param[out] newIdx Optional output variable that will point to the first
1361 /// character in this string after the number parsed.
1362 /// On failure, it will be set to the initial value \p{startIdx}.
1363 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1364 /// point to the first character behind the parsed number.
1365 int64_t ParseInt( integer startIdx, integer* newIdx ) const
1366 { return ParseInt( startIdx, nullptr, newIdx ); }
1367
1368 /// Reads an unsigned 64-bit integer in standard decimal format at the given position
1369 /// from this %AString.
1370 ///
1371 /// Parameter \p{numberFormat} defaults to \c nullptr. This denotes static singleton
1372 /// #"str TNumberFormat::Computational"
1373 /// which is configured to not using - and therefore also not parsing - grouping characters.
1374 ///
1375 /// Optional output parameter \p{newIdx} may be used to detect if parsing was successful.
1376 /// If not, it receives the value of \p{startIdx}, even if leading whitespaces had been
1377 /// read.
1378 ///
1379 /// Sign literals \c '-' or \c '+' are \b not accepted and parsing will fail.
1380 /// For reading signed integral values, see methods #ParseInt, for floating point numbers
1381 /// #ParseFloat.
1382 ///
1383 /// For more information on number conversion, see class
1384 /// #"TNumberFormat;NumberFormat". All number-parsing interface methods
1385 /// have a corresponding implementation within this class.
1386 ///
1387 /// @param startIdx The start index for parsing.
1388 /// Optional and defaults to \c 0.
1389 /// @param numberFormat The format definition. Defaults to \c nullptr.
1390 /// @param[out] newIdx Optional output variable that will point to the first
1391 /// character in this string after the number parsed.
1392 /// On failure, it will be set to the initial value \p{startIdx}.
1393 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1394 /// point to the first character behind the parsed number.
1395 ALIB_DLL
1396 uint64_t ParseDec( integer startIdx =0, TNumberFormat<TChar>* numberFormat= nullptr,
1397 integer* newIdx= nullptr ) const;
1398
1399 /// Overloaded version of
1400 /// #"TString::ParseDec(integer,TNumberFormat<TChar>*,integer*)const;ParseDec"
1401 /// providing default values for omitted parameters.
1402 ///
1403 /// @param numberFormat The format definition. Defaults to \c nullptr.
1404 /// @param[out] newIdx Optional output variable that will point to the first
1405 /// character in this string after the number parsed.
1406 /// On failure, it will be set to the initial value \c 0.
1407 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1408 /// point to the first character behind the parsed number.
1409 uint64_t ParseDec( TNumberFormat<TChar>* numberFormat, integer* newIdx= nullptr ) const
1410 { return ParseDec( 0, numberFormat, newIdx ); }
1411
1412 /// Overloaded version of
1413 /// #"TString::ParseDec(integer,TNumberFormat<TChar>*,integer*)const;ParseDec"
1414 /// providing default values for omitted parameters.
1415 ///
1416 /// @param[out] newIdx Optional output variable that will point to the first
1417 /// character in this string after the number parsed.
1418 /// On failure, it will be set to the initial value \c 0.
1419 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1420 /// point to the first character behind the parsed number.
1421 uint64_t ParseDec( integer* newIdx ) const { return ParseDec( 0, nullptr, newIdx ); }
1422
1423
1424 /// Overloaded version of
1425 /// #"TString::ParseDec(integer,TNumberFormat<TChar>*,integer*)const;ParseDec"
1426 /// providing default values for omitted parameters.
1427 ///
1428 /// @param startIdx The start index for parsing.
1429 /// Optional and defaults to \c 0.
1430 /// @param[out] newIdx Optional output variable that will point to the first
1431 /// character in this string after the number parsed.
1432 /// On failure, it will be set to the initial value \p{startIdx}.
1433 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1434 /// point to the first character behind the parsed number.
1435 uint64_t ParseDec( integer startIdx, integer* newIdx ) const
1436 { return ParseDec( startIdx, nullptr, newIdx ); }
1437
1438 /// Reads an unsigned 64-bit integer in binary format at the given position
1439 /// from this string.
1440 ///
1441 /// Parameter \p{numberFormat} defaults to \c nullptr. This denotes static singleton
1442 /// #"TNumberFormat::Computational;NumberFormat::Computational"
1443 /// which is configured to not using - and therefore also not parsing - grouping characters.
1444 ///
1445 /// Optional output parameter \p{newIdx} may be used to detect if parsing was successful.
1446 /// If not, it receives the value of \p{startIdx}, even if leading whitespaces had been
1447 /// read.
1448 ///
1449 /// For more information on number conversion, see class
1450 /// #"TNumberFormat;NumberFormat". All number-parsing interface methods
1451 /// have a corresponding implementation within this class.
1452 ///
1453 /// @param startIdx The start index for parsing.
1454 /// Optional and defaults to \c 0.
1455 /// @param numberFormat The format definition. Defaults to \c nullptr.
1456 /// @param[out] newIdx Optional output variable that will point to the first
1457 /// character in this string after the number parsed.
1458 /// On failure, it will be set to the initial value \p{startIdx}.
1459 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1460 /// point to the first character behind the parsed number.
1461 ALIB_DLL
1462 uint64_t ParseBin( integer startIdx =0, TNumberFormat<TChar>* numberFormat= nullptr,
1463 integer* newIdx= nullptr ) const;
1464
1465
1466 /// Overloaded version of
1467 /// #"TString::ParseBin(integer,TNumberFormat<TChar>*,integer*)const;ParseBin"
1468 /// providing default values for omitted parameters.
1469 ///
1470 /// @param numberFormat The format definition. Defaults to \c nullptr.
1471 /// @param[out] newIdx Optional output variable that will point to the first
1472 /// character in this string after the number parsed.
1473 /// On failure, it will be set to the initial value \c 0.
1474 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1475 /// point to the first character behind the parsed number.
1476 uint64_t ParseBin( TNumberFormat<TChar>* numberFormat, integer* newIdx= nullptr ) const
1477 { return ParseBin( 0, numberFormat, newIdx ); }
1478
1479 /// Overloaded version of
1480 /// #"TString::ParseBin(integer,TNumberFormat<TChar>*,integer*)const;ParseBin"
1481 /// providing default values for omitted parameters.
1482 ///
1483 /// @param[out] newIdx Optional output variable that will point to the first
1484 /// character in this string after the number parsed.
1485 /// On failure, it will be set to the initial value \c 0.
1486 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1487 /// point to the first character behind the parsed number.
1488 uint64_t ParseBin( integer* newIdx ) const { return ParseBin( 0, nullptr, newIdx ); }
1489
1490
1491 /// Overloaded version of
1492 /// #"TString::ParseBin(integer,TNumberFormat<TChar>*,integer*)const;ParseBin"
1493 /// providing default values for omitted parameters.
1494 ///
1495 /// @param startIdx The start index for parsing.
1496 /// Optional and defaults to \c 0.
1497 /// @param[out] newIdx Optional output variable that will point to the first
1498 /// character in this string after the number parsed.
1499 /// On failure, it will be set to the initial value \p{startIdx}.
1500 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1501 /// point to the first character behind the parsed number.
1502 uint64_t ParseBin( integer startIdx, integer* newIdx ) const
1503 { return ParseBin( startIdx, nullptr, newIdx ); }
1504
1505 /// Reads an unsigned 64-bit integer in hexadecimal format at the given position
1506 /// from this string.
1507 ///
1508 /// Parameter \p{numberFormat} defaults to \c nullptr. This denotes static singleton
1509 /// #"TNumberFormat::Computational;NumberFormat::Computational"
1510 /// which is configured to not using - and therefore also not parsing - grouping characters.
1511 ///
1512 /// Optional output parameter \p{newIdx} may be used to detect if parsing was successful.
1513 /// If not, it receives the value of \p{startIdx}, even if leading whitespaces had been
1514 /// read.
1515 ///
1516 /// For more information on number conversion, see class
1517 /// #"TNumberFormat;NumberFormat". All number-parsing interface methods
1518 /// have a corresponding implementation within this class.
1519 ///
1520 /// @param startIdx The start index for parsing.
1521 /// Optional and defaults to \c 0.
1522 /// @param numberFormat The format definition. Defaults to \c nullptr.
1523 /// @param[out] newIdx Optional output variable that will point to the first
1524 /// character in this string after the number parsed.
1525 /// On failure, it will be set to the initial value \p{startIdx}.
1526 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1527 /// point to the first character behind the parsed number.
1528 ALIB_DLL
1529 uint64_t ParseHex( integer startIdx =0, TNumberFormat<TChar>* numberFormat= nullptr,
1530 integer* newIdx= nullptr ) const;
1531
1532
1533 /// Overloaded version of
1534 /// #"TString::ParseHex(integer,TNumberFormat<TChar>*,integer*)const;ParseHex"
1535 /// providing default values for omitted parameters.
1536 ///
1537 /// @param numberFormat The format definition. Defaults to \c nullptr.
1538 /// @param[out] newIdx Optional output variable that will point to the first
1539 /// character in this string after the number parsed.
1540 /// On failure, it will be set to the initial value \c 0.
1541 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1542 /// point to the first character behind the parsed number.
1543 uint64_t ParseHex( TNumberFormat<TChar>* numberFormat, integer* newIdx= nullptr ) const
1544 { return ParseHex( 0, numberFormat, newIdx ); }
1545
1546 /// Overloaded version of
1547 /// #"TString::ParseHex(integer,TNumberFormat<TChar>*,integer*)const;ParseHex"
1548 /// providing default values for omitted parameters.
1549 ///
1550 /// @param[out] newIdx Optional output variable that will point to the first
1551 /// character in this string after the number parsed.
1552 /// On failure, it will be set to the initial value \c 0.
1553 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1554 /// point to the first character behind the parsed number.
1555 uint64_t ParseHex( integer* newIdx ) const { return ParseHex( 0, nullptr, newIdx ); }
1556
1557
1558 /// Overloaded version of
1559 /// #"TString::ParseHex(integer,TNumberFormat<TChar>*,integer*)const;ParseHex"
1560 /// providing default values for omitted parameters.
1561 ///
1562 /// @param startIdx The start index for parsing.
1563 /// Optional and defaults to \c 0.
1564 /// @param[out] newIdx Optional output variable that will point to the first
1565 /// character in this string after the number parsed.
1566 /// On failure, it will be set to the initial value \p{startIdx}.
1567 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1568 /// point to the first character behind the parsed number.
1569 uint64_t ParseHex( integer startIdx, integer* newIdx ) const
1570 { return ParseHex( startIdx, nullptr, newIdx ); }
1571
1572 /// Reads an unsigned 64-bit integer in octal format at the given position
1573 /// from this string.
1574 ///
1575 /// Parameter \p{numberFormat} defaults to \c nullptr. This denotes static singleton
1576 /// #"TNumberFormat::Computational;NumberFormat::Computational"
1577 /// which is configured to not using - and therefore also not parsing - grouping characters.
1578 ///
1579 /// Optional output parameter \p{newIdx} may be used to detect if parsing was successful.
1580 /// If not, it receives the value of \p{startIdx}, even if leading whitespaces had been
1581 /// read.
1582 ///
1583 /// For more information on number conversion, see class
1584 /// #"TNumberFormat;NumberFormat". All number-parsing interface methods
1585 /// have a corresponding implementation within this class.
1586 ///
1587 /// @param startIdx The start index for parsing.
1588 /// Optional and defaults to \c 0.
1589 /// @param numberFormat The format definition. Defaults to \c nullptr.
1590 /// @param[out] newIdx Optional output variable that will point to the first
1591 /// character in this string after the number parsed.
1592 /// On failure, it will be set to the initial value \p{startIdx}.
1593 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1594 /// point to the first character behind the parsed number.
1595 ALIB_DLL
1596 uint64_t ParseOct( integer startIdx =0, TNumberFormat<TChar>* numberFormat= nullptr,
1597 integer* newIdx= nullptr ) const;
1598
1599
1600 /// Overloaded version of
1601 /// #"TString::ParseOct(integer,TNumberFormat<TChar>*,integer*)const;ParseOct"
1602 /// providing default values for omitted parameters.
1603 ///
1604 /// @param numberFormat The format definition. Defaults to \c nullptr.
1605 /// @param[out] newIdx Optional output variable that will point to the first
1606 /// character in this string after the number parsed.
1607 /// On failure, it will be set to the initial value \c 0.
1608 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1609 /// point to the first character behind the parsed number.
1610 uint64_t ParseOct( TNumberFormat<TChar>* numberFormat, integer* newIdx= nullptr ) const
1611 { return ParseOct( 0, numberFormat, newIdx ); }
1612
1613 /// Overloaded version of
1614 /// #"TString::ParseOct(integer,TNumberFormat<TChar>*,integer*)const;ParseOct"
1615 /// providing default values for omitted parameters.
1616 ///
1617 /// @param[out] newIdx Optional output variable that will point to the first
1618 /// character in this string after the number parsed.
1619 /// On failure, it will be set to the initial value \c 0.
1620 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1621 /// point to the first character behind the parsed number.
1622 uint64_t ParseOct( integer* newIdx ) const { return ParseOct( 0, nullptr, newIdx ); }
1623
1624
1625 /// Overloaded version of
1626 /// #"TString::ParseOct(integer,TNumberFormat<TChar>*,integer*)const;ParseOct"
1627 /// providing default values for omitted parameters.
1628 ///
1629 /// @param startIdx The start index for parsing.
1630 /// Optional and defaults to \c 0.
1631 /// @param[out] newIdx Optional output variable that will point to the first
1632 /// character in this string after the number parsed.
1633 /// On failure, it will be set to the initial value \p{startIdx}.
1634 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1635 /// point to the first character behind the parsed number.
1636 uint64_t ParseOct( integer startIdx, integer* newIdx ) const
1637 { return ParseOct( startIdx, nullptr, newIdx ); }
1638
1639 /// Reads a floating point number at the given position from this string.
1640 ///
1641 /// Parameter \p{numberFormat} defaults to \c nullptr. This denotes static singleton
1642 /// #"TNumberFormat::Computational;NumberFormat::Computational"
1643 /// which is configured to 'international' settings (not using the locale) and therefore
1644 /// also not parsing grouping characters.
1645 ///
1646 /// Optional output parameter \p{newIdx} may be used to detect if parsing was successful.
1647 /// If not, it receives the value of \p{startIdx}, even if leading whitespaces had been
1648 /// read.
1649 ///
1650 /// For more information on number conversion, see class
1651 /// #"TNumberFormat;NumberFormat". All number-parsing interface methods
1652 /// have a corresponding implementation within this class.
1653 ///
1654 /// @param startIdx The start index for parsing.
1655 /// Optional and defaults to \c 0.
1656 /// @param numberFormat The format definition. Defaults to \c nullptr.
1657 /// @param[out] newIdx Optional output variable that will point to the first
1658 /// character in this string after the number parsed.
1659 /// On failure, it will be set to the initial value \p{startIdx}.
1660 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1661 /// point to the first character behind the parsed number.
1662 ALIB_DLL
1663 double ParseFloat( integer startIdx =0, TNumberFormat<TChar>* numberFormat= nullptr,
1664 integer* newIdx= nullptr ) const;
1665
1666 /// Overloaded version of
1667 /// #"TString::ParseFloat(integer,TNumberFormat<TChar>*,integer*)const;ParseFloat"
1668 /// providing default values for omitted parameters.
1669 ///
1670 /// @param numberFormat The format definition. Defaults to \c nullptr.
1671 /// @param[out] newIdx Optional output variable that will point to the first
1672 /// character in this string after the number parsed.
1673 /// On failure, it will be set to the initial value \c 0.
1674 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1675 /// point to the first character behind the parsed number.
1676 double ParseFloat( TNumberFormat<TChar>* numberFormat, integer* newIdx= nullptr ) const
1677 { return ParseFloat( 0, numberFormat, newIdx ); }
1678
1679 /// Overloaded version of
1680 /// #"TString::ParseFloat(integer,TNumberFormat<TChar>*,integer*)const;ParseFloat"
1681 /// providing default values for omitted parameters.
1682 ///
1683 /// @param[out] newIdx Optional output variable that will point to the first
1684 /// character in this string after the number parsed.
1685 /// On failure, it will be set to the initial value \c 0.
1686 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1687 /// point to the first character behind the parsed number.
1688 double ParseFloat( integer* newIdx ) const { return ParseFloat( 0, nullptr, newIdx ); }
1689
1690
1691 /// Overloaded version of
1692 /// #"TString::ParseFloat(integer,TNumberFormat<TChar>*,integer*)const;ParseFloat"
1693 /// providing default values for omitted parameters.
1694 ///
1695 /// @param startIdx The start index for parsing.
1696 /// Optional and defaults to \c 0.
1697 /// @param[out] newIdx Optional output variable that will point to the first
1698 /// character in this string after the number parsed.
1699 /// On failure, it will be set to the initial value \p{startIdx}.
1700 /// @return The parsed value. In addition, the output parameter \b newIdx is set to
1701 /// point to the first character behind the parsed number.
1702 double ParseFloat( integer startIdx, integer* newIdx ) const
1703 { return ParseFloat( startIdx, nullptr, newIdx ); }
1704
1705 //##############################################################################################
1706 // Conversion
1707 //##############################################################################################
1708
1709 /// Copies this string's contents into a given character buffer.
1710 /// It is the caller's responsibility that \p{dest} is large enough, write-enabled, etc.
1711 ///
1712 /// @param dest The destination buffer.
1713 /// @return The length of this string.
1714 integer CopyTo( TChar* dest ) const {
1715 if (IsNotEmpty())
1716 characters::Copy( buffer, length, dest );
1717 return length;
1718 }
1719
1720 /// Sets this String to a copy of the given string, allocated in given \p{allocator}.
1721 ///
1722 /// \note
1723 /// In case the given \p{copy} is empty or nulled, no allocation is performed and this
1724 /// string is set to empty. Still, the pointer to the buffer is copied.
1725 /// Thus, this string behaves in respect to the method #IsNull the same as the given
1726 /// string \p{copy}.
1727 ///
1728 /// @tparam TAllocator The type of the given \p{allocator}, as prototyped with class
1729 /// #"lang::Allocator". Deduced by the compiler.
1730 /// @param allocator The allocator to use.
1731 /// @param copy The string to copy to the new memory allocated.
1732 template<typename TAllocator>
1734 void Allocate( TAllocator& allocator, const TString<TChar>& copy ) {
1735 if( (length= copy.length) == 0 ) {
1736 buffer= copy.buffer;
1737 return;
1738 }
1739
1740 auto* newBuf= allocator().template AllocArray<TChar>( copy.length );
1741 copy.CopyTo( newBuf );
1742 buffer= newBuf;
1743 }
1744
1745 /// Deallocates this String's memory in \p{allocator} and sets this instance to \e nulled.
1746 /// \note
1747 /// In case this instance is empty or nulled, no deallocation is performed.
1748 /// This should not happen with due usage, which is:
1749 /// - A string is allocated using the method #Allocate on another instance.
1750 /// - For the allocated string, this method is to be called, passing the same allocator.
1751 ///
1752 /// \note
1753 /// Nevertheless, because the method #Allocate likewise does not perform an allocation call
1754 /// in the case an empty string was given, it is a valid use to allocate and later deallocate
1755 /// empty strings.
1756 /// @tparam TAllocator The type of the given \p{allocator}, as prototyped with the class
1757 /// #"lang::Allocator". Deduced by the compiler.
1758 /// @param allocator The allocator to use.
1759 template<typename TAllocator>
1761 void Free( TAllocator& allocator ) {
1762 if( length == 0 || buffer == nullptr )
1763 return;
1764 allocator().FreeArray( buffer, length );
1765 }
1766
1767 public:
1768 //##############################################################################################
1769 // Helper Methods
1770 //##############################################################################################
1771
1772 /// Adjusts a region given as in/out parameters, to fit to this object's range [0..length].
1773 ///
1774 /// @param[in,out] regionStart The proposed region start which might get adjusted to fit to
1775 /// range [0..length].
1776 /// @param[in,out] regionLength The proposed region length which might get adjusted to fit to
1777 /// range [0..length].
1778 ///
1779 /// @return Returns \c true, if the adjusted region is empty.
1780 bool AdjustRegion( integer& regionStart, integer& regionLength ) const {
1781 // if start exceeds string, set to empty range at the end of the string and return true
1782 if (regionStart >= length) {
1783 regionStart= length;
1784 regionLength= 0;
1785 return true; // indicate empty
1786 }
1787
1788 // if negative start, cut it from the length
1789 if (regionStart < 0 ) {
1790 regionLength+= regionStart;
1791 regionStart= 0;
1792 }
1793
1794 // adjust length
1795 if ( regionLength < 0 ) {
1796 regionLength= 0;
1797 return true;
1798 }
1799
1800 integer maxRegionLength= length - regionStart;
1801 if ( regionLength > maxRegionLength )
1802 regionLength= maxRegionLength;
1803
1804 // return true if adjusted region is empty
1805 return regionLength == 0;
1806 }
1807
1808
1809 /// Implementation of \c std::iterator_traits for class \b %TString and its descendents.
1810 /// Base class \b String exposes #const_iterator which uses
1811 /// <c>const TChar*</c> and <c>const TChar&</c> for template types \p{TPointer} and
1812 /// \p{TReference}. Descendant classes may expose a mutable
1813 /// version (e.g., #"TAString;AString").
1814 ///
1815 /// As the name of the class indicates, this iterator satisfies the C++ standard library
1816 /// concept
1817 /// \https{RandomAccessIterator,en.cppreference.com/w/cpp/concept/RandomAccessIterator}.
1818 template<typename TCharConstOrMutable>
1820 {
1821 public:
1822 using iterator_category = std::random_access_iterator_tag; ///< Implementation of <c>std::iterator_traits</c>.
1823 using value_type = TCharConstOrMutable; ///< Implementation of <c>std::iterator_traits</c>.
1824 using difference_type = integer; ///< Implementation of <c>std::iterator_traits</c>.
1825 using pointer = TCharConstOrMutable*; ///< Implementation of <c>std::iterator_traits</c>.
1826 using reference = TCharConstOrMutable&; ///< Implementation of <c>std::iterator_traits</c>.
1827
1828 protected:
1829 /// The pointer into the buffer is all we store.
1830 TCharConstOrMutable* p;
1831 public:
1832 /// Constructor.
1833 /// @param start Pointer to the initial character.
1834 explicit TRandomAccessIterator( TCharConstOrMutable* start = nullptr ) : p(start) {}
1835
1836 //############################ To satisfy concept of InputIterator ##########################
1837
1838 /// Prefix increment operator.
1839 /// @return A reference to this object.
1840 TRandomAccessIterator& operator++() { ++p; return *this; }
1841
1842 /// Postfix increment operator.
1843 /// @return An iterator value that is not increased, yet.
1845
1846 /// Comparison operator.
1847 /// @param other The iterator to compare ourselves to.
1848 /// @return \c true if this and the given iterator are pointing to the same character
1849 /// in the same array, \c false otherwise.
1850 bool operator==(TRandomAccessIterator other) const { return p == other.p; }
1851
1852 /// Comparison operator.
1853 /// @param other The iterator to compare ourselves to.
1854 /// @return \c true if this and given iterator are not equal, \c false otherwise.
1855 bool operator!=(TRandomAccessIterator other) const { return !(*this == other); }
1856
1857 /// Retrieves the character that this iterator references.
1858 /// @return The character value.
1859 TCharConstOrMutable& operator*() const { return *p; }
1860
1861 /// Retrieves the character that this iterator references.
1862 /// @return The character value.
1863 TCharConstOrMutable& operator*() { return *p; }
1864
1865
1866 //######################## To satisfy concept of BidirectionalIterator ######################
1867
1868 /// Prefix decrement operator.
1869 /// @return A reference to this object.
1870 TRandomAccessIterator& operator--() { --p; return *this; }
1871
1872
1873 /// Postfix decrement operator.
1874 /// @return The iterator value prior the decrement operation.
1876
1877
1878 //######################## To satisfy concept of RandomAccessIterator #######################
1879
1880 /// Addition assignment.
1881 /// @param n The value to subtract.
1882 /// @return A reference to this iterator.
1883 TRandomAccessIterator& operator+=(integer n) { p+= n; return *this; }
1884
1885 /// Subtraction assignment.
1886 /// @param n The value to subtract.
1887 /// @return A reference to this iterator.
1888 TRandomAccessIterator& operator-=(integer n) { p-= n; return *this; }
1889
1890 /// Addition.
1891 /// @param n The value to subtract.
1892 /// @return The resulting iterator value.
1894
1895 /// Subtraction.
1896 /// @param n The value to subtract.
1897 /// @return The resulting iterator value.
1899
1900 /// Difference (distance) from this iterator to the given one.
1901 /// @param other The iterator to subtract
1902 /// @return The difference between (distance of) this and the given iterator.
1903 integer operator-(TRandomAccessIterator other) const { return p - other.p; }
1904
1905 /// Subscript operator.
1906 /// @param n The distance to add.
1907 /// @return Reference to the character referenced by this iterator plus the distance
1908 /// given.
1909 TCharConstOrMutable& operator[]( integer n ) const { return *( p + n ); }
1910
1911 //#### Comparison operators (also needed to satisfy concept of RandomAccessIterator) ###
1912
1913 /// Compares this iterator with the given one.
1914 /// @param other The iterator to compare
1915 /// @return \c true if this iterator is \e smaller than \p{other},
1916 /// \c false otherwise.
1917 bool operator<(TRandomAccessIterator other) const { return p < other.p; }
1918
1919 /// Compares this iterator with the given one.
1920 /// @param other The iterator to compare
1921 /// @return \c true if this iterator is \e smaller than or equal to \p{other},
1922 /// \c false otherwise.
1923 bool operator<=(TRandomAccessIterator other) const { return p <= other.p; }
1924
1925 /// Compares this iterator with the given one.
1926 /// @param other The iterator to compare
1927 /// @return \c true if this iterator is \e greater than \p{other},
1928 /// \c false otherwise.
1929 bool operator>(TRandomAccessIterator other) const { return p > other.p; }
1930
1931 /// Compares this iterator with the given one.
1932 /// @param other The iterator to compare
1933 /// @return \c true if this iterator is \e greater than or equal to \p{other},
1934 /// \c false otherwise.
1935 bool operator>=(TRandomAccessIterator other) const { return p >= other.p; }
1936 };
1937
1938 // ###############################################################################################
1939 // Iteration (std::iterator_traits)
1940 // ###############################################################################################
1941
1942 /// The constant iterator exposed by this character container. A Mutable version is
1943 /// found only in descendant classes (e.g., #"TAString;AString").
1944 using const_iterator = TRandomAccessIterator<const TChar>;
1945
1946 /// The constant reverse iterator exposed by this character container. A Mutable version is
1947 /// found only in descendant classes (e.g., #"TAString;AString").
1948 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1949
1950 /// Returns an iterator pointing to a constant character at the start of this string.
1951 /// @return The start of this string.
1953
1954 /// Returns an iterator pointing to a constant character at the start of this string.
1955 /// @return The start of this string.
1957
1958 /// Returns an iterator pointing behind this string.
1959 /// @return The end of this string.
1961
1962 /// Returns an iterator pointing behind this string.
1963 /// @return The end of this string.
1965
1966 /// Returns a reverse iterator pointing to a constant character at the end of this string.
1967 /// @return The last character of this string.
1969
1970 /// Returns a reverse iterator pointing before the start of this string.
1971 /// @return The character before this string.
1973
1974 /// Returns a reverse iterator pointing to a constant character at the end of this string.
1975 /// @return The last character of this string.
1977
1978 /// Returns a reverse iterator pointing before the start of this string.
1979 /// @return The character before this string.
1981
1982 /// Returns #Length as \c size_t. Added for compatibility with the standard library.
1983 /// @return The character before this string.
1984 size_type size() const { return Length(); }
1985
1986 //##############################################################################################
1987
1988 /// Constructs this string using start and end iterators.
1989 ///
1990 /// @param start An iterator referencing the start of the string.
1991 /// @param end An iterator referencing the end of the string.
1993 : buffer( &*start)
1994 , length( end-start >= 0 ? end-start : 0 ) {}
1995
1996 protected:
1997 #if !DOXYGEN
1998 ALIB_ALLOW_DOCS // needed due to a bug in current clang
1999 #endif
2000
2001 /// Implementation of the substring search function.
2002 /// \attention This protected method expects valid (in range) parameters!
2003 /// Parameter \p{endIdx} must be smaller or equal to the length of this string
2004 /// minus the length of \p{needle} plus \c 1.
2005 /// @tparam TSensitivity The letter case sensitivity of the search.
2006 /// @param needle The substring to search.
2007 /// @param startIdx The start index of the search.
2008 /// @param endIdx The index where the search ends. Precisely, the index of the
2009 /// first character that is not found.
2010 /// @return The index of the first occurrence of \p{needle}, respectively \c -1 if not found.
2011 template<lang::Case TSensitivity =lang::Case::Sensitive>
2013 indexOfString( const TString& needle, integer startIdx, integer endIdx ) const;
2014
2015 #if !DOXYGEN
2017 #endif
2018}; // class TString
2019
2020//##################################################################################################
2021// Specializations of ArrayTraits for class TString
2022//##################################################################################################
2023} namespace alib::characters {
2024
2025#if !DOXYGEN
2026template<typename TChar> struct ArrayTraits<strings::TString<TChar>, TChar>
2027{
2028 using T= strings::TString<TChar>;
2029 static constexpr Policy Access = Policy::Implicit;
2030 static constexpr Policy Construction = Policy::Implicit;
2031 static constexpr const TChar* Buffer (const T& src) { return src.Buffer(); }
2032 static constexpr integer Length (const T& src) { return src.Length(); }
2033 static constexpr T Construct(const TChar* b, integer l) { return T(b, l); }
2034};
2035
2036template<typename TChar> struct ZTArrayTraits<strings::TString<TChar>, TChar>
2037{
2038 using T= strings::TString<TChar>;
2039 static constexpr Policy Access = Policy::ExplicitOnly;
2040 static constexpr Policy Construction = Policy::ExplicitOnly;
2041 static constexpr const TChar* Buffer(const T& src) { return src.Buffer(); }
2042 static constexpr integer Length(const T& src) { return src.Length(); }
2043 static constexpr T Construct(const TChar* b, integer l ) { return T(b, l); }
2044};
2045#endif // !DOXYGEN
2046
2047} namespace alib::strings {
2048//##################################################################################################
2049// Comparison Operators
2050//##################################################################################################
2051#if DOXYGEN
2052
2053//==================================================================================================
2054/// Starship operator and <c>==</c> operator for \alib Strings and compatible types.
2055///
2056/// The operators use the methods #"TString::Equals" and #"TString::CompareTo(const TString<TChar>)"
2057/// for evaluation.
2058///
2059/// For performance-critical sections, the original methods may be used where template
2060/// parameter \p{TCheck} can be set to #"NC".
2061///
2062/// \note For avoiding redundancy, only <c>operator<=></c> is listed here in the documentation.
2063/// Internally, different overloads with different requirements are used and, of course,
2064/// <b>operator==</b> is likewise given.<br>
2065/// Furthermore, all operators are available for the derived string types
2066/// \b %CString, \b %AString and \b %Substring likewise.
2067///
2068/// @param lhs The left-hand operand of string-like type.
2069/// @param rhs The right-hand operand of string-like type.
2070/// @returns The result of the comparison.
2071//==================================================================================================
2072auto operator<=>(const String& lhs, const String& rhs);
2073#else
2074
2075// Note(25/01/17):
2076// Clang strangely did not find the following templated operators when they resided in an
2077// exported namespace.
2078// The workaround was to not export the namespace but export each operator instead.
2079// We think this is wrong behavior and not aligned with the language specification.
2080} namespace alib::strings {
2081
2083template<typename TChar>
2084bool operator== (const TString<TChar>& lhs, const TString<TChar>& rhs)
2085{ return lhs. template Equals <CHK, lang::Case::Sensitive>(rhs); }
2086
2088template<typename TChar, typename T>
2089requires (!std::is_same_v<T, TString<TChar>>)
2090bool operator== (const TString<TChar>& lhs, const T& rhs)
2091{ return lhs. template Equals <CHK, lang::Case::Sensitive>(rhs); }
2092
2094template<typename TChar>
2095auto operator<=> (const TString<TChar>& lhs, const TString<TChar>& rhs)
2096{ return lhs. template CompareTo<CHK, lang::Case::Sensitive>(rhs); }
2097
2099template<typename TChar, typename T>
2100requires (!std::same_as<TString<TChar>, T>)
2101auto operator<=> (const TString<TChar>& lhs, const T& rhs)
2102{ return lhs. template CompareTo<CHK, lang::Case::Sensitive>(rhs); }
2103
2104} ALIB_EXPORT namespace alib::strings {
2105#endif // DOXYGEN
2106
2107
2108//##################################################################################################
2109// Template instantiation declarations
2110//##################################################################################################
2111#if !DOXYGEN
2112
2113template<> ALIB_DLL integer TString<nchar>::WStringLength () const;
2114extern template ALIB_DLL integer TString<nchar>::indexOfString<lang::Case::Sensitive>( const TString<nchar >&, integer, integer ) const;
2115extern template ALIB_DLL integer TString<nchar>::indexOfString<lang::Case::Ignore >( const TString<nchar >&, integer, integer ) const;
2116extern template ALIB_DLL integer TString<nchar>::IndexOfSegmentEnd ( nchar, nchar, integer ) const;
2117extern template ALIB_DLL uint64_t TString<nchar>::ParseDecDigits ( integer, integer* ) const;
2118extern template ALIB_DLL int64_t TString<nchar>::ParseInt ( integer, TNumberFormat<nchar>*, integer* ) const;
2119extern template ALIB_DLL uint64_t TString<nchar>::ParseDec ( integer, TNumberFormat<nchar>*, integer* ) const;
2120extern template ALIB_DLL uint64_t TString<nchar>::ParseBin ( integer, TNumberFormat<nchar>*, integer* ) const;
2121extern template ALIB_DLL uint64_t TString<nchar>::ParseHex ( integer, TNumberFormat<nchar>*, integer* ) const;
2122extern template ALIB_DLL uint64_t TString<nchar>::ParseOct ( integer, TNumberFormat<nchar>*, integer* ) const;
2123extern template ALIB_DLL double TString<nchar>::ParseFloat ( integer, TNumberFormat<nchar>*, integer* ) const;
2124extern template ALIB_DLL size_t TString<nchar>::Hashcode () const;
2125extern template ALIB_DLL size_t TString<nchar>::HashcodeIgnoreCase () const;
2126
2127template<> inline integer TString<wchar>::WStringLength () const { return length; }
2128extern template ALIB_DLL integer TString<wchar>::indexOfString<lang::Case::Sensitive>(const TString<wchar>&, integer, integer ) const;
2129extern template ALIB_DLL integer TString<wchar>::indexOfString<lang::Case::Ignore >(const TString<wchar>&, integer, integer ) const;
2130extern template ALIB_DLL integer TString<wchar>::IndexOfSegmentEnd (wchar, wchar, integer ) const;
2131extern template ALIB_DLL uint64_t TString<wchar>::ParseDecDigits ( integer, integer* ) const;
2132extern template ALIB_DLL int64_t TString<wchar>::ParseInt ( integer, TNumberFormat<wchar>*, integer* ) const;
2133extern template ALIB_DLL uint64_t TString<wchar>::ParseDec ( integer, TNumberFormat<wchar>*, integer* ) const;
2134extern template ALIB_DLL uint64_t TString<wchar>::ParseBin ( integer, TNumberFormat<wchar>*, integer* ) const;
2135extern template ALIB_DLL uint64_t TString<wchar>::ParseHex ( integer, TNumberFormat<wchar>*, integer* ) const;
2136extern template ALIB_DLL uint64_t TString<wchar>::ParseOct ( integer, TNumberFormat<wchar>*, integer* ) const;
2137extern template ALIB_DLL double TString<wchar>::ParseFloat ( integer, TNumberFormat<wchar>*, integer* ) const;
2138extern template ALIB_DLL size_t TString<wchar>::Hashcode () const;
2139extern template ALIB_DLL size_t TString<wchar>::HashcodeIgnoreCase () const;
2140
2141template<> ALIB_DLL integer TString<xchar>::WStringLength () const;
2142extern template ALIB_DLL integer TString<xchar>::indexOfString<lang::Case::Sensitive>( const TString<xchar >&, integer, integer ) const;
2143extern template ALIB_DLL integer TString<xchar>::indexOfString<lang::Case::Ignore >( const TString<xchar >&, integer, integer ) const;
2144extern template ALIB_DLL integer TString<xchar>::IndexOfSegmentEnd ( xchar, xchar, integer ) const;
2145extern template ALIB_DLL uint64_t TString<xchar>::ParseDecDigits ( integer, integer* ) const;
2146extern template ALIB_DLL int64_t TString<xchar>::ParseInt ( integer, TNumberFormat<xchar>*, integer* ) const;
2147extern template ALIB_DLL uint64_t TString<xchar>::ParseDec ( integer, TNumberFormat<xchar>*, integer* ) const;
2148extern template ALIB_DLL uint64_t TString<xchar>::ParseBin ( integer, TNumberFormat<xchar>*, integer* ) const;
2149extern template ALIB_DLL uint64_t TString<xchar>::ParseHex ( integer, TNumberFormat<xchar>*, integer* ) const;
2150extern template ALIB_DLL uint64_t TString<xchar>::ParseOct ( integer, TNumberFormat<xchar>*, integer* ) const;
2151extern template ALIB_DLL double TString<xchar>::ParseFloat ( integer, TNumberFormat<xchar>*, integer* ) const;
2152extern template ALIB_DLL size_t TString<xchar>::Hashcode () const;
2153extern template ALIB_DLL size_t TString<xchar>::HashcodeIgnoreCase () const;
2154
2155//##################################################################################################
2156// debug members
2157//##################################################################################################
2158#if ALIB_DEBUG_STRINGS
2159 extern template ALIB_DLL void TString<nchar>::dbgCheck() const;
2160 extern template ALIB_DLL void TString<wchar>::dbgCheck() const;
2161 extern template ALIB_DLL void TString<xchar>::dbgCheck() const;
2162#endif
2163
2164#endif //!DOXYGEN
2165
2166//##################################################################################################
2167// TString aliases
2168//##################################################################################################
2169} ALIB_EXPORT namespace alib {
2170
2171/// Type alias in namespace \b alib.
2172using String = strings::TString <character>;
2173
2174/// Type alias in namespace \b alib.
2175using ComplementString = strings::TString <complementChar>;
2176
2177/// Type alias in namespace \b alib.
2178using StrangeString = strings::TString <strangeChar>;
2179
2180/// Type alias in namespace \b alib.
2181using NString = strings::TString <nchar>;
2182
2183/// Type alias in namespace \b alib.
2184using WString = strings::TString <wchar>;
2185
2186/// Type alias in namespace \b alib.
2187using XString = strings::TString <xchar>;
2188}
2189//##################################################################################################
2190// TString Constants
2191//##################################################################################################
2192namespace alib::strings {
2193#if DOXYGEN
2194//==================================================================================================
2195/// This template class has three specializations for types #"characters::nchar",
2196/// #"characters::wchar", and #"characters::xchar", which each provides the static method
2197/// #EmptyString.
2198/// (The only non-zero-terminated string-constant needed/supported by \alib.)
2199///
2200/// The class is useful to implement methods that are templated with the character type they use
2201/// and that are in need of an empty string instance.
2202///
2203/// In non-templated code (that works with fixed or logical character sizes), the following
2204/// \c constexpr namespace constants are rather to be used:
2205/// #"EMPTY_STRING", #"EMPTY_COMPLEMENT_STRING", #"EMPTY_STRANGE_STRING",
2206/// #"EMPTY_NSTRING", #"EMPTY_WSTRING", and #"EMPTY_XSTRING".
2207///
2208/// Nulled strings are not defined here, as they any time can be constructed using \c nullptr.
2209/// To improve readability, \c constexpr namespace variable are given with #"NULL_STRING",
2210/// #"NULL_COMPLEMENT_STRING", #"NULL_STRANGE_STRING", #"NULL_NSTRING",
2211/// #"NULL_WSTRING", and #"NULL_XSTRING".
2212///
2213/// @see
2214/// Manual chapter #"alib_strings_details_constants".
2215///
2216/// @tparam TChar The #"alib_characters_chars;character type".
2217//==================================================================================================
2218template<typename TChar> struct StringConstantsTraits {
2219 ///@return An empty string.
2220 constexpr static String<TChar> EmptyString();
2221};
2222#else // DOXYGEN
2223template<typename TChar> struct StringConstantsTraits {};
2224template<> struct StringConstantsTraits<nchar> { constexpr static NString EmptyString() { return "" ; } };
2225template<> struct StringConstantsTraits<wchar> { constexpr static WString EmptyString() { return A_WCHAR(""); } };
2226template<> struct StringConstantsTraits<xchar> { constexpr static XString EmptyString() { return A_XCHAR(""); } };
2227#endif //!DOXYGEN
2228
2229} // namespace [alib::strings]
2230
2231ALIB_EXPORT namespace alib {
2232
2233/// An empty string of the default character type.
2235
2236/// An empty string of the complement character type.
2238
2239/// An empty string of the strange character type.
2241
2242/// An empty string of the narrow character type.
2244
2245/// An empty string of the wide character type.
2247
2248/// An empty string of the complement character type.
2250
2251// doxygen would consider the constructor call as a function call
2252#if DOXYGEN
2253/// A \e nulled string of the default character type.
2254inline constexpr String NULL_STRING;
2255
2256/// A \e nulled string of the complement character type.
2258
2259/// A \e nulled string of the strange character type.
2261
2262/// A \e nulled string of the narrow character type.
2263inline constexpr NString NULL_NSTRING;
2264
2265/// A \e nulled string of the wide character type.
2266inline constexpr WString NULL_WSTRING;
2267
2268/// A \e nulled string of the complement character type.
2269inline constexpr XString NULL_XSTRING;
2270#else
2271inline constexpr String NULL_STRING(nullptr);
2272inline constexpr ComplementString NULL_COMPLEMENT_STRING(nullptr);
2273inline constexpr StrangeString NULL_STRANGE_STRING(nullptr);
2274inline constexpr NString NULL_NSTRING(nullptr);
2275inline constexpr WString NULL_WSTRING(nullptr);
2276inline constexpr XString NULL_XSTRING(nullptr);
2277#endif
2278
2279
2280} // namespace [alib]
#define ALIB_DLL
Definition alib.inl:573
#define ALIB_ALLOW_DOCS
Definition alib.inl:662
#define ALIB_POP_ALLOWANCE
Definition alib.inl:673
#define A_XCHAR(STR)
Definition alib.inl:1305
#define ALIB_ALLOW_NULL_POINTER_PASSING
Definition alib.inl:584
#define ALIB_EXPORT
Definition alib.inl:562
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1144
#define A_WCHAR(STR)
Definition alib.inl:1304
TRandomAccessIterator operator--(int)
Definition string.inl:1875
bool operator>=(TRandomAccessIterator other) const
Definition string.inl:1935
TRandomAccessIterator operator+(integer n) const
Definition string.inl:1893
bool operator!=(TRandomAccessIterator other) const
Definition string.inl:1855
TCharConstOrMutable * pointer
Implementation of std::iterator_traits.
Definition string.inl:1825
TRandomAccessIterator & operator-=(integer n)
Definition string.inl:1888
integer operator-(TRandomAccessIterator other) const
Definition string.inl:1903
TCharConstOrMutable value_type
Implementation of std::iterator_traits.
Definition string.inl:1823
bool operator==(TRandomAccessIterator other) const
Definition string.inl:1850
TRandomAccessIterator operator++(int)
Definition string.inl:1844
TCharConstOrMutable & reference
Implementation of std::iterator_traits.
Definition string.inl:1826
TRandomAccessIterator & operator+=(integer n)
Definition string.inl:1883
TRandomAccessIterator(TCharConstOrMutable *start=nullptr)
Definition string.inl:1834
integer difference_type
Implementation of std::iterator_traits.
Definition string.inl:1824
bool operator<=(TRandomAccessIterator other) const
Definition string.inl:1923
TRandomAccessIterator operator-(integer n) const
Definition string.inl:1898
bool operator>(TRandomAccessIterator other) const
Definition string.inl:1929
TCharConstOrMutable & operator*() const
Definition string.inl:1859
bool operator<(TRandomAccessIterator other) const
Definition string.inl:1917
TCharConstOrMutable & operator[](integer n) const
Definition string.inl:1909
std::random_access_iterator_tag iterator_category
Implementation of std::iterator_traits.
Definition string.inl:1822
int64_t ParseInt(integer startIdx, integer *newIdx) const
Definition string.inl:1365
TChar operator[](integer idx) const
Definition string.inl:472
int CompareTo(const TString &rhs, integer rhsRegionStart, integer rhsRegionLength=MAX_LEN) const
Definition string.inl:619
integer CopyTo(TChar *dest) const
Definition string.inl:1714
double ParseFloat(integer startIdx, integer *newIdx) const
Definition string.inl:1702
uint64_t ParseDec(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
constexpr TString(lang::IsNullptr auto const &) noexcept
Constructor accepting nullptr. Constructs a nulled string.
Definition string.inl:174
uint64_t ParseDec(integer startIdx, integer *newIdx) const
Definition string.inl:1435
uint64_t ParseHex(integer startIdx, integer *newIdx) const
Definition string.inl:1569
const_iterator cbegin() const
Definition string.inl:1956
uint64_t ParseBin(integer *newIdx) const
Definition string.inl:1488
const_reverse_iterator rend() const
Definition string.inl:1972
constexpr TString(T &src) noexcept
Definition string.inl:222
uint64_t ParseDecDigits(integer startIdx=0, integer *newIdx=nullptr) const
integer IndexOfOrLength(TChar needle, integer startIdx) const
Definition string.inl:883
constexpr integer Length() const
Definition string.inl:304
constexpr TString(const T &src) noexcept
constexpr bool IsEmpty() const
Definition string.inl:353
bool EndsWith(const TString &needle) const
Definition string.inl:768
TChar CharAtStart() const
Definition string.inl:421
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.inl:803
constexpr bool IsNotNull() const
Definition string.inl:343
const_reverse_iterator rbegin() const
Definition string.inl:1968
uint64_t ParseHex(integer *newIdx) const
Definition string.inl:1555
uint64_t ParseOct(integer startIdx, integer *newIdx) const
Definition string.inl:1636
TString(TAllocator &allocator, const TString< TChar > &copy)
Definition string.inl:240
std::size_t HashcodeIgnoreCase() const
integer IndexOfFirstDifference(const TString &needle, lang::Case sensitivity=lang::Case::Sensitive, integer startIdx=0) const
Definition string.inl:1079
double ParseFloat(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
uint64_t ParseDec(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
Definition string.inl:1409
uint64_t ParseHex(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
Definition string.inl:1543
void Allocate(TAllocator &allocator, const TString< TChar > &copy)
Definition string.inl:1734
TRandomAccessIterator< const CharacterType > const_iterator
Definition string.inl:1944
integer CountChar(TChar needle, TChar omit, integer startPos) const
Definition string.inl:1168
std::size_t Hashcode() const
TChar CharAt(integer idx) const
Definition string.inl:403
const_reverse_iterator crend() const
Definition string.inl:1980
int64_t ParseInt(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
constexpr bool IsNotEmpty() const
Definition string.inl:357
const_iterator end() const
Definition string.inl:1960
bool AdjustRegion(integer &regionStart, integer &regionLength) const
Definition string.inl:1780
bool ContainsAt(const TString &needle, integer pos) const
Definition string.inl:703
integer IndexOfAny(const TString &needles, integer startIdx=0) const
Definition string.inl:961
constexpr const CharacterType * Buffer() const
Definition string.inl:299
uint64_t ParseBin(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
const_iterator begin() const
Definition string.inl:1952
integer IndexOf(const TString &needle, integer startIdx=0, integer endIdx=strings::MAX_LEN) const
Definition string.inl:1038
const_iterator cend() const
Definition string.inl:1964
uint64_t ParseOct(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
Definition string.inl:1610
integer Count(const TString &needle, integer startPos=0) const
Definition string.inl:1209
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition string.inl:1948
integer IndexOf(TChar needle, integer regionStart, integer regionLength) const
Definition string.inl:831
int64_t ParseInt(integer *newIdx) const
Definition string.inl:1351
uint64_t ParseHex(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
integer WStringLength() const
integer indexOfString(const TString &needle, integer startIdx, integer endIdx) const
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
Definition string.inl:913
TChar CharAtEnd() const
Definition string.inl:440
uint64_t ParseBin(integer startIdx, integer *newIdx) const
Definition string.inl:1502
uint64_t ParseOct(integer *newIdx) const
Definition string.inl:1622
double ParseFloat(integer *newIdx) const
Definition string.inl:1688
constexpr TString() noexcept=default
TString(const_iterator &start, const_iterator &end)
Definition string.inl:1992
integer IndexOfSegmentEnd(TChar opener, TChar closer, integer idx) const
int CompareTo(const TString &rhs, integer rhsRegionStart, integer rhsRegionLength, integer regionStart, integer regionLength=MAX_LEN) const
Definition string.inl:663
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.inl:372
uint64_t ParseOct(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
integer CountChar(TChar needle, integer startPos=0) const
Definition string.inl:1132
int64_t ParseInt(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
Definition string.inl:1339
uint64_t ParseDec(integer *newIdx) const
Definition string.inl:1421
const_reverse_iterator crbegin() const
Definition string.inl:1976
bool Equals(const TString< TChar > &rhs) const
Definition string.inl:519
constexpr bool IsNull() const
Definition string.inl:338
bool StartsWith(const TString &needle) const
Definition string.inl:739
integer IndexOfOrLength(TChar needle) const
Definition string.inl:863
void Free(TAllocator &allocator)
Definition string.inl:1761
integer Count(const TString &needle, const TString &omit, integer startPos=0) const
Definition string.inl:1251
integer LastIndexOfAny(const TString &needles, integer startIdx=MAX_LEN) const
Definition string.inl:1001
uint64_t ParseBin(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
Definition string.inl:1476
int CompareTo(const TString< TChar > &rhs) const
Definition string.inl:572
size_type size() const
Definition string.inl:1984
double ParseFloat(TNumberFormat< TChar > *numberFormat, integer *newIdx=nullptr) const
Definition string.inl:1676
const TChar * Search(const TChar *haystack, integer haystackLength, TChar needle)
void Copy(const TChar *src, integer length, TChar *dest)
integer IndexOfFirstDifference(const TChar *haystack, integer haystackLength, const TChar *needle, integer needleLength, lang::Case sensitivity)
integer LastIndexOfAnyExclude(const TChar *haystack, integer startIdx, const TChar *needles, integer needlesLength)
integer LastIndexOfAnyInclude(const TChar *haystack, integer startIdx, const TChar *needles, integer needlesLength)
int Compare(const TChar *lhs, const TChar *rhs, integer cmpLength)
bool Equal(TChar lhs, TRhs rhs)
Definition functions.inl:62
integer IndexOfAnyIncluded(const TChar *haystack, integer haystackLength, const TChar *needles, integer needlesLength)
integer IndexOfAnyExcluded(const TChar *haystack, integer haystackLength, const TChar *needles, integer needlesLength)
int CompareIgnoreCase(const TChar *lhs, const TChar *rhs, integer cmpLength)
Case
Denotes upper and lower case character treatment.
platform_specific integer
Definition integers.inl:32
Inclusion
Denotes how members of a set something should be taken into account.
@ Include
Chooses inclusion.
constexpr integer MAX_LEN
The maximum length of an ALib string.
Definition string.inl:51
auto operator<=>(const String &lhs, const String &rhs)
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
constexpr String NULL_STRING
A nulled string of the default character type.
Definition string.inl:2254
constexpr ComplementString NULL_COMPLEMENT_STRING
A nulled string of the complement character type.
Definition string.inl:2257
strings::TString< wchar > WString
Type alias in namespace alib.
Definition string.inl:2184
constexpr ComplementString EMPTY_COMPLEMENT_STRING
An empty string of the complement character type.
Definition string.inl:2237
strings::TString< xchar > XString
Type alias in namespace alib.
Definition string.inl:2187
constexpr NString EMPTY_NSTRING
An empty string of the narrow character type.
Definition string.inl:2243
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
constexpr WString NULL_WSTRING
A nulled string of the wide character type.
Definition string.inl:2266
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2172
constexpr XString NULL_XSTRING
A nulled string of the complement character type.
Definition string.inl:2269
constexpr StrangeString EMPTY_STRANGE_STRING
An empty string of the strange character type.
Definition string.inl:2240
strings::TString< complementChar > ComplementString
Type alias in namespace alib.
Definition string.inl:2175
constexpr WString EMPTY_WSTRING
An empty string of the wide character type.
Definition string.inl:2246
constexpr StrangeString NULL_STRANGE_STRING
A nulled string of the strange character type.
Definition string.inl:2260
constexpr XString EMPTY_XSTRING
An empty string of the complement character type.
Definition string.inl:2249
strings::TString< strangeChar > StrangeString
Type alias in namespace alib.
Definition string.inl:2178
#define ALIB_STRING_DBG_CHK(instance)
See sibling type #"NC".
Definition chk_nc.inl:33
static constexpr Policy Access
static integer Length(const TStringSource &src)
static TStringSource Construct(const TChar *array, integer length)
static constexpr Policy Construction
static const TChar * Buffer(const TStringSource &src)
static constexpr Policy Construction
static constexpr Policy Access
static const TChar * Buffer(const TStringSource &src)
static TStringSource Construct(const TChar *array, integer length)
static integer Length(const TStringSource &src)
static constexpr String< TChar > EmptyString()