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