13 template<
class char_t, 
class traits_t>
 
   16     assign(nSymbols, chSymbol);
 
   19 template<
class char_t, 
class traits_t>
 
   22     assign(pszSource, nSymbols);
 
   25 template<
class char_t, 
class traits_t>
 
   31 template<
class char_t, 
class traits_t>
 
   34     assign(std::move(sAnother));
 
   37 template<
class char_t, 
class traits_t>
 
   43 template<
class char_t, 
class traits_t>
 
   44 template<
class fwd_it_t>
 
   47     assign(itFirst, itLast);
 
   50 template<
class char_t, 
class traits_t>
 
   51 template<range_of_t_c<
char_t> 
string_t>
 
   57 template<
class char_t, 
class traits_t>
 
   63 template<
class char_t, 
class traits_t>
 
   66     if (_resize(nSymbols))
 
   67         std::fill(begin(), end(), chSymbol);
 
   70 template<
class char_t, 
class traits_t>
 
   73     if (pszSource && _resize(nSymbols))
 
   74         std::memmove(data(), pszSource, nSymbols * 
sizeof(value_type));
 
   77 template<
class char_t, 
class traits_t>
 
   80     if (pszSource != data())
 
   81         assign(pszSource, traits_t::length(pszSource));
 
   84 template<
class char_t, 
class traits_t>
 
   87     std::swap(m_Data, sAnother.m_Data);
 
   90 template<
class char_t, 
class traits_t>
 
   93     if (sAnother.data() != data())
 
   94         assign(sAnother.data());
 
   97 template<
class char_t, 
class traits_t>
 
   98 template<
class fwd_it_t>
 
  101     if (_resize(std::distance(itFirst, itLast)))
 
  103         fwd_it_t itOther = itFirst;
 
  106         while (itOther != itLast)
 
  115 template<
class char_t, 
class traits_t>
 
  116 template<range_of_t_c<
char_t> 
string_t>
 
  119     assign(sAnother.cbegin(), sAnother.cend());
 
  122 template<
class char_t, 
class traits_t>
 
  123 template<
class... args_t>
 
  124     requires format_acceptable_args_c<char_t, args_t...>
 
  126     const format_string_type<std::type_identity_t<args_t>...> sFormat,
 
  129     vformat(sFormat.get(), std::forward<args_t>(args)...);
 
  132 template<
class char_t, 
class traits_t>
 
  133 template<
class... args_t>
 
  134     requires format_acceptable_args_c<char_t, args_t...>
 
  136     const format_string_type<std::type_identity_t<args_t>...> sFormat,
 
  139     return static_vformat(sFormat.get(), std::forward<args_t>(args)...);
 
  142 template<
class char_t, 
class traits_t>
 
  143 template<
class... args_t>
 
  144     requires format_acceptable_args_c<char_t, args_t...>
 
  146     const format_string_type<std::type_identity_t<args_t>...> sFormat,
 
  149     append_vformat(sFormat.get(), std::forward<args_t>(args)...);
 
  152 template<
class char_t, 
class traits_t>
 
  153 template<
class... args_t>
 
  154     requires format_acceptable_args_c<char_t, args_t...>
 
  158     append_vformat(svFormat, std::forward<args_t>(args)...);
 
  161 template<
class char_t, 
class traits_t>
 
  162 template<
class... args_t>
 
  163     requires format_acceptable_args_c<char_t, args_t...>
 
  165     string_view svFormat,
 
  169     sTemp.
vformat(svFormat, std::forward<args_t>(args)...);
 
  173 template<
class char_t, 
class traits_t>
 
  174 template<
class... args_t>
 
  175     requires format_acceptable_args_c<char_t, args_t...>
 
  178     if (!svFormat.empty())
 
  179         traits_t::format_to(std::back_inserter(*
this), svFormat, std::forward<args_t>(args)...);
 
  182 template<
class char_t, 
class traits_t>
 
  185     std::swap(m_Data, sOther.m_Data);
 
  188 template<
class char_t, 
class traits_t>
 
  190     size_type nCapacity) noexcept
 
  192     if (nCapacity > capacity())
 
  193         _resize(nCapacity, string_resize_type::reserve);
 
  198 template<
class char_t, 
class traits_t>
 
  201     if (!m_Data.is_small() && capacity() > size())
 
  202         _resize(size(), string_resize_type::shrink_to_fit);
 
  205 template<
class char_t, 
class traits_t>
 
  211 template<
class char_t, 
class traits_t>
 
  214     size_type nSymbols) 
const noexcept
 
  216     return string_view(data() + nPos, nSymbols != npos ? nSymbols : size() - nPos);
 
  219 template<
class char_t, 
class traits_t>
 
  222     for (value_type& ch : *
this)
 
  223         ch = traits_t::to_lower(ch);
 
  226 template<
class char_t, 
class traits_t>
 
  229     for (value_type& ch : *
this)
 
  230         ch = traits_t::to_upper(ch);
 
  233 template<
class char_t, 
class traits_t>
 
  239 template<
class char_t, 
class traits_t>
 
  242     return at(size() - 1);
 
  245 template<
class char_t, 
class traits_t>
 
  251 template<
class char_t, 
class traits_t>
 
  257 template<
class char_t, 
class traits_t>
 
  260     return m_Data.capacity();
 
  263 template<
class char_t, 
class traits_t>
 
  266     return std::numeric_limits<size_type>::max() - 1 
 
  270 template<
class char_t, 
class traits_t>
 
  274     std::optional<to_t> optResult = std::nullopt;
 
  277         std::is_trivial_v<to_t> && std::is_standard_layout_v<to_t> || std::is_pointer_v<to_t>
 
  278         || std::is_same_v<to_t, std::nullptr_t>)
 
  280         if constexpr (std::is_same_v<to_t, std::nullptr_t>)
 
  282             if (compare(
QX_STR_PREFIX(
typename traits_t::value_type, 
"nullptr")) == 0)
 
  287         else if constexpr (std::is_same_v<to_t, bool>)
 
  289             if (compare(
QX_STR_PREFIX(
typename traits_t::value_type, 
"true")) == 0)
 
  293             else if (compare(
QX_STR_PREFIX(
typename traits_t::value_type, 
"false")) == 0)
 
  298         else if (
const auto pszSelectedFormat = pszFormat ? pszFormat : get_format_specifier<value_type, to_t>())
 
  300             constexpr string_view svNSpecifier(
QX_STR_PREFIX(value_type, 
"%n"));
 
  301             constexpr 
size_t      nBufferSize = 256;
 
  303             const size_t nFormatSpecifierLength = traits_t::length(pszSelectedFormat);
 
  304             if (nFormatSpecifierLength <= nBufferSize - svNSpecifier.size() - 1)
 
  306                 value_type formatBuffer[nBufferSize];
 
  307                 std::memcpy(formatBuffer, pszSelectedFormat, nFormatSpecifierLength * 
sizeof(value_type));
 
  309                     formatBuffer + nFormatSpecifierLength,
 
  311                     svNSpecifier.size() * 
sizeof(value_type));
 
  312                 formatBuffer[nFormatSpecifierLength + svNSpecifier.size()] = 
QX_CHAR_PREFIX(value_type, 
'\0');
 
  316                 const int nConvertedArgs = traits_t::sscanf(data(), formatBuffer, &result, &nSymbolsRead);
 
  318                 if (
static_cast<size_type
>(nSymbolsRead) == size() && nConvertedArgs == 1)
 
  326         sstream_type ss(data());
 
  334 template<
class char_t, 
class traits_t>
 
  338     size_type nPos) 
const noexcept
 
  340     size_type nCharsToCopy = 0;
 
  342     if (pDest && nCount > 0 && nPos < size())
 
  344         nCharsToCopy = std::min(nPos + nCount, size()) - nPos;
 
  345         std::memcpy(pDest, data() + nPos, nCharsToCopy * 
sizeof(value_type));
 
  351 template<
class char_t, 
class traits_t>
 
  352 template<
class from_t>
 
  356         std::is_trivial_v<from_t> && std::is_standard_layout_v<from_t> || std::is_pointer_v<from_t>
 
  357         || std::is_same_v<from_t, std::nullptr_t>)
 
  359         if constexpr (std::is_same_v<from_t, std::nullptr_t>)
 
  363         else if constexpr (std::is_same_v<from_t, bool>)
 
  371             format(
QX_STR_PREFIX(
typename traits_t::value_type, 
"{}"), data);
 
  382 template<
class char_t, 
class traits_t>
 
  383 template<
class from_t>
 
  388     return std::move(sTemp);
 
  391 template<
class char_t, 
class traits_t>
 
  397 template<
class char_t, 
class traits_t>
 
  402         const size_type nSize       = size();
 
  403         const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszStr) : nSymbols;
 
  405         if (_resize(nSize + nSizeSource))
 
  406             std::memcpy(data() + nSize, pszStr, nSizeSource * 
sizeof(value_type));
 
  410 template<
class char_t, 
class traits_t>
 
  413     append(sStr.data(), sStr.size());
 
  416 template<
class char_t, 
class traits_t>
 
  417 template<
class fwd_it_t>
 
  420     for (
auto it = itBegin; it != itEnd; ++it)
 
  424 template<
class char_t, 
class traits_t>
 
  425 template<range_of_t_c<
char_t> 
string_t>
 
  428     append(sStr.cbegin(), sStr.cend());
 
  431 template<
class char_t, 
class traits_t>
 
  434     value_type chSymbol) noexcept
 
  436     return insert(nPos, &chSymbol, 1);
 
  439 template<
class char_t, 
class traits_t>
 
  442     const_pointer pszWhat,
 
  443     size_type     nSymbols) noexcept
 
  447         const size_type nSize       = size();
 
  448         const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszWhat) : nSymbols;
 
  450         if (nSizeSource > 0 && _resize(nSize + nSizeSource))
 
  452             std::memmove(data() + nPos + nSizeSource, data() + nPos, (nSize - nPos) * 
sizeof(value_type));
 
  453             std::memcpy(data() + nPos, pszWhat, nSizeSource * 
sizeof(value_type));
 
  454             return nPos + nSizeSource;
 
  461 template<
class char_t, 
class traits_t>
 
  462 template<
class fwd_it_t>
 
  465     fwd_it_t  itWhatBegin,
 
  466     fwd_it_t  itWhatEnd) noexcept
 
  468     if constexpr (is_random_access_iterator<fwd_it_t>)
 
  470         return insert(nPos, itWhatBegin.operator->(), 
static_cast<size_type
>(itWhatEnd - itWhatBegin));
 
  474         size_type nWhatSize = 0;
 
  475         for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
 
  478         size_type nStartSymbols = size();
 
  479         if (nWhatSize > 0 && _resize(nStartSymbols + nWhatSize))
 
  481             std::memmove(data() + nPos + nWhatSize, data() + nPos, (nStartSymbols - nPos) * 
sizeof(value_type));
 
  483             size_type nWhatPos = 0;
 
  484             for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
 
  486                 at(nPos + nWhatPos) = *it;
 
  490             return nPos + nWhatSize;
 
  499 template<
class char_t, 
class traits_t>
 
  504     return insert(nPos, sWhat.data(), sWhat.size());
 
  507 template<
class char_t, 
class traits_t>
 
  508 template<range_of_t_c<
char_t> 
string_t>
 
  511     string_t  sWhat) noexcept
 
  513     return insert(
static_cast<size_type
>(nPos), sWhat.cbegin(), sWhat.cend());
 
  516 template<
class char_t, 
class traits_t>
 
  519     value_type     chSymbol) noexcept
 
  521     return insert(
static_cast<size_type
>(itPos - cbegin()), chSymbol);
 
  524 template<
class char_t, 
class traits_t>
 
  527     const_pointer  pszWhat,
 
  528     size_type      nSymbols) noexcept
 
  530     return insert(
static_cast<size_type
>(itPos - cbegin()), pszWhat, nSymbols);
 
  533 template<
class char_t, 
class traits_t>
 
  538     return insert(
static_cast<size_type
>(itPos - cbegin()), sWhat.data(), sWhat.size());
 
  541 template<
class char_t, 
class traits_t>
 
  542 template<
class fwd_it_t>
 
  545     fwd_it_t       itWhatBegin,
 
  546     fwd_it_t       itWhatEnd) noexcept
 
  548     return insert(
static_cast<size_type
>(itPos - begin()), itWhatBegin, itWhatEnd);
 
  551 template<
class char_t, 
class traits_t>
 
  552 template<range_of_t_c<
char_t> 
string_t>
 
  555     string_t       sWhat) noexcept
 
  557     return insert(
static_cast<size_type
>(itPos - begin()), sWhat.cbegin(), sWhat.cend());
 
  560 template<
class char_t, 
class traits_t>
 
  563     insert(size(), &chSymbol, 1);
 
  566 template<
class char_t, 
class traits_t>
 
  569     insert(0, &chSymbol, 1);
 
  572 template<
class char_t, 
class traits_t>
 
  575     if (
const typename iterator::difference_type nCharsToErase = itLast - itFirst; nCharsToErase > 0)
 
  577         const size_type nStartSize     = size();
 
  578         const size_type nSymbolsToCopy = itLast != end() ? traits_t::length(itLast.operator->()) : 0;
 
  580         if (nSymbolsToCopy > 0)
 
  582             std::memmove(itFirst.operator->(), itLast.operator->(), nSymbolsToCopy * 
sizeof(value_type));
 
  585         if (
static_cast<typename iterator::difference_type
>(nStartSize) >= nCharsToErase)
 
  587             _resize(nStartSize - nCharsToErase);
 
  592 template<
class char_t, 
class traits_t>
 
  595     erase(itPos, itPos + 1);
 
  598 template<
class char_t, 
class traits_t>
 
  604 template<
class char_t, 
class traits_t>
 
  610 template<
class char_t, 
class traits_t>
 
  613     value_type chRet = back();
 
  618 template<
class char_t, 
class traits_t>
 
  621     value_type chRet = front();
 
  626 template<
class char_t, 
class traits_t>
 
  632             return traits_t::is_space(ch);
 
  636 template<
class char_t, 
class traits_t>
 
  638     value_type chSymbol) noexcept
 
  641         [chSymbol](value_type ch)
 
  643             return ch == chSymbol;
 
  647 template<
class char_t, 
class traits_t>
 
  649     const_pointer pszStr) noexcept
 
  654             [pszStr](value_type ch)
 
  656                 for (size_type j = 0; pszStr[j] != 
QX_CHAR_PREFIX(value_type, 
'\0'); ++j)
 
  671 template<
class char_t, 
class traits_t>
 
  673     const_pointer pszStr,
 
  674     size_type     nStrSize) noexcept
 
  679             [pszStr, nStrSize](value_type ch)
 
  681                 for (size_type j = 0; j < nStrSize; ++j)
 
  694 template<
class char_t, 
class traits_t>
 
  698     return trim_left(sStr.data(), sStr.size());
 
  701 template<
class char_t, 
class traits_t>
 
  702 template<
class fwd_it_t>
 
  705     fwd_it_t itEnd) noexcept
 
  708         [itBegin, itEnd](
auto ch)
 
  710             for (
auto it = itBegin; it != itEnd; ++it)
 
  718 template<
class char_t, 
class traits_t>
 
  719 template<range_of_t_c<
char_t> 
string_t>
 
  721     const string_t& sStr) noexcept
 
  723     return trim_left(sStr.cbegin(), sStr.cend());
 
  726 template<
class char_t, 
class traits_t>
 
  732             return traits_t::is_space(ch);
 
  736 template<
class char_t, 
class traits_t>
 
  738     value_type chSymbol) noexcept
 
  741         [chSymbol](value_type ch)
 
  743             return ch == chSymbol;
 
  747 template<
class char_t, 
class traits_t>
 
  749     const_pointer pszStr) noexcept
 
  754             [pszStr](value_type ch)
 
  756                 for (size_type j = 0; pszStr[j] != 
QX_CHAR_PREFIX(value_type, 
'\0'); ++j)
 
  771 template<
class char_t, 
class traits_t>
 
  773     const_pointer pszStr,
 
  774     size_type     nStrSize) noexcept
 
  779             [pszStr, nStrSize](value_type ch)
 
  781                 for (size_type j = 0; j < nStrSize; ++j)
 
  794 template<
class char_t, 
class traits_t>
 
  798     return trim_right(sStr.data(), sStr.size());
 
  801 template<
class char_t, 
class traits_t>
 
  802 template<
class fwd_it_t>
 
  805     fwd_it_t itEnd) noexcept
 
  808         [itBegin, itEnd](
auto ch)
 
  810             for (
auto it = itBegin; it != itEnd; ++it)
 
  818 template<
class char_t, 
class traits_t>
 
  819 template<range_of_t_c<
char_t> 
string_t>
 
  821     const string_t& sStr) noexcept
 
  823     return trim_right(sStr.cbegin(), sStr.cend());
 
  826 template<
class char_t, 
class traits_t>
 
  832             return traits_t::is_space(ch);
 
  836 template<
class char_t, 
class traits_t>
 
  838     value_type chSymbol) noexcept
 
  841         [chSymbol](value_type ch)
 
  843             return ch == chSymbol;
 
  847 template<
class char_t, 
class traits_t>
 
  849     const_pointer pszStr) noexcept
 
  854             [pszStr](value_type ch)
 
  856                 for (size_type j = 0; pszStr[j] != 
QX_CHAR_PREFIX(value_type, 
'\0'); ++j)
 
  871 template<
class char_t, 
class traits_t>
 
  873     const_pointer pszStr,
 
  874     size_type     nStrSize) noexcept
 
  879             [pszStr, nStrSize](value_type ch)
 
  881                 for (size_type j = 0; j < nStrSize; ++j)
 
  894 template<
class char_t, 
class traits_t>
 
  898     return trim(sStr.data(), sStr.size());
 
  901 template<
class char_t, 
class traits_t>
 
  902 template<
class fwd_it_t>
 
  905     fwd_it_t itEnd) noexcept
 
  908         [itBegin, itEnd](
auto ch)
 
  910             for (
auto it = itBegin; it != itEnd; ++it)
 
  918 template<
class char_t, 
class traits_t>
 
  919 template<range_of_t_c<
char_t> 
string_t>
 
  921     const string_t& sStr) noexcept
 
  923     return trim(sStr.cbegin(), sStr.cend());
 
  926 template<
class char_t, 
class traits_t>
 
  930     size_type  nEnd) noexcept
 
  932     size_type nPos = find(chSymbol, nBegin, nEnd);
 
  940 template<
class char_t, 
class traits_t>
 
  942     const_pointer pszStr,
 
  945     size_type     nStrSize) noexcept
 
  949         const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
 
  950         const size_type nPos          = find(pszStr, nBegin, nLocalStrSize, nEnd);
 
  953             erase(nPos, nLocalStrSize);
 
  963 template<
class char_t, 
class traits_t>
 
  967     size_type           nEnd) noexcept
 
  969     const size_type nPos = find(sStr, nBegin, nEnd);
 
  972         erase(nPos, sStr.size());
 
  977 template<
class char_t, 
class traits_t>
 
  978 template<
class fwd_it_t>
 
  983     size_type nEnd) noexcept
 
  985     const size_type nPos = find(itBegin, itEnd, nBegin, nEnd);
 
  988         erase(nPos, 
static_cast<size_type
>(std::distance(itBegin, itEnd)));
 
  993 template<
class char_t, 
class traits_t>
 
  994 template<range_of_t_c<
char_t> 
string_t>
 
  996     const string_t& sStr,
 
  998     size_type       nEnd) noexcept
 
 1000     return remove(sStr.cbegin(), sStr.cend(), nBegin, nEnd);
 
 1003 template<
class char_t, 
class traits_t>
 
 1006     return remove(chSymbol, 
static_cast<size_type
>(0), 
static_cast<size_type
>(1)) != npos;
 
 1009 template<
class char_t, 
class traits_t>
 
 1012     return remove(pszStr, 
static_cast<size_type
>(0), nStrSize, nStrSize) != npos;
 
 1015 template<
class char_t, 
class traits_t>
 
 1018     return remove(sStr, 
static_cast<size_type
>(0), sStr.size()) != npos;
 
 1021 template<
class char_t, 
class traits_t>
 
 1022 template<
class fwd_it_t>
 
 1025     return remove(itBegin, itEnd, 
static_cast<size_type
>(0), 
static_cast<size_type
>(std::distance(itBegin, itEnd)))
 
 1029 template<
class char_t, 
class traits_t>
 
 1030 template<range_of_t_c<
char_t> 
string_t>
 
 1033     return remove_prefix(sStr.cbegin(), sStr.cend());
 
 1036 template<
class char_t, 
class traits_t>
 
 1039     const size_type nSize = size();
 
 1040     return remove(chSymbol, nSize - 1, nSize) != npos;
 
 1043 template<
class char_t, 
class traits_t>
 
 1048         const size_type nSize         = size();
 
 1049         const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
 
 1051         return remove(pszStr, nSize - nLocalStrSize, nSize, nLocalStrSize) != npos;
 
 1059 template<
class char_t, 
class traits_t>
 
 1062     return remove_suffix(sStr.data(), sStr.size());
 
 1065 template<
class char_t, 
class traits_t>
 
 1066 template<
class fwd_it_t>
 
 1069     const size_type nSize = size();
 
 1070     return remove(itBegin, itEnd, nSize - 
static_cast<size_type
>(std::distance(itBegin, itEnd)), nSize) != npos;
 
 1073 template<
class char_t, 
class traits_t>
 
 1074 template<range_of_t_c<
char_t> 
string_t>
 
 1077     return remove_suffix(sStr.cbegin(), sStr.cend());
 
 1080 template<
class char_t, 
class traits_t>
 
 1082     value_type chSymbol,
 
 1084     size_type  nEnd) noexcept
 
 1086     size_type nOccurrences       = 0;
 
 1087     size_type nLastOccurrencePos = nBegin;
 
 1092         nLastOccurrencePos = remove(chSymbol, nLastOccurrencePos, nEnd);
 
 1093     } 
while (nLastOccurrencePos != npos);
 
 1095     return nOccurrences - 1;
 
 1098 template<
class char_t, 
class traits_t>
 
 1100     const_pointer pszStr,
 
 1103     size_type     nStrSize) noexcept
 
 1107         size_type nOccurrences       = 0;
 
 1108         size_type nLastOccurrencePos = nBegin;
 
 1113             nLastOccurrencePos = remove(pszStr, nLastOccurrencePos, nEnd, nStrSize);
 
 1114         } 
while (nLastOccurrencePos != npos);
 
 1116         return nOccurrences - 1;
 
 1124 template<
class char_t, 
class traits_t>
 
 1128     size_type           nEnd) noexcept
 
 1130     return remove_all(sStr.data(), nBegin, nEnd, sStr.size());
 
 1133 template<
class char_t, 
class traits_t>
 
 1134 template<
class fwd_it_t>
 
 1139     size_type nEnd) noexcept
 
 1141     size_type nOccurrences       = 0;
 
 1142     size_type nLastOccurrencePos = nBegin;
 
 1147         nLastOccurrencePos = remove(itFirst, itLast, nLastOccurrencePos, nEnd);
 
 1148     } 
while (nLastOccurrencePos != npos);
 
 1150     return nOccurrences - 1;
 
 1153 template<
class char_t, 
class traits_t>
 
 1154 template<range_of_t_c<
char_t> 
string_t>
 
 1156     const string_t& sStr,
 
 1158     size_type       nEnd) noexcept
 
 1160     return remove_all(sStr.cbegin(), sStr.cend(), nBegin, nEnd);
 
 1163 template<
class char_t, 
class traits_t>
 
 1167     const_pointer pszReplace,
 
 1168     size_t        nReplaceSize) noexcept
 
 1170     const size_type nStartSize = size();
 
 1171     const size_type nNewSize   = nStartSize - nSize + nReplaceSize;
 
 1173     _resize(nNewSize, string_resize_type::reserve);
 
 1176         data() + nBegin + nReplaceSize,
 
 1177         data() + nBegin + nSize,
 
 1178         (nStartSize - nBegin - nSize) * 
sizeof(value_type));
 
 1180     std::memcpy(data() + nBegin, pszReplace, nReplaceSize * 
sizeof(value_type));
 
 1184     return nBegin + nReplaceSize;
 
 1187 template<
class char_t, 
class traits_t>
 
 1188 template<
class replace_
string_t>
 
 1192     const replace_string_t& sReplace) noexcept
 
 1194     return replace(nBegin, nSize, _get_string_view_like_data(sReplace), _get_string_view_like_size(sReplace));
 
 1197 template<
class char_t, 
class traits_t>
 
 1198 template<
class find_
string_t, 
class replace_
string_t>
 
 1200     const find_string_t&    sFind,
 
 1201     const replace_string_t& sReplace,
 
 1203     size_type               nEnd) noexcept
 
 1205     if (size_type nPos = find(sFind, nBegin, nEnd); nPos != npos)
 
 1209             _get_string_view_like_size(sFind),
 
 1210             _get_string_view_like_data(sReplace),
 
 1211             _get_string_view_like_size(sReplace));
 
 1219 template<
class char_t, 
class traits_t>
 
 1220 template<
class find_
string_t, 
class replace_
string_t>
 
 1222     const find_string_t&    sFind,
 
 1223     const replace_string_t& sReplace,
 
 1225     size_type               nEnd) noexcept
 
 1227     size_type nOccurrences = 0;
 
 1228     size_type nPos         = nBegin;
 
 1232         nPos = replace(sFind, sReplace, nPos, nEnd);
 
 1235     } 
while (nPos != npos);
 
 1237     return nOccurrences;
 
 1240 template<
class char_t, 
class traits_t>
 
 1243     return compare(&chSymbol, 1);
 
 1246 template<
class char_t, 
class traits_t>
 
 1249     return traits_t::compare(data(), pszStr);
 
 1252 template<
class char_t, 
class traits_t>
 
 1255     return traits_t::compare_n(data(), pStr, nSymbols);
 
 1258 template<
class char_t, 
class traits_t>
 
 1261     return compare(sStr.data(), sStr.size());
 
 1264 template<
class char_t, 
class traits_t>
 
 1265 template<
class fwd_it_t>
 
 1268     return iter_strcmp(cbegin(), cend(), itBegin, itEnd);
 
 1271 template<
class char_t, 
class traits_t>
 
 1272 template<range_of_t_c<
char_t> 
string_t>
 
 1275     return compare(sStr.cbegin(), sStr.cend());
 
 1278 template<
class char_t, 
class traits_t>
 
 1280     value_type chSymbol,
 
 1282     size_type  nEnd) 
const noexcept
 
 1287         [chSymbol](const_pointer pCurrentChar)
 
 1289             return *pCurrentChar == chSymbol;
 
 1293 template<
class char_t, 
class traits_t>
 
 1295     const_pointer pszWhat,
 
 1297     size_type     nWhatSize,
 
 1298     size_type     nEnd) 
const noexcept
 
 1302         const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
 
 1307             [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
 
 1309                 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
 
 1318 template<
class char_t, 
class traits_t>
 
 1322     size_type           nEnd) 
const noexcept
 
 1324     return find(sWhat.data(), nBegin, sWhat.size(), nEnd);
 
 1327 template<
class char_t, 
class traits_t>
 
 1328 template<
class fwd_it_t>
 
 1330     fwd_it_t  itWhatBegin,
 
 1333     size_type nEnd) 
const noexcept
 
 1335     const size_t nWhatSize = itWhatEnd - itWhatBegin;
 
 1339         [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
 
 1341             const size_t nStart = 
static_cast<size_type
>(pCurrentChar - data());
 
 1350 template<
class char_t, 
class traits_t>
 
 1351 template<range_of_t_c<
char_t> 
string_t>
 
 1355     size_type nEnd) 
const noexcept
 
 1357     return find(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
 
 1360 template<
class char_t, 
class traits_t>
 
 1362     value_type chSymbol,
 
 1364     size_type  nEnd) 
const noexcept
 
 1369         [chSymbol](const_pointer pCurrentChar)
 
 1371             return *pCurrentChar == chSymbol;
 
 1375 template<
class char_t, 
class traits_t>
 
 1377     const_pointer pszWhat,
 
 1379     size_type     nWhatSize,
 
 1380     size_type     nEnd) 
const noexcept
 
 1384         const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
 
 1389             [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
 
 1391                 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
 
 1400 template<
class char_t, 
class traits_t>
 
 1404     size_type           nEnd) 
const noexcept
 
 1406     return rfind(sWhat.data(), nBegin, sWhat.size(), nEnd);
 
 1409 template<
class char_t, 
class traits_t>
 
 1410 template<
class fwd_it_t>
 
 1412     fwd_it_t  itWhatBegin,
 
 1415     size_type nEnd) 
const noexcept
 
 1417     const size_t nWhatSize = itWhatEnd - itWhatBegin;
 
 1421         [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
 
 1423             const size_t nStart = 
static_cast<size_type
>(pCurrentChar - data());
 
 1432 template<
class char_t, 
class traits_t>
 
 1433 template<range_of_t_c<
char_t> 
string_t>
 
 1437     size_type nEnd) 
const noexcept
 
 1439     return rfind(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
 
 1442 template<
class char_t, 
class traits_t>
 
 1444     value_type chSymbol,
 
 1445     size_type  nBegin) 
const noexcept
 
 1447     return find(chSymbol, nBegin);
 
 1450 template<
class char_t, 
class traits_t>
 
 1452     const_pointer pszWhat,
 
 1454     size_type     nWhatSize) 
const noexcept
 
 1458         return _find_first_of(
 
 1460             pszWhat + nWhatSize,
 
 1462             [](const_pointer pChar)
 
 1473 template<
class char_t, 
class traits_t>
 
 1475     const_pointer pszWhat,
 
 1476     size_type     nBegin) 
const noexcept
 
 1480         return _find_first_of(
 
 1482             static_cast<const_pointer
>(
nullptr),
 
 1484             [](const_pointer pChar)
 
 1486                 return *(pChar + 1) != 
QX_CHAR_PREFIX(value_type, 
'\0') ? pChar + 1 : 
nullptr;
 
 1495 template<
class char_t, 
class traits_t>
 
 1498     size_type           nBegin) 
const noexcept
 
 1500     return find_first_of(sWhat.data(), nBegin, sWhat.size());
 
 1503 template<
class char_t, 
class traits_t>
 
 1504 template<
class fwd_it_t>
 
 1506     fwd_it_t  itWhatBegin,
 
 1508     size_type nBegin) 
const noexcept
 
 1510     return _find_first_of(
 
 1520 template<
class char_t, 
class traits_t>
 
 1521 template<range_of_t_c<
char_t> 
string_t>
 
 1524     size_type nBegin) 
const noexcept
 
 1526     return find_first_of(sWhat.cbegin(), sWhat.cend(), nBegin);
 
 1529 template<
class char_t, 
class traits_t>
 
 1531     value_type chSymbol,
 
 1532     size_type  nEnd) 
const noexcept
 
 1534     return rfind(chSymbol, npos, nEnd);
 
 1537 template<
class char_t, 
class traits_t>
 
 1539     const_pointer pszWhat,
 
 1541     size_type     nWhatSize) 
const noexcept
 
 1545         return _find_last_of(
 
 1547             pszWhat + nWhatSize,
 
 1549             [](const_pointer pChar)
 
 1560 template<
class char_t, 
class traits_t>
 
 1562     const_pointer pszWhat,
 
 1563     size_type     nEnd) 
const noexcept
 
 1567         return _find_last_of(
 
 1569             static_cast<const_pointer
>(
nullptr),
 
 1571             [](const_pointer pChar)
 
 1573                 return *(pChar + 1) != 
QX_CHAR_PREFIX(value_type, 
'\0') ? pChar + 1 : 
nullptr;
 
 1582 template<
class char_t, 
class traits_t>
 
 1585     size_type           nEnd) 
const noexcept
 
 1587     return find_last_of(sWhat.data(), nEnd, sWhat.size());
 
 1590 template<
class char_t, 
class traits_t>
 
 1591 template<
class fwd_it_t>
 
 1593     fwd_it_t  itWhatBegin,
 
 1595     size_type nEnd) 
const noexcept
 
 1597     return _find_last_of(
 
 1607 template<
class char_t, 
class traits_t>
 
 1608 template<range_of_t_c<
char_t> 
string_t>
 
 1611     size_type nEnd) 
const noexcept
 
 1613     return find_last_of(sWhat.cbegin(), sWhat.cend(), nEnd);
 
 1616 template<
class char_t, 
class traits_t>
 
 1618     value_type chSymbol,
 
 1619     size_type  nBegin) 
const noexcept
 
 1624         [chSymbol](const_pointer pCurrentChar)
 
 1626             return *pCurrentChar != chSymbol;
 
 1630 template<
class char_t, 
class traits_t>
 
 1632     const_pointer pszWhat,
 
 1634     size_type     nWhatSize) 
const noexcept
 
 1638         return _find_first_not_of(
 
 1640             pszWhat + nWhatSize,
 
 1642             [](const_pointer pChar)
 
 1653 template<
class char_t, 
class traits_t>
 
 1655     const_pointer pszWhat,
 
 1656     size_type     nBegin) 
const noexcept
 
 1660         return _find_first_not_of(
 
 1662             static_cast<const_pointer
>(
nullptr),
 
 1664             [](const_pointer pChar)
 
 1666                 return *(pChar + 1) != 
QX_CHAR_PREFIX(value_type, 
'\0') ? pChar + 1 : 
nullptr;
 
 1675 template<
class char_t, 
class traits_t>
 
 1678     size_type           nBegin) 
const noexcept
 
 1680     return find_first_not_of(sWhat.data(), nBegin, sWhat.size());
 
 1683 template<
class char_t, 
class traits_t>
 
 1684 template<
class fwd_it_t>
 
 1686     fwd_it_t  itWhatBegin,
 
 1688     size_type nBegin) 
const noexcept
 
 1690     return _find_first_not_of(
 
 1700 template<
class char_t, 
class traits_t>
 
 1701 template<range_of_t_c<
char_t> 
string_t>
 
 1704     size_type nBegin) 
const noexcept
 
 1706     return find_first_not_of(sWhat.cbegin(), sWhat.cend(), nBegin);
 
 1709 template<
class char_t, 
class traits_t>
 
 1711     value_type chSymbol,
 
 1712     size_type  nEnd) 
const noexcept
 
 1717         [chSymbol](const_pointer pCurrentChar)
 
 1719             return *pCurrentChar != chSymbol;
 
 1723 template<
class char_t, 
class traits_t>
 
 1725     const_pointer pszWhat,
 
 1727     size_type     nWhatSize) 
const noexcept
 
 1731         return _find_last_not_of(
 
 1733             pszWhat + nWhatSize,
 
 1735             [](const_pointer pChar)
 
 1746 template<
class char_t, 
class traits_t>
 
 1748     const_pointer pszWhat,
 
 1749     size_type     nEnd) 
const noexcept
 
 1753         return _find_last_not_of(
 
 1755             static_cast<const_pointer
>(
nullptr),
 
 1757             [](const_pointer pChar)
 
 1759                 return *(pChar + 1) != 
QX_CHAR_PREFIX(value_type, 
'\0') ? pChar + 1 : 
nullptr;
 
 1768 template<
class char_t, 
class traits_t>
 
 1771     size_type           nEnd) 
const noexcept
 
 1773     return find_last_not_of(sWhat.data(), nEnd, sWhat.size());
 
 1776 template<
class char_t, 
class traits_t>
 
 1777 template<
class fwd_it_t>
 
 1779     fwd_it_t  itWhatBegin,
 
 1781     size_type nEnd) 
const noexcept
 
 1783     return _find_last_not_of(
 
 1793 template<
class char_t, 
class traits_t>
 
 1794 template<range_of_t_c<
char_t> 
string_t>
 
 1797     size_type nEnd) 
const noexcept
 
 1799     return find_last_not_of(sWhat.cbegin(), sWhat.cend(), nEnd);
 
 1802 template<
class char_t, 
class traits_t>
 
 1804     const value_type chSeparator) 
const noexcept
 
 1808     size_type nStart = 0;
 
 1810     while ((nEnd = find(chSeparator, nStart)) != npos)
 
 1812         tokens.emplace_back(substr(nStart, nEnd - nStart));
 
 1814         while (traits_t::compare_n(data() + nStart, &chSeparator, 1) == 0)
 
 1818     if (nStart != size())
 
 1819         tokens.emplace_back(substr(nStart));
 
 1821     return std::move(tokens);
 
 1824 template<
class char_t, 
class traits_t>
 
 1826     const_pointer pszSeparator,
 
 1827     size_type     nSepLen) 
const noexcept
 
 1834     if (nSepLen == npos)
 
 1835         nSepLen = traits_t::length(pszSeparator);
 
 1837     size_type nStart = 0;
 
 1839     while ((nEnd = find(pszSeparator, nStart, nSepLen, npos)) != npos)
 
 1841         tokens.emplace_back(substr(nStart, nEnd - nStart));
 
 1843         while (traits_t::compare_n(data() + nStart, pszSeparator, nSepLen) == 0)
 
 1847     if (nStart != size())
 
 1848         tokens.emplace_back(substr(nStart));
 
 1853 template<
class char_t, 
class traits_t>
 
 1857     return split(sSeparator.data(), sSeparator.size());
 
 1860 template<
class char_t, 
class traits_t>
 
 1861 template<
class fwd_it_t>
 
 1863     fwd_it_t itSepFirst,
 
 1864     fwd_it_t itSepLast) 
const noexcept
 
 1868     const size_type nSepLen = 
static_cast<size_type
>(std::distance(itSepFirst, itSepLast));
 
 1870     size_type nStart = 0;
 
 1872     while ((nEnd = find(itSepFirst, itSepLast, nStart)) != npos)
 
 1874         tokens.emplace_back(substr(nStart, nEnd - nStart));
 
 1875         nStart = nEnd + nSepLen;
 
 1877     tokens.emplace_back(substr(nStart));
 
 1882 template<
class char_t, 
class traits_t>
 
 1883 template<range_of_t_c<
char_t> 
string_t>
 
 1885     const string_t& sSeparator) 
const noexcept
 
 1887     return split(sSeparator.cbegin(), sSeparator.cend());
 
 1890 template<
class char_t, 
class traits_t>
 
 1894         return at(0) == chSymbol;
 
 1899 template<
class char_t, 
class traits_t>
 
 1904         if (size_type nThisSize = size(); nThisSize > 0)
 
 1906             if (nStrSize == npos)
 
 1907                 nStrSize = traits_t::length(pszStr);
 
 1909             if (nStrSize <= nThisSize)
 
 1910                 return traits_t::compare_n(data(), pszStr, nStrSize) == 0;
 
 1917 template<
class char_t, 
class traits_t>
 
 1920     return starts_with(sStr.data(), sStr.size());
 
 1923 template<
class char_t, 
class traits_t>
 
 1924 template<
class fwd_it_t>
 
 1927     auto nStrSize = std::distance(itBegin, itEnd);
 
 1928     return iter_strcmp(cbegin(), cbegin() + 
static_cast<size_type
>(nStrSize), itBegin, itEnd) == 0;
 
 1931 template<
class char_t, 
class traits_t>
 
 1932 template<range_of_t_c<
char_t> 
string_t>
 
 1935     return starts_with(sStr.cbegin(), sStr.cend());
 
 1938 template<
class char_t, 
class traits_t>
 
 1941     const size_type nSize = size();
 
 1943         return at(nSize - 1) == chSymbol;
 
 1948 template<
class char_t, 
class traits_t>
 
 1953         if (size_type nThisSize = size(); nThisSize > 0)
 
 1955             if (nStrSize == npos)
 
 1956                 nStrSize = traits_t::length(pszStr);
 
 1958             if (nStrSize <= nThisSize)
 
 1959                 return traits_t::compare_n(data() + nThisSize - nStrSize, pszStr, nStrSize) == 0;
 
 1966 template<
class char_t, 
class traits_t>
 
 1969     return ends_with(sStr.data(), sStr.size());
 
 1972 template<
class char_t, 
class traits_t>
 
 1973 template<
class fwd_it_t>
 
 1976     return iter_strcmp(cend() - 
static_cast<size_type
>(std::distance(itBegin, itEnd)), cend(), itBegin, itEnd) == 0;
 
 1979 template<
class char_t, 
class traits_t>
 
 1980 template<range_of_t_c<
char_t> 
string_t>
 
 1983     return ends_with(sStr.cbegin(), sStr.cend());
 
 1986 template<
class char_t, 
class traits_t>
 
 1989     return find(chSymbol) != npos;
 
 1992 template<
class char_t, 
class traits_t>
 
 1995     return find(pszStr, 0, nStrSize) != npos;
 
 1998 template<
class char_t, 
class traits_t>
 
 2001     return find(sStr) != npos;
 
 2004 template<
class char_t, 
class traits_t>
 
 2005 template<
class fwd_it_t>
 
 2008     return find(itBegin, itEnd) != npos;
 
 2011 template<
class char_t, 
class traits_t>
 
 2012 template<range_of_t_c<
char_t> 
string_t>
 
 2015     return find(sStr) != npos;
 
 2018 template<
class char_t, 
class traits_t>
 
 2025 template<
class char_t, 
class traits_t>
 
 2026 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(basic_string&& sStr) noexcept
 
 2028     assign(std::move(sStr));
 
 2032 template<
class char_t, 
class traits_t>
 
 2033 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const basic_string& sStr) noexcept
 
 2039 template<
class char_t, 
class traits_t>
 
 2040 template<range_of_t_c<
char_t> 
string_t>
 
 2041 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const string_t& sStr) noexcept
 
 2047 template<
class char_t, 
class traits_t>
 
 2048 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(value_type chSymbol) noexcept
 
 2054 template<
class char_t, 
class traits_t>
 
 2055 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(const_pointer pszSource) noexcept
 
 2058         append(pszSource, traits_t::length(pszSource));
 
 2063 template<
class char_t, 
class traits_t>
 
 2064 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const basic_string& sStr) noexcept
 
 2066     append(sStr.data(), sStr.size());
 
 2070 template<
class char_t, 
class traits_t>
 
 2071 template<range_of_t_c<
char_t> 
string_t>
 
 2072 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const string_t& sStr) noexcept
 
 2074     append(sStr.cbegin(), sStr.cend());
 
 2078 template<
class char_t, 
class traits_t>
 
 2079 inline bool basic_string<char_t, traits_t>::operator==(value_type chSymbol) 
const noexcept
 
 2081     return size() == 1 && at(0) == chSymbol;
 
 2084 template<
class char_t, 
class traits_t>
 
 2085 inline bool basic_string<char_t, traits_t>::operator==(const_pointer pszSource) 
const noexcept
 
 2087     return compare(pszSource) == 0;
 
 2090 template<
class char_t, 
class traits_t>
 
 2091 inline bool basic_string<char_t, traits_t>::operator==(
const basic_string& sStr) 
const noexcept
 
 2093     return size() == sStr.size() && compare(sStr.data(), sStr.size()) == 0;
 
 2096 template<
class char_t, 
class traits_t>
 
 2097 template<range_of_t_c<
char_t> 
string_t>
 
 2098 inline bool basic_string<char_t, traits_t>::operator==(
const string_t& sStr) 
const noexcept
 
 2100     return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) == 0;
 
 2103 template<
class char_t, 
class traits_t>
 
 2104 inline bool basic_string<char_t, traits_t>::operator!=(value_type chSymbol) 
const noexcept
 
 2106     return !operator==(chSymbol);
 
 2109 template<
class char_t, 
class traits_t>
 
 2110 inline bool basic_string<char_t, traits_t>::operator!=(const_pointer pszSource) 
const noexcept
 
 2112     return !operator==(pszSource);
 
 2115 template<
class char_t, 
class traits_t>
 
 2116 inline bool basic_string<char_t, traits_t>::operator!=(
const basic_string& sStr) 
const noexcept
 
 2118     return !operator==(sStr);
 
 2121 template<
class char_t, 
class traits_t>
 
 2122 template<range_of_t_c<
char_t> 
string_t>
 
 2123 inline bool basic_string<char_t, traits_t>::operator!=(
const string_t& sStr) 
const noexcept
 
 2125     return !operator==(sStr);
 
 2128 template<
class char_t, 
class traits_t>
 
 2129 inline bool basic_string<char_t, traits_t>::operator<(value_type chSymbol) 
const noexcept
 
 2131     return compare(&chSymbol, 1) < 0;
 
 2134 template<
class char_t, 
class traits_t>
 
 2135 inline bool basic_string<char_t, traits_t>::operator<(const_pointer pszSource) 
const noexcept
 
 2137     return compare(pszSource) < 0;
 
 2140 template<
class char_t, 
class traits_t>
 
 2141 inline bool basic_string<char_t, traits_t>::operator<(
const basic_string& sStr) 
const noexcept
 
 2143     return compare(sStr.data(), sStr.size()) < 0;
 
 2146 template<
class char_t, 
class traits_t>
 
 2147 template<range_of_t_c<
char_t> 
string_t>
 
 2148 inline bool basic_string<char_t, traits_t>::operator<(
const string_t& sStr) 
const noexcept
 
 2150     return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) < 0;
 
 2153 template<
class char_t, 
class traits_t>
 
 2154 inline bool basic_string<char_t, traits_t>::operator<=(value_type chSymbol) 
const noexcept
 
 2156     return compare(&chSymbol, 1) <= 0;
 
 2159 template<
class char_t, 
class traits_t>
 
 2160 inline bool basic_string<char_t, traits_t>::operator<=(const_pointer pszSource) 
const noexcept
 
 2162     return compare(pszSource) <= 0;
 
 2165 template<
class char_t, 
class traits_t>
 
 2166 inline bool basic_string<char_t, traits_t>::operator<=(
const basic_string& sStr) 
const noexcept
 
 2168     return compare(sStr.data(), sStr.size()) <= 0;
 
 2171 template<
class char_t, 
class traits_t>
 
 2172 template<range_of_t_c<
char_t> 
string_t>
 
 2173 inline bool basic_string<char_t, traits_t>::operator<=(
const string_t& sStr) 
const noexcept
 
 2175     return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) <= 0;
 
 2178 template<
class char_t, 
class traits_t>
 
 2179 inline bool basic_string<char_t, traits_t>::operator>(value_type chSymbol) 
const noexcept
 
 2181     return compare(&chSymbol, 1) > 0;
 
 2184 template<
class char_t, 
class traits_t>
 
 2185 inline bool basic_string<char_t, traits_t>::operator>(const_pointer pszSource) 
const noexcept
 
 2187     return compare(pszSource) > 0;
 
 2190 template<
class char_t, 
class traits_t>
 
 2191 inline bool basic_string<char_t, traits_t>::operator>(
const basic_string& sStr) 
const noexcept
 
 2193     return compare(sStr.data(), sStr.size()) > 0;
 
 2196 template<
class char_t, 
class traits_t>
 
 2197 template<range_of_t_c<
char_t> 
string_t>
 
 2198 inline bool basic_string<char_t, traits_t>::operator>(
const string_t& sStr) 
const noexcept
 
 2200     return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) > 0;
 
 2203 template<
class char_t, 
class traits_t>
 
 2204 inline bool basic_string<char_t, traits_t>::operator>=(value_type chSymbol) 
const noexcept
 
 2206     return compare(&chSymbol, 1) >= 0;
 
 2209 template<
class char_t, 
class traits_t>
 
 2210 inline bool basic_string<char_t, traits_t>::operator>=(const_pointer pszSource) 
const noexcept
 
 2212     return compare(pszSource) >= 0;
 
 2215 template<
class char_t, 
class traits_t>
 
 2216 inline bool basic_string<char_t, traits_t>::operator>=(
const basic_string& sStr) 
const noexcept
 
 2218     return compare(sStr.data(), sStr.size()) >= 0;
 
 2221 template<
class char_t, 
class traits_t>
 
 2222 template<range_of_t_c<
char_t> 
string_t>
 
 2223 inline bool basic_string<char_t, traits_t>::operator>=(
const string_t& sStr) 
const noexcept
 
 2225     return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) >= 0;
 
 2228 template<
class char_t, 
class traits_t>
 
 2229 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::operator[](
 
 2230     size_type nSymbol) noexcept
 
 2235 template<
class char_t, 
class traits_t>
 
 2236 inline typename basic_string<char_t, traits_t>::const_reference basic_string<char_t, traits_t>::operator[](
 
 2237     size_type nSymbol) 
const noexcept
 
 2242 template<
class char_t, 
class traits_t>
 
 2243 inline basic_string<char_t, traits_t>::operator std::basic_string_view<
 
 2244     typename basic_string<char_t, traits_t>::value_type>() 
const noexcept
 
 2246     return string_view(data(), size());
 
 2249 template<
class char_t, 
class traits_t>
 
 2250 inline basic_string<char_t, traits_t>::operator bool() const noexcept
 
 2255 template<
class char_t, 
class traits_t>
 
 2256 inline bool basic_string<char_t, traits_t>::_resize(size_type nSymbols, string_resize_type eType) noexcept
 
 2259         m_Data.resize(nSymbols, eType == string_resize_type::shrink_to_fit ? 0 : traits_t::align(), eType);
 
 2261     if (bRet && eType == string_resize_type::common)
 
 2262         at(nSymbols) = 
QX_CHAR_PREFIX(
typename traits_t::value_type, 
'\0');
 
 2267 template<
class char_t, 
class traits_t>
 
 2268 template<
class searcher_t>
 
 2269 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_left(
 
 2270     const searcher_t& searcher) noexcept
 
 2272     size_type nSymbols = 0;
 
 2274     for (size_type i = 0; i < size(); ++i)
 
 2276         if (searcher(at(i)))
 
 2286 template<
class char_t, 
class traits_t>
 
 2287 template<
class searcher_t>
 
 2288 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_right(
 
 2289     const searcher_t& searcher) noexcept
 
 2291     size_type nSymbols = 0;
 
 2292     size_type nSize    = size();
 
 2294     for (size_type i = nSize - 1; i != std::numeric_limits<size_type>::max(); --i)
 
 2296         if (searcher(at(i)))
 
 2302     erase(nSize - nSymbols, nSymbols);
 
 2306 template<
class char_t, 
class traits_t>
 
 2307 template<
class searcher_t>
 
 2308 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim(
 
 2309     const searcher_t& searcher) noexcept
 
 2311     const size_type nSize     = size();
 
 2312     size_type       nStartPos = 0;
 
 2313     size_type       nEndPos   = nSize;
 
 2315     while (nStartPos < nSize && searcher(at(nStartPos)))
 
 2318     while (nEndPos > nStartPos && searcher(at(nEndPos - 1)))
 
 2321     size_type nNewSize = nEndPos - nStartPos;
 
 2323     std::memmove(data(), data() + nStartPos, nNewSize * 
sizeof(value_type));
 
 2326     return nSize - nNewSize;
 
 2329 template<
class char_t, 
class traits_t>
 
 2330 template<
class comparator_t>
 
 2331 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find(
 
 2334     const comparator_t& comparator) 
const noexcept
 
 2339     const_pointer pData        = data();
 
 2340     const_pointer pCurrentChar = pData + nBegin;
 
 2341     const_pointer pEnd         = pData + nEnd;
 
 2343     while (pCurrentChar < pEnd)
 
 2345         if (comparator(pCurrentChar))
 
 2346             return static_cast<size_type
>(pCurrentChar - pData);
 
 2354 template<
class char_t, 
class traits_t>
 
 2355 template<
class comparator_t>
 
 2356 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_rfind(
 
 2359     const comparator_t& comparator) 
const noexcept
 
 2362         nBegin = size() - 1;
 
 2364     const_pointer pData        = data();
 
 2365     const_pointer pCurrentChar = pData + nBegin;
 
 2366     const_pointer pEnd         = pData + nEnd;
 
 2368     while (pCurrentChar >= pEnd)
 
 2370         if (comparator(pCurrentChar))
 
 2371             return static_cast<size_type
>(pCurrentChar - pData);
 
 2379 template<
class char_t, 
class traits_t>
 
 2380 template<
class incrementer_t, 
class fwd_it_t>
 
 2381 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_first_of(
 
 2385     const incrementer_t& incrementer) 
const noexcept
 
 2387     for (size_type i = nBegin; i < size(); ++i)
 
 2388         for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
 
 2395 template<
class char_t, 
class traits_t>
 
 2396 template<
class incrementer_t, 
class fwd_it_t>
 
 2397 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_of(
 
 2401     const incrementer_t& incrementer) 
const noexcept
 
 2403     for (size_type i = size() - 1; i != nEnd - 1; --i)
 
 2404         for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
 
 2411 template<
class char_t, 
class traits_t>
 
 2412 template<
class incrementer_t, 
class fwd_it_t>
 
 2413 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_first_not_of(
 
 2417     const incrementer_t& incrementer) 
const noexcept
 
 2419     for (size_type i = nBegin; i < size(); ++i)
 
 2421         bool bFoundOneOf = 
false;
 
 2422         for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
 
 2423             bFoundOneOf |= *it == at(i);
 
 2432 template<
class char_t, 
class traits_t>
 
 2433 template<
class incrementer_t, 
class fwd_it_t>
 
 2434 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_not_of(
 
 2438     const incrementer_t& incrementer) 
const noexcept
 
 2440     for (size_type i = size() - 1; i != nEnd - 1; --i)
 
 2442         bool bFoundOneOf = 
false;
 
 2443         for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
 
 2444             bFoundOneOf |= *it == at(i);
 
 2453 template<
class char_t, 
class traits_t>
 
 2454 template<
class string_view_like_t>
 
 2455 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_get_string_view_like_size(
 
 2456     const string_view_like_t& sValue) noexcept
 
 2458     if constexpr (std::is_same_v<string_view_like_t, value_type>)
 
 2462     else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
 
 2464         return traits_t::length(sValue);
 
 2466     else if constexpr (range_of_t_c<string_view_like_t, char_t>)
 
 2468         return sValue.size();
 
 2472         QX_STATIC_ASSERT_NO_INSTANTIATION(
"Unexpected type");
 
 2477 template<
class char_t, 
class traits_t>
 
 2478 template<
class string_view_like_t>
 
 2479 inline typename basic_string<char_t, traits_t>::const_pointer basic_string<char_t, traits_t>::
 
 2480     _get_string_view_like_data(
const string_view_like_t& sValue) noexcept
 
 2482     if constexpr (std::is_same_v<string_view_like_t, value_type>)
 
 2486     else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
 
 2490     else if constexpr (range_of_t_c<string_view_like_t, char_t>)
 
 2492         return sValue.data();
 
 2496         QX_STATIC_ASSERT_NO_INSTANTIATION(
"Unexpected type");
 
 2501 template<
class T, 
class char_t, 
class traits_t>
 
 2507 template<
class char_t, 
class traits_t>
 
 2508 basic_string<char_t, traits_t> operator+(
 
 2509     const basic_string<char_t, traits_t>& lhs,
 
 2510     const basic_string<char_t, traits_t>& rhs) noexcept
 
 2512     basic_string<char_t, traits_t> str(lhs);
 
 2517 template<
class char_t, 
class traits_t>
 
 2518 basic_string<char_t, traits_t> operator+(
 
 2519     basic_string<char_t, traits_t>&&      lhs,
 
 2520     const basic_string<char_t, traits_t>& rhs) noexcept
 
 2522     basic_string<char_t, traits_t> str(std::move(lhs));
 
 2527 template<
class char_t, 
class traits_t>
 
 2528 basic_string<char_t, traits_t> operator+(
 
 2529     const basic_string<char_t, traits_t>& lhs,
 
 2530     typename traits_t::const_pointer      rhs) noexcept
 
 2532     basic_string<char_t, traits_t> str(lhs);
 
 2537 template<
class char_t, 
class traits_t>
 
 2538 basic_string<char_t, traits_t> operator+(
 
 2539     basic_string<char_t, traits_t>&& lhs,
 
 2540     typename traits_t::const_pointer rhs) noexcept
 
 2542     basic_string<char_t, traits_t> str(std::move(lhs));
 
 2547 template<
class char_t, 
class traits_t>
 
 2548 basic_string<char_t, traits_t> operator+(
 
 2549     typename traits_t::const_pointer      lhs,
 
 2550     const basic_string<char_t, traits_t>& rhs) noexcept
 
 2552     basic_string<char_t, traits_t> str(lhs);
 
 2557 template<
class char_t, 
class traits_t>
 
 2558 basic_string<char_t, traits_t> operator+(
 
 2559     const basic_string<char_t, traits_t>& lhs,
 
 2560     typename traits_t::value_type         rhs) noexcept
 
 2562     basic_string<char_t, traits_t> str(lhs);
 
 2567 template<
class char_t, 
class traits_t>
 
 2568 basic_string<char_t, traits_t> operator+(
 
 2569     basic_string<char_t, traits_t>&& lhs,
 
 2570     typename traits_t::value_type    rhs) noexcept
 
 2572     basic_string<char_t, traits_t> str(std::move(lhs));
 
 2577 template<
class char_t, 
class traits_t>
 
 2578 basic_string<char_t, traits_t> operator+(
 
 2579     typename traits_t::value_type         lhs,
 
 2580     const basic_string<char_t, traits_t>& rhs) noexcept
 
 2582     basic_string<char_t, traits_t> str(&lhs, 1);
 
 2587 template<
class char_t, 
class traits_t, range_of_t_c<
char_t> 
string_t>
 
 2588 basic_string<char_t, traits_t> operator+(
const basic_string<char_t, traits_t>& lhs, 
const string_t& rhs) noexcept
 
 2590     basic_string<char_t, traits_t> str(lhs);
 
 2595 template<
class char_t, 
class traits_t, range_of_t_c<
char_t> 
string_t>
 
 2596 basic_string<char_t, traits_t> operator+(basic_string<char_t, traits_t>&& lhs, 
const string_t& rhs) noexcept
 
 2598     basic_string<char_t, traits_t> str(std::move(lhs));
 
 2603 template<
class char_t, 
class traits_t, range_of_t_c<
char_t> 
string_t>
 
 2604 basic_string<char_t, traits_t> operator+(
const string_t& lhs, 
const basic_string<char_t, traits_t>& rhs) noexcept
 
 2606     basic_string<char_t, traits_t> str(lhs);
 
 2615 template<
class char_t, 
class traits_t>
 
 2616 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::size() const noexcept
 
 2618     return m_Data.size();
 
 2625 template<
class char_t, 
class traits_t>
 
 2626 inline typename basic_string<char_t, traits_t>::pointer basic_string<char_t, traits_t>::data() noexcept
 
 2628     return m_Data.data();
 
 2636 template<
class char_t, 
class traits_t>
 
 2637 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::at(size_type nIndex) noexcept
 
 2639     return data()[nIndex];
 
 2645 template<
class char_t, 
class traits_t>
 
 2646 inline void basic_string<char_t, traits_t>::clear() noexcept
 
 2660 template<
class char_t, 
class traits_t>
 
 2661 struct hash<qx::basic_string<char_t, traits_t>>
 
 2665         return traits_t::hash_function(str.data(), traits_t::hash_seed(), str.size());
 
 2671 template<
class char_t, 
class traits_t>
 
 2679 template<
class char_t, 
class traits_t>
 
 2682     template<
class format_context_type>
 
 2694 template<
class char_t, 
class traits_t>
 
 2695 qx::details::ostream<char_t>& operator<<(
 
 2696     qx::details::ostream<char_t>&             os,
 
 2703 template<
class char_t, 
class traits_t>
 
 2706     typename qx::details::istream<traits_t>::iostate ret_bit = qx::details::istream<traits_t>::goodbit;
 
 2708     auto try_push_back = [&str, &is, &ret_bit](char_t ch)
 
 2710         typename traits_t::size_type nCurrentSize = str.size();
 
 2711         if (str._resize(nCurrentSize + 1))
 
 2713             str[nCurrentSize] = ch;
 
 2719             ret_bit |= qx::details::istream<traits_t>::failbit;
 
 2730         if (!traits_t::is_space(ch))
 
 2740         if (!traits_t::is_space(ch))
 
 2742             if (!try_push_back(ch))
 
 2752     is.setstate(ret_bit);
 
void push_back(value_type chSymbol) noexcept
Insert char in the end of the string.
 
void erase(iterator itFirst, iterator itLast) noexcept
Erase substring.
 
size_type find(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) const noexcept
Find substring.
 
bool remove_prefix(value_type chSymbol) noexcept
Remove string prefix if matches.
 
size_type remove_all(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) noexcept
Remove all occurrences of a substring in a string.
 
std::optional< to_t > to(const_pointer pszFormat=nullptr) const noexcept
Convert string to specified type.
 
int compare(value_type chSymbol) const noexcept
Performs a binary comparison of the characters.
 
size_type find_last_of(value_type chSymbol, size_type nEnd=0) const noexcept
Find last position of character.
 
void push_front(value_type chSymbol) noexcept
Insert char in the beginning of the string.
 
size_type capacity() const noexcept
Get allocated memory size (including null terminator)
 
value_type pop_back() noexcept
Erase last char and return it.
 
size_type copy(pointer pDest, size_type nCount, size_type nPos=0) const noexcept
Copies a substring [nPos, nPos + nCount) to character string pointed to by pDest.
 
views split(const value_type chSeparator) const noexcept
Split string by separator.
 
size_type rfind(value_type chSymbol, size_type nBegin=npos, size_type nEnd=0) const noexcept
Find substring (reverse direction)
 
size_type length() const noexcept
Get string length.
 
void free() noexcept
Clear string and free allocated memory.
 
void from(const from_t &data)
Construct string from custom type.
 
size_type trim_right() noexcept
Trim the string to the right (whitespace characters)
 
requires format_acceptable_args_c< char_t, args_t... > void vformat(string_view svFormat, args_t &&... args)
Clear the string and format it with the format string and the args.
 
void assign(size_type nSymbols, value_type chSymbol) noexcept
Assign by filling.
 
size_type replace_all(const find_string_t &sFind, const replace_string_t &sReplace, size_type nBegin=0, size_type nEnd=npos) noexcept
Replace all occurrences of sFind with sReplace.
 
bool ends_with(value_type chSymbol) const noexcept
Check if current string ends with char.
 
void swap(basic_string &sOther) noexcept
Swap this str and other.
 
value_type pop_front() noexcept
Erase first char and return it.
 
void append(value_type chSymbol) noexcept
Append char.
 
bool contains(value_type chSymbol) const noexcept
Check if string contains char.
 
size_type trim() noexcept
Trim the string to the both sides (whitespace characters)
 
void to_upper() noexcept
Convert string to uppercase.
 
void shrink_to_fit() noexcept
Fit allocated size to string's actual size.
 
static basic_string static_from(const from_t &data)
Construct string from custom type and get it.
 
size_type find_last_not_of(value_type chSymbol, size_type nEnd=0) const noexcept
Finds the last character not equal to chSymbol.
 
size_type trim_left() noexcept
Trim the string to the left (whitespace characters)
 
size_type reserve(size_type nCapacity) noexcept
Reserve memory for the string.
 
requires format_acceptable_args_c< char_t, args_t... > void append_vformat(string_view svFormat, args_t &&... args)
Append the formatted string to the current one.
 
string_view substr(size_type nPos, size_type nSymbols=npos) const noexcept
Get substring.
 
requires format_acceptable_args_c< char_t, args_t... > void append_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args)
Append the formatted string to the current one.
 
void to_lower() noexcept
Convert string to lowercase.
 
requires format_acceptable_args_c< char_t, args_t... > void format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args)
Clear the string and format it with the format string and the args.
 
size_type insert(size_type nPos, value_type chSymbol) noexcept
Insert substring.
 
bool remove_suffix(value_type chSymbol) noexcept
Remove string suffix if matches.
 
const_pointer c_str() const noexcept
Get pointer to string zero terminated.
 
requires static format_acceptable_args_c< char_t, args_t... > basic_string static_vformat(string_view svFormat, args_t &&... args)
Create a string by formatting it with the format string and the args.
 
size_type remove(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) noexcept
Remove the first occurrence of a substring in a string.
 
static constexpr size_type max_size() noexcept
Get the theoretical maximum of string size.
 
bool starts_with(value_type chSymbol) const noexcept
Check if current string starts with char.
 
value_type front() const noexcept
Get first char of the string.
 
value_type back() const noexcept
Get last char of the string.
 
requires static format_acceptable_args_c< char_t, args_t... > basic_string static_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args)
Create a string by formatting it with the format string and the args.
 
size_type replace(size_type nBegin, size_type nSize, const_pointer pszReplace, size_t nReplaceSize) noexcept
Replace a substring with a given string.
 
size_type find_first_of(value_type chSymbol, size_type nBegin=0) const noexcept
Find first position of character.
 
size_type find_first_not_of(value_type chSymbol, size_type nBegin=0) const noexcept
Finds the first character not equal to chSymbol.
 
Const random access iterator type.
 
Non-const random access iterator type.
 
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
 
basic_string< char_t, traits_t > convert_to_string(const T &value)
Converts any type that has a std::formatter overload to qx::basic_string.
 
#define QX_CHAR_PREFIX(value_t, ch)
Chose witch of prefixes add to char : L or none.
 
constexpr int iter_strcmp(fwd_it_1_t itBegin1, fwd_it_1_t itEnd1, fwd_it_2_t itBegin2, fwd_it_2_t itEnd2) noexcept
Compares string 1 with string 2.
 
#define QX_STR_PREFIX(value_t, str)
Chose witch of prefixes add to string : L or none.