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