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