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<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<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<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<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<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<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>())
301 const int nConvertedArgs = traits_t::sscanf(data(), pszSelectedFormat, &result);
303 if (nConvertedArgs == 1)
310 sstream_type ss(data());
318 template<
class char_t,
class traits_t>
322 size_type nPos)
const noexcept
324 size_type nCharsToCopy = 0;
326 if (pDest && nCount > 0 && nPos < size())
328 nCharsToCopy = std::min(nPos + nCount, size()) - nPos;
329 std::memcpy(pDest, data() + nPos, nCharsToCopy *
sizeof(value_type));
335 template<
class char_t,
class traits_t>
336 template<
class from_t>
340 std::is_trivial_v<from_t> && std::is_standard_layout_v<from_t> || std::is_pointer_v<from_t>
341 || std::is_same_v<from_t, std::nullptr_t>)
343 if constexpr (std::is_same_v<from_t, std::nullptr_t>)
345 assign(
QX_STR_PREFIX(
typename traits_t::value_type,
"nullptr"));
347 else if constexpr (std::is_same_v<from_t, bool>)
355 format(
QX_STR_PREFIX(
typename traits_t::value_type,
"{}"), data);
366 template<
class char_t,
class traits_t>
367 template<
class from_t>
372 return std::move(sTemp);
375 template<
class char_t,
class traits_t>
381 template<
class char_t,
class traits_t>
386 const size_type nSize = size();
387 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszStr) : nSymbols;
389 if (_resize(nSize + nSizeSource))
390 std::memcpy(data() + nSize, pszStr, nSizeSource *
sizeof(value_type));
394 template<
class char_t,
class traits_t>
400 template<
class char_t,
class traits_t>
401 template<
class fwd_it_t>
404 for (
auto it = itBegin; it != itEnd; ++it)
408 template<
class char_t,
class traits_t>
409 template<range_of_t_c<
char_t>
string_t>
412 append(sStr.cbegin(), sStr.cend());
415 template<
class char_t,
class traits_t>
418 value_type chSymbol) noexcept
420 return insert(nPos, &chSymbol, 1);
423 template<
class char_t,
class traits_t>
426 const_pointer pszWhat,
427 size_type nSymbols) noexcept
431 const size_type nSize = size();
432 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszWhat) : nSymbols;
434 if (nSizeSource > 0 && _resize(nSize + nSizeSource))
436 std::memmove(data() + nPos + nSizeSource, data() + nPos, (nSize - nPos) *
sizeof(value_type));
437 std::memcpy(data() + nPos, pszWhat, nSizeSource *
sizeof(value_type));
438 return nPos + nSizeSource;
445 template<
class char_t,
class traits_t>
446 template<
class fwd_it_t>
449 fwd_it_t itWhatBegin,
450 fwd_it_t itWhatEnd) noexcept
452 if constexpr (is_random_access_iterator<fwd_it_t>)
454 return insert(nPos, itWhatBegin.operator->(),
static_cast<size_type
>(itWhatEnd - itWhatBegin));
458 size_type nWhatSize = 0;
459 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
462 size_type nStartSymbols = size();
463 if (nWhatSize > 0 && _resize(nStartSymbols + nWhatSize))
465 std::memmove(data() + nPos + nWhatSize, data() + nPos, (nStartSymbols - nPos) *
sizeof(value_type));
467 size_type nWhatPos = 0;
468 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
470 at(nPos + nWhatPos) = *it;
474 return nPos + nWhatSize;
483 template<
class char_t,
class traits_t>
488 return insert(nPos, sWhat.data(), sWhat.size());
491 template<
class char_t,
class traits_t>
492 template<range_of_t_c<
char_t>
string_t>
495 string_t sWhat) noexcept
497 return insert(
static_cast<size_type
>(nPos), sWhat.cbegin(), sWhat.cend());
500 template<
class char_t,
class traits_t>
503 value_type chSymbol) noexcept
505 return insert(
static_cast<size_type
>(itPos - cbegin()), chSymbol);
508 template<
class char_t,
class traits_t>
511 const_pointer pszWhat,
512 size_type nSymbols) noexcept
514 return insert(
static_cast<size_type
>(itPos - cbegin()), pszWhat, nSymbols);
517 template<
class char_t,
class traits_t>
522 return insert(
static_cast<size_type
>(itPos - cbegin()), sWhat.data(), sWhat.size());
525 template<
class char_t,
class traits_t>
526 template<
class fwd_it_t>
529 fwd_it_t itWhatBegin,
530 fwd_it_t itWhatEnd) noexcept
532 return insert(
static_cast<size_type
>(itPos - begin()), itWhatBegin, itWhatEnd);
535 template<
class char_t,
class traits_t>
536 template<range_of_t_c<
char_t>
string_t>
539 string_t sWhat) noexcept
541 return insert(
static_cast<size_type
>(itPos - begin()), sWhat.cbegin(), sWhat.cend());
544 template<
class char_t,
class traits_t>
547 insert(size(), &chSymbol, 1);
550 template<
class char_t,
class traits_t>
553 insert(0, &chSymbol, 1);
556 template<
class char_t,
class traits_t>
559 if (
const typename iterator::difference_type nCharsToErase = itLast - itFirst; nCharsToErase > 0)
561 const size_type nStartSize = size();
562 const size_type nSymbolsToCopy = itLast != end() ? traits_t::length(itLast.operator->()) : 0;
564 if (nSymbolsToCopy > 0)
566 std::memmove(itFirst.operator->(), itLast.operator->(), nSymbolsToCopy *
sizeof(value_type));
569 if (
static_cast<typename iterator::difference_type
>(nStartSize) >= nCharsToErase)
571 _resize(nStartSize - nCharsToErase);
576 template<
class char_t,
class traits_t>
579 erase(itPos, itPos + 1);
582 template<
class char_t,
class traits_t>
588 template<
class char_t,
class traits_t>
594 template<
class char_t,
class traits_t>
597 value_type chRet = back();
602 template<
class char_t,
class traits_t>
605 value_type chRet = front();
610 template<
class char_t,
class traits_t>
616 return traits_t::is_space(ch);
620 template<
class char_t,
class traits_t>
622 value_type chSymbol) noexcept
625 [chSymbol](value_type ch)
627 return ch == chSymbol;
631 template<
class char_t,
class traits_t>
633 const_pointer pszStr) noexcept
638 [pszStr](value_type ch)
640 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
655 template<
class char_t,
class traits_t>
657 const_pointer pszStr,
658 size_type nStrSize) noexcept
663 [pszStr, nStrSize](value_type ch)
665 for (size_type j = 0; j < nStrSize; ++j)
678 template<
class char_t,
class traits_t>
682 return trim_left(sStr.data(), sStr.size());
685 template<
class char_t,
class traits_t>
686 template<
class fwd_it_t>
689 fwd_it_t itEnd) noexcept
692 [itBegin, itEnd](
auto ch)
694 for (
auto it = itBegin; it != itEnd; ++it)
702 template<
class char_t,
class traits_t>
703 template<range_of_t_c<
char_t>
string_t>
705 const string_t& sStr) noexcept
707 return trim_left(sStr.cbegin(), sStr.cend());
710 template<
class char_t,
class traits_t>
716 return traits_t::is_space(ch);
720 template<
class char_t,
class traits_t>
722 value_type chSymbol) noexcept
725 [chSymbol](value_type ch)
727 return ch == chSymbol;
731 template<
class char_t,
class traits_t>
733 const_pointer pszStr) noexcept
738 [pszStr](value_type ch)
740 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
755 template<
class char_t,
class traits_t>
757 const_pointer pszStr,
758 size_type nStrSize) noexcept
763 [pszStr, nStrSize](value_type ch)
765 for (size_type j = 0; j < nStrSize; ++j)
778 template<
class char_t,
class traits_t>
782 return trim_right(sStr.data(), sStr.size());
785 template<
class char_t,
class traits_t>
786 template<
class fwd_it_t>
789 fwd_it_t itEnd) noexcept
792 [itBegin, itEnd](
auto ch)
794 for (
auto it = itBegin; it != itEnd; ++it)
802 template<
class char_t,
class traits_t>
803 template<range_of_t_c<
char_t>
string_t>
805 const string_t& sStr) noexcept
807 return trim_right(sStr.cbegin(), sStr.cend());
810 template<
class char_t,
class traits_t>
816 return traits_t::is_space(ch);
820 template<
class char_t,
class traits_t>
822 value_type chSymbol) noexcept
825 [chSymbol](value_type ch)
827 return ch == chSymbol;
831 template<
class char_t,
class traits_t>
833 const_pointer pszStr) noexcept
838 [pszStr](value_type ch)
840 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
855 template<
class char_t,
class traits_t>
857 const_pointer pszStr,
858 size_type nStrSize) noexcept
863 [pszStr, nStrSize](value_type ch)
865 for (size_type j = 0; j < nStrSize; ++j)
878 template<
class char_t,
class traits_t>
882 return trim(sStr.data(), sStr.size());
885 template<
class char_t,
class traits_t>
886 template<
class fwd_it_t>
889 fwd_it_t itEnd) noexcept
892 [itBegin, itEnd](
auto ch)
894 for (
auto it = itBegin; it != itEnd; ++it)
902 template<
class char_t,
class traits_t>
903 template<range_of_t_c<
char_t>
string_t>
905 const string_t& sStr) noexcept
907 return trim(sStr.cbegin(), sStr.cend());
910 template<
class char_t,
class traits_t>
914 size_type nEnd) noexcept
916 size_type nPos = find(chSymbol, nBegin, nEnd);
924 template<
class char_t,
class traits_t>
926 const_pointer pszStr,
929 size_type nStrSize) noexcept
933 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
934 const size_type nPos = find(pszStr, nBegin, nLocalStrSize, nEnd);
937 erase(nPos, nLocalStrSize);
947 template<
class char_t,
class traits_t>
951 size_type nEnd) noexcept
953 const size_type nPos = find(sStr, nBegin, nEnd);
956 erase(nPos, sStr.size());
961 template<
class char_t,
class traits_t>
962 template<
class fwd_it_t>
967 size_type nEnd) noexcept
969 const size_type nPos = find(itBegin, itEnd, nBegin, nEnd);
972 erase(nPos,
static_cast<size_type
>(std::distance(itBegin, itEnd)));
977 template<
class char_t,
class traits_t>
978 template<range_of_t_c<
char_t>
string_t>
980 const string_t& sStr,
982 size_type nEnd) noexcept
984 return remove(sStr.cbegin(), sStr.cend(), nBegin, nEnd);
987 template<
class char_t,
class traits_t>
990 return remove(chSymbol,
static_cast<size_type
>(0),
static_cast<size_type
>(1)) != npos;
993 template<
class char_t,
class traits_t>
996 return remove(pszStr,
static_cast<size_type
>(0), nStrSize, nStrSize) != npos;
999 template<
class char_t,
class traits_t>
1002 return remove(sStr,
static_cast<size_type
>(0), sStr.size()) != npos;
1005 template<
class char_t,
class traits_t>
1006 template<
class fwd_it_t>
1009 return remove(itBegin, itEnd,
static_cast<size_type
>(0),
static_cast<size_type
>(std::distance(itBegin, itEnd)))
1013 template<
class char_t,
class traits_t>
1014 template<range_of_t_c<
char_t>
string_t>
1017 return remove_prefix(sStr.cbegin(), sStr.cend());
1020 template<
class char_t,
class traits_t>
1023 const size_type nSize = size();
1024 return remove(chSymbol, nSize - 1, nSize) != npos;
1027 template<
class char_t,
class traits_t>
1032 const size_type nSize = size();
1033 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
1035 return remove(pszStr, nSize - nLocalStrSize, nSize, nLocalStrSize) != npos;
1043 template<
class char_t,
class traits_t>
1046 return remove_suffix(sStr.data(), sStr.size());
1049 template<
class char_t,
class traits_t>
1050 template<
class fwd_it_t>
1053 const size_type nSize = size();
1054 return remove(itBegin, itEnd, nSize -
static_cast<size_type
>(std::distance(itBegin, itEnd)), nSize) != npos;
1057 template<
class char_t,
class traits_t>
1058 template<range_of_t_c<
char_t>
string_t>
1061 return remove_suffix(sStr.cbegin(), sStr.cend());
1064 template<
class char_t,
class traits_t>
1066 value_type chSymbol,
1068 size_type nEnd) noexcept
1070 size_type nOccurrences = 0;
1071 size_type nLastOccurrencePos = nBegin;
1076 nLastOccurrencePos = remove(chSymbol, nLastOccurrencePos, nEnd);
1077 }
while (nLastOccurrencePos != npos);
1079 return nOccurrences - 1;
1082 template<
class char_t,
class traits_t>
1084 const_pointer pszStr,
1087 size_type nStrSize) noexcept
1091 size_type nOccurrences = 0;
1092 size_type nLastOccurrencePos = nBegin;
1097 nLastOccurrencePos = remove(pszStr, nLastOccurrencePos, nEnd, nStrSize);
1098 }
while (nLastOccurrencePos != npos);
1100 return nOccurrences - 1;
1108 template<
class char_t,
class traits_t>
1112 size_type nEnd) noexcept
1114 return remove_all(sStr.data(), nBegin, nEnd, sStr.size());
1117 template<
class char_t,
class traits_t>
1118 template<
class fwd_it_t>
1123 size_type nEnd) noexcept
1125 size_type nOccurrences = 0;
1126 size_type nLastOccurrencePos = nBegin;
1131 nLastOccurrencePos = remove(itFirst, itLast, nLastOccurrencePos, nEnd);
1132 }
while (nLastOccurrencePos != npos);
1134 return nOccurrences - 1;
1137 template<
class char_t,
class traits_t>
1138 template<range_of_t_c<
char_t>
string_t>
1140 const string_t& sStr,
1142 size_type nEnd) noexcept
1144 return remove_all(sStr.cbegin(), sStr.cend(), nBegin, nEnd);
1147 template<
class char_t,
class traits_t>
1151 const_pointer pszReplace,
1152 size_t nReplaceSize) noexcept
1154 const size_type nStartSize = size();
1155 const size_type nNewSize = nStartSize - nSize + nReplaceSize;
1157 _resize(nNewSize, string_resize_type::reserve);
1160 data() + nBegin + nReplaceSize,
1161 data() + nBegin + nSize,
1162 (nStartSize - nBegin - nSize) *
sizeof(value_type));
1164 std::memcpy(data() + nBegin, pszReplace, nReplaceSize *
sizeof(value_type));
1168 return nBegin + nReplaceSize;
1171 template<
class char_t,
class traits_t>
1172 template<
class replace_
string_t>
1176 const replace_string_t& sReplace) noexcept
1178 return replace(nBegin, nSize, _get_string_view_like_data(sReplace), _get_string_view_like_size(sReplace));
1181 template<
class char_t,
class traits_t>
1182 template<
class find_
string_t,
class replace_
string_t>
1184 const find_string_t& sFind,
1185 const replace_string_t& sReplace,
1187 size_type nEnd) noexcept
1189 if (size_type nPos = find(sFind, nBegin, nEnd); nPos != npos)
1193 _get_string_view_like_size(sFind),
1194 _get_string_view_like_data(sReplace),
1195 _get_string_view_like_size(sReplace));
1203 template<
class char_t,
class traits_t>
1204 template<
class find_
string_t,
class replace_
string_t>
1206 const find_string_t& sFind,
1207 const replace_string_t& sReplace,
1209 size_type nEnd) noexcept
1211 size_type nOccurrences = 0;
1212 size_type nPos = nBegin;
1216 nPos = replace(sFind, sReplace, nPos, nEnd);
1219 }
while (nPos != npos);
1221 return nOccurrences;
1224 template<
class char_t,
class traits_t>
1227 return compare(&chSymbol, 1);
1230 template<
class char_t,
class traits_t>
1233 return traits_t::compare(data(), pszStr);
1236 template<
class char_t,
class traits_t>
1239 return traits_t::compare_n(data(), pStr, nSymbols);
1242 template<
class char_t,
class traits_t>
1245 return compare(sStr.data(), sStr.size());
1248 template<
class char_t,
class traits_t>
1249 template<
class fwd_it_t>
1252 return iter_strcmp(cbegin(), cend(), itBegin, itEnd);
1255 template<
class char_t,
class traits_t>
1256 template<range_of_t_c<
char_t>
string_t>
1259 return compare(sStr.cbegin(), sStr.cend());
1262 template<
class char_t,
class traits_t>
1264 value_type chSymbol,
1266 size_type nEnd)
const noexcept
1271 [chSymbol](const_pointer pCurrentChar)
1273 return *pCurrentChar == chSymbol;
1277 template<
class char_t,
class traits_t>
1279 const_pointer pszWhat,
1281 size_type nWhatSize,
1282 size_type nEnd)
const noexcept
1286 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1291 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1293 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1302 template<
class char_t,
class traits_t>
1306 size_type nEnd)
const noexcept
1308 return find(sWhat.data(), nBegin, sWhat.size(), nEnd);
1311 template<
class char_t,
class traits_t>
1312 template<
class fwd_it_t>
1314 fwd_it_t itWhatBegin,
1317 size_type nEnd)
const noexcept
1322 [
this, itWhatBegin, itWhatEnd, nEnd](const_pointer pCurrentChar)
1325 const_iterator(
this,
static_cast<size_type
>(pCurrentChar - data())),
1332 template<
class char_t,
class traits_t>
1333 template<range_of_t_c<
char_t>
string_t>
1337 size_type nEnd)
const noexcept
1339 return find(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
1342 template<
class char_t,
class traits_t>
1344 value_type chSymbol,
1346 size_type nEnd)
const noexcept
1351 [chSymbol](const_pointer pCurrentChar)
1353 return *pCurrentChar == chSymbol;
1357 template<
class char_t,
class traits_t>
1359 const_pointer pszWhat,
1361 size_type nWhatSize,
1362 size_type nEnd)
const noexcept
1366 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1371 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1373 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1382 template<
class char_t,
class traits_t>
1386 size_type nEnd)
const noexcept
1388 return rfind(sWhat.data(), nBegin, sWhat.size(), nEnd);
1391 template<
class char_t,
class traits_t>
1392 template<
class fwd_it_t>
1394 fwd_it_t itWhatBegin,
1397 size_type nEnd)
const noexcept
1402 [
this, itWhatBegin, itWhatEnd, nEnd](const_pointer pCurrentChar)
1405 const_iterator(
this,
static_cast<size_type
>(pCurrentChar - data())),
1412 template<
class char_t,
class traits_t>
1413 template<range_of_t_c<
char_t>
string_t>
1417 size_type nEnd)
const noexcept
1419 return rfind(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
1422 template<
class char_t,
class traits_t>
1424 value_type chSymbol,
1425 size_type nBegin)
const noexcept
1427 return find(chSymbol, nBegin);
1430 template<
class char_t,
class traits_t>
1432 const_pointer pszWhat,
1434 size_type nWhatSize)
const noexcept
1438 return _find_first_of(
1440 pszWhat + nWhatSize,
1442 [](const_pointer pChar)
1453 template<
class char_t,
class traits_t>
1455 const_pointer pszWhat,
1456 size_type nBegin)
const noexcept
1460 return _find_first_of(
1462 static_cast<const_pointer
>(
nullptr),
1464 [](const_pointer pChar)
1466 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1475 template<
class char_t,
class traits_t>
1478 size_type nBegin)
const noexcept
1480 return find_first_of(sWhat.data(), nBegin, sWhat.size());
1483 template<
class char_t,
class traits_t>
1484 template<
class fwd_it_t>
1486 fwd_it_t itWhatBegin,
1488 size_type nBegin)
const noexcept
1490 return _find_first_of(
1500 template<
class char_t,
class traits_t>
1501 template<range_of_t_c<
char_t>
string_t>
1504 size_type nBegin)
const noexcept
1506 return find_first_of(sWhat.cbegin(), sWhat.cend(), nBegin);
1509 template<
class char_t,
class traits_t>
1511 value_type chSymbol,
1512 size_type nEnd)
const noexcept
1514 return rfind(chSymbol, npos, nEnd);
1517 template<
class char_t,
class traits_t>
1519 const_pointer pszWhat,
1521 size_type nWhatSize)
const noexcept
1525 return _find_last_of(
1527 pszWhat + nWhatSize,
1529 [](const_pointer pChar)
1540 template<
class char_t,
class traits_t>
1542 const_pointer pszWhat,
1543 size_type nEnd)
const noexcept
1547 return _find_last_of(
1549 static_cast<const_pointer
>(
nullptr),
1551 [](const_pointer pChar)
1553 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1562 template<
class char_t,
class traits_t>
1565 size_type nEnd)
const noexcept
1567 return find_last_of(sWhat.data(), nEnd, sWhat.size());
1570 template<
class char_t,
class traits_t>
1571 template<
class fwd_it_t>
1573 fwd_it_t itWhatBegin,
1575 size_type nEnd)
const noexcept
1577 return _find_last_of(
1587 template<
class char_t,
class traits_t>
1588 template<range_of_t_c<
char_t>
string_t>
1591 size_type nEnd)
const noexcept
1593 return find_last_of(sWhat.cbegin(), sWhat.cend(), nEnd);
1596 template<
class char_t,
class traits_t>
1598 value_type chSymbol,
1599 size_type nBegin)
const noexcept
1604 [chSymbol](const_pointer pCurrentChar)
1606 return *pCurrentChar != chSymbol;
1610 template<
class char_t,
class traits_t>
1612 const_pointer pszWhat,
1614 size_type nWhatSize)
const noexcept
1618 return _find_first_not_of(
1620 pszWhat + nWhatSize,
1622 [](const_pointer pChar)
1633 template<
class char_t,
class traits_t>
1635 const_pointer pszWhat,
1636 size_type nBegin)
const noexcept
1640 return _find_first_not_of(
1642 static_cast<const_pointer
>(
nullptr),
1644 [](const_pointer pChar)
1646 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1655 template<
class char_t,
class traits_t>
1658 size_type nBegin)
const noexcept
1660 return find_first_not_of(sWhat.data(), nBegin, sWhat.size());
1663 template<
class char_t,
class traits_t>
1664 template<
class fwd_it_t>
1666 fwd_it_t itWhatBegin,
1668 size_type nBegin)
const noexcept
1670 return _find_first_not_of(
1680 template<
class char_t,
class traits_t>
1681 template<range_of_t_c<
char_t>
string_t>
1684 size_type nBegin)
const noexcept
1686 return find_first_not_of(sWhat.cbegin(), sWhat.cend(), nBegin);
1689 template<
class char_t,
class traits_t>
1691 value_type chSymbol,
1692 size_type nEnd)
const noexcept
1697 [chSymbol](const_pointer pCurrentChar)
1699 return *pCurrentChar != chSymbol;
1703 template<
class char_t,
class traits_t>
1705 const_pointer pszWhat,
1707 size_type nWhatSize)
const noexcept
1711 return _find_last_not_of(
1713 pszWhat + nWhatSize,
1715 [](const_pointer pChar)
1726 template<
class char_t,
class traits_t>
1728 const_pointer pszWhat,
1729 size_type nEnd)
const noexcept
1733 return _find_last_not_of(
1735 static_cast<const_pointer
>(
nullptr),
1737 [](const_pointer pChar)
1739 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1748 template<
class char_t,
class traits_t>
1751 size_type nEnd)
const noexcept
1753 return find_last_not_of(sWhat.data(), nEnd, sWhat.size());
1756 template<
class char_t,
class traits_t>
1757 template<
class fwd_it_t>
1759 fwd_it_t itWhatBegin,
1761 size_type nEnd)
const noexcept
1763 return _find_last_not_of(
1773 template<
class char_t,
class traits_t>
1774 template<range_of_t_c<
char_t>
string_t>
1777 size_type nEnd)
const noexcept
1779 return find_last_not_of(sWhat.cbegin(), sWhat.cend(), nEnd);
1782 template<
class char_t,
class traits_t>
1784 const value_type chSeparator)
const noexcept
1788 size_type nStart = 0;
1790 while ((nEnd = find(chSeparator, nStart)) != npos)
1792 tokens.emplace_back(substr(nStart, nEnd - nStart));
1794 while (traits_t::compare_n(data() + nStart, &chSeparator, 1) == 0)
1798 if (nStart != size())
1799 tokens.emplace_back(substr(nStart));
1801 return std::move(tokens);
1804 template<
class char_t,
class traits_t>
1806 const_pointer pszSeparator,
1807 size_type nSepLen)
const noexcept
1814 if (nSepLen == npos)
1815 nSepLen = traits_t::length(pszSeparator);
1817 size_type nStart = 0;
1819 while ((nEnd = find(pszSeparator, nStart, nSepLen, npos)) != npos)
1821 tokens.emplace_back(substr(nStart, nEnd - nStart));
1823 while (traits_t::compare_n(data() + nStart, pszSeparator, nSepLen) == 0)
1827 if (nStart != size())
1828 tokens.emplace_back(substr(nStart));
1833 template<
class char_t,
class traits_t>
1837 return split(sSeparator.data(), sSeparator.size());
1840 template<
class char_t,
class traits_t>
1841 template<
class fwd_it_t>
1843 fwd_it_t itSepFirst,
1844 fwd_it_t itSepLast)
const noexcept
1848 const size_type nSepLen =
static_cast<size_type
>(std::distance(itSepFirst, itSepLast));
1850 size_type nStart = 0;
1852 while ((nEnd = find(itSepFirst, itSepLast, nStart)) != npos)
1854 tokens.emplace_back(substr(nStart, nEnd - nStart));
1855 nStart = nEnd + nSepLen;
1857 tokens.emplace_back(substr(nStart));
1862 template<
class char_t,
class traits_t>
1863 template<range_of_t_c<
char_t>
string_t>
1865 const string_t& sSeparator)
const noexcept
1867 return split(sSeparator.cbegin(), sSeparator.cend());
1870 template<
class char_t,
class traits_t>
1874 return at(0) == chSymbol;
1879 template<
class char_t,
class traits_t>
1884 if (size_type nThisSize = size(); nThisSize > 0)
1886 if (nStrSize == npos)
1887 nStrSize = traits_t::length(pszStr);
1889 if (nStrSize <= nThisSize)
1890 return traits_t::compare_n(data(), pszStr, nStrSize) == 0;
1897 template<
class char_t,
class traits_t>
1900 return starts_with(sStr.data(), sStr.size());
1903 template<
class char_t,
class traits_t>
1904 template<
class fwd_it_t>
1907 auto nStrSize = std::distance(itBegin, itEnd);
1908 return iter_strcmp(cbegin(), cbegin() +
static_cast<size_type
>(nStrSize), itBegin, itEnd) == 0;
1911 template<
class char_t,
class traits_t>
1912 template<range_of_t_c<
char_t>
string_t>
1915 return starts_with(sStr.cbegin(), sStr.cend());
1918 template<
class char_t,
class traits_t>
1921 const size_type nSize = size();
1923 return at(nSize - 1) == chSymbol;
1928 template<
class char_t,
class traits_t>
1933 if (size_type nThisSize = size(); nThisSize > 0)
1935 if (nStrSize == npos)
1936 nStrSize = traits_t::length(pszStr);
1938 if (nStrSize <= nThisSize)
1939 return traits_t::compare_n(data() + nThisSize - nStrSize, pszStr, nStrSize) == 0;
1946 template<
class char_t,
class traits_t>
1949 return ends_with(sStr.data(), sStr.size());
1952 template<
class char_t,
class traits_t>
1953 template<
class fwd_it_t>
1956 return iter_strcmp(cend() -
static_cast<size_type
>(std::distance(itBegin, itEnd)), cend(), itBegin, itEnd) == 0;
1959 template<
class char_t,
class traits_t>
1960 template<range_of_t_c<
char_t>
string_t>
1963 return ends_with(sStr.cbegin(), sStr.cend());
1966 template<
class char_t,
class traits_t>
1969 return find(chSymbol) != npos;
1972 template<
class char_t,
class traits_t>
1975 return find(pszStr, 0, nStrSize) != npos;
1978 template<
class char_t,
class traits_t>
1981 return find(sStr) != npos;
1984 template<
class char_t,
class traits_t>
1985 template<
class fwd_it_t>
1988 return find(itBegin, itEnd) != npos;
1991 template<
class char_t,
class traits_t>
1992 template<range_of_t_c<
char_t>
string_t>
1995 return find(sStr) != npos;
1998 template<
class char_t,
class traits_t>
2005 template<
class char_t,
class traits_t>
2006 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(basic_string&& sStr) noexcept
2008 assign(std::move(sStr));
2012 template<
class char_t,
class traits_t>
2013 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const basic_string& sStr) noexcept
2019 template<
class char_t,
class traits_t>
2020 template<range_of_t_c<
char_t>
string_t>
2021 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const string_t& sStr) noexcept
2027 template<
class char_t,
class traits_t>
2028 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(value_type chSymbol) noexcept
2034 template<
class char_t,
class traits_t>
2035 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(const_pointer pszSource) noexcept
2038 append(pszSource, traits_t::length(pszSource));
2043 template<
class char_t,
class traits_t>
2044 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const basic_string& sStr) noexcept
2046 append(sStr.data(), sStr.size());
2050 template<
class char_t,
class traits_t>
2051 template<range_of_t_c<
char_t>
string_t>
2052 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const string_t& sStr) noexcept
2054 append(sStr.cbegin(), sStr.cend());
2058 template<
class char_t,
class traits_t>
2059 inline bool basic_string<char_t, traits_t>::operator==(value_type chSymbol)
const noexcept
2061 return size() == 1 && at(0) == chSymbol;
2064 template<
class char_t,
class traits_t>
2065 inline bool basic_string<char_t, traits_t>::operator==(const_pointer pszSource)
const noexcept
2067 return compare(pszSource) == 0;
2070 template<
class char_t,
class traits_t>
2071 inline bool basic_string<char_t, traits_t>::operator==(
const basic_string& sStr)
const noexcept
2073 return size() == sStr.size() && compare(sStr.data(), sStr.size()) == 0;
2076 template<
class char_t,
class traits_t>
2077 template<range_of_t_c<
char_t>
string_t>
2078 inline bool basic_string<char_t, traits_t>::operator==(
const string_t& sStr)
const noexcept
2080 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) == 0;
2083 template<
class char_t,
class traits_t>
2084 inline bool basic_string<char_t, traits_t>::operator!=(value_type chSymbol)
const noexcept
2086 return !operator==(chSymbol);
2089 template<
class char_t,
class traits_t>
2090 inline bool basic_string<char_t, traits_t>::operator!=(const_pointer pszSource)
const noexcept
2092 return !operator==(pszSource);
2095 template<
class char_t,
class traits_t>
2096 inline bool basic_string<char_t, traits_t>::operator!=(
const basic_string& sStr)
const noexcept
2098 return !operator==(sStr);
2101 template<
class char_t,
class traits_t>
2102 template<range_of_t_c<
char_t>
string_t>
2103 inline bool basic_string<char_t, traits_t>::operator!=(
const string_t& sStr)
const noexcept
2105 return !operator==(sStr);
2108 template<
class char_t,
class traits_t>
2109 inline bool basic_string<char_t, traits_t>::operator<(value_type chSymbol)
const noexcept
2111 return compare(&chSymbol, 1) < 0;
2114 template<
class char_t,
class traits_t>
2115 inline bool basic_string<char_t, traits_t>::operator<(const_pointer pszSource)
const noexcept
2117 return compare(pszSource) < 0;
2120 template<
class char_t,
class traits_t>
2121 inline bool basic_string<char_t, traits_t>::operator<(
const basic_string& sStr)
const noexcept
2123 return compare(sStr.data(), sStr.size()) < 0;
2126 template<
class char_t,
class traits_t>
2127 template<range_of_t_c<
char_t>
string_t>
2128 inline bool basic_string<char_t, traits_t>::operator<(
const string_t& sStr)
const noexcept
2130 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) < 0;
2133 template<
class char_t,
class traits_t>
2134 inline bool basic_string<char_t, traits_t>::operator<=(value_type chSymbol)
const noexcept
2136 return compare(&chSymbol, 1) <= 0;
2139 template<
class char_t,
class traits_t>
2140 inline bool basic_string<char_t, traits_t>::operator<=(const_pointer pszSource)
const noexcept
2142 return compare(pszSource) <= 0;
2145 template<
class char_t,
class traits_t>
2146 inline bool basic_string<char_t, traits_t>::operator<=(
const basic_string& sStr)
const noexcept
2148 return compare(sStr.data(), sStr.size()) <= 0;
2151 template<
class char_t,
class traits_t>
2152 template<range_of_t_c<
char_t>
string_t>
2153 inline bool basic_string<char_t, traits_t>::operator<=(
const string_t& sStr)
const noexcept
2155 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) <= 0;
2158 template<
class char_t,
class traits_t>
2159 inline bool basic_string<char_t, traits_t>::operator>(value_type chSymbol)
const noexcept
2161 return compare(&chSymbol, 1) > 0;
2164 template<
class char_t,
class traits_t>
2165 inline bool basic_string<char_t, traits_t>::operator>(const_pointer pszSource)
const noexcept
2167 return compare(pszSource) > 0;
2170 template<
class char_t,
class traits_t>
2171 inline bool basic_string<char_t, traits_t>::operator>(
const basic_string& sStr)
const noexcept
2173 return compare(sStr.data(), sStr.size()) > 0;
2176 template<
class char_t,
class traits_t>
2177 template<range_of_t_c<
char_t>
string_t>
2178 inline bool basic_string<char_t, traits_t>::operator>(
const string_t& sStr)
const noexcept
2180 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) > 0;
2183 template<
class char_t,
class traits_t>
2184 inline bool basic_string<char_t, traits_t>::operator>=(value_type chSymbol)
const noexcept
2186 return compare(&chSymbol, 1) >= 0;
2189 template<
class char_t,
class traits_t>
2190 inline bool basic_string<char_t, traits_t>::operator>=(const_pointer pszSource)
const noexcept
2192 return compare(pszSource) >= 0;
2195 template<
class char_t,
class traits_t>
2196 inline bool basic_string<char_t, traits_t>::operator>=(
const basic_string& sStr)
const noexcept
2198 return compare(sStr.data(), sStr.size()) >= 0;
2201 template<
class char_t,
class traits_t>
2202 template<range_of_t_c<
char_t>
string_t>
2203 inline bool basic_string<char_t, traits_t>::operator>=(
const string_t& sStr)
const noexcept
2205 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) >= 0;
2208 template<
class char_t,
class traits_t>
2209 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::operator[](
2210 size_type nSymbol) noexcept
2215 template<
class char_t,
class traits_t>
2216 inline typename basic_string<char_t, traits_t>::const_reference basic_string<char_t, traits_t>::operator[](
2217 size_type nSymbol)
const noexcept
2222 template<
class char_t,
class traits_t>
2223 inline basic_string<char_t, traits_t>::operator std::basic_string_view<
2224 typename basic_string<char_t, traits_t>::value_type>()
const noexcept
2226 return string_view(data(), size());
2229 template<
class char_t,
class traits_t>
2230 inline basic_string<char_t, traits_t>::operator bool() const noexcept
2235 template<
class char_t,
class traits_t>
2236 inline bool basic_string<char_t, traits_t>::_resize(size_type nSymbols, string_resize_type eType) noexcept
2239 m_Data.resize(nSymbols, eType == string_resize_type::shrink_to_fit ? 0 : traits_t::align(), eType);
2241 if (bRet && eType == string_resize_type::common)
2242 at(nSymbols) =
QX_CHAR_PREFIX(
typename traits_t::value_type,
'\0');
2247 template<
class char_t,
class traits_t>
2248 template<
class searcher_t>
2249 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_left(
2250 const searcher_t& searcher) noexcept
2252 size_type nSymbols = 0;
2254 for (size_type i = 0; i < size(); ++i)
2256 if (searcher(at(i)))
2266 template<
class char_t,
class traits_t>
2267 template<
class searcher_t>
2268 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_right(
2269 const searcher_t& searcher) noexcept
2271 size_type nSymbols = 0;
2272 size_type nSize = size();
2274 for (size_type i = nSize - 1; i != std::numeric_limits<size_type>::max(); --i)
2276 if (searcher(at(i)))
2282 erase(nSize - nSymbols, nSymbols);
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(
2289 const searcher_t& searcher) noexcept
2291 const size_type nSize = size();
2292 size_type nStartPos = 0;
2293 size_type nEndPos = nSize;
2295 while (nStartPos < nSize && searcher(at(nStartPos)))
2298 while (nEndPos > nStartPos && searcher(at(nEndPos - 1)))
2301 size_type nNewSize = nEndPos - nStartPos;
2303 std::memmove(data(), data() + nStartPos, nNewSize *
sizeof(value_type));
2306 return nSize - nNewSize;
2309 template<
class char_t,
class traits_t>
2310 template<
class comparator_t>
2311 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find(
2314 const comparator_t& comparator)
const noexcept
2319 const_pointer pData = data();
2320 const_pointer pCurrentChar = pData + nBegin;
2321 const_pointer pEnd = pData + nEnd;
2323 while (pCurrentChar < pEnd)
2325 if (comparator(pCurrentChar))
2326 return static_cast<size_type
>(pCurrentChar - pData);
2334 template<
class char_t,
class traits_t>
2335 template<
class comparator_t>
2336 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_rfind(
2339 const comparator_t& comparator)
const noexcept
2342 nBegin = size() - 1;
2344 const_pointer pData = data();
2345 const_pointer pCurrentChar = pData + nBegin;
2346 const_pointer pEnd = pData + nEnd;
2348 while (pCurrentChar >= pEnd)
2350 if (comparator(pCurrentChar))
2351 return static_cast<size_type
>(pCurrentChar - pData);
2359 template<
class char_t,
class traits_t>
2360 template<
class incrementer_t,
class fwd_it_t>
2361 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_first_of(
2365 const incrementer_t& incrementer)
const noexcept
2367 for (size_type i = nBegin; i < size(); ++i)
2368 for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
2375 template<
class char_t,
class traits_t>
2376 template<
class incrementer_t,
class fwd_it_t>
2377 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_of(
2381 const incrementer_t& incrementer)
const noexcept
2383 for (size_type i = size() - 1; i != nEnd - 1; --i)
2384 for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
2391 template<
class char_t,
class traits_t>
2392 template<
class incrementer_t,
class fwd_it_t>
2393 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_first_not_of(
2397 const incrementer_t& incrementer)
const noexcept
2399 for (size_type i = nBegin; i < size(); ++i)
2401 bool bFoundOneOf =
false;
2402 for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
2403 bFoundOneOf |= *it == at(i);
2412 template<
class char_t,
class traits_t>
2413 template<
class incrementer_t,
class fwd_it_t>
2414 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_not_of(
2418 const incrementer_t& incrementer)
const noexcept
2420 for (size_type i = size() - 1; i != nEnd - 1; --i)
2422 bool bFoundOneOf =
false;
2423 for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
2424 bFoundOneOf |= *it == at(i);
2433 template<
class char_t,
class traits_t>
2434 template<
class string_view_like_t>
2435 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_get_string_view_like_size(
2436 const string_view_like_t& sValue) noexcept
2438 if constexpr (std::is_same_v<string_view_like_t, value_type>)
2442 else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
2444 return traits_t::length(sValue);
2446 else if constexpr (range_of_t_c<string_view_like_t, char_t>)
2448 return sValue.size();
2452 QX_STATIC_ASSERT_NO_INSTANTIATION(
"Unexpected type");
2457 template<
class char_t,
class traits_t>
2458 template<
class string_view_like_t>
2459 inline typename basic_string<char_t, traits_t>::const_pointer basic_string<char_t, traits_t>::
2460 _get_string_view_like_data(
const string_view_like_t& sValue) noexcept
2462 if constexpr (std::is_same_v<string_view_like_t, value_type>)
2466 else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
2470 else if constexpr (range_of_t_c<string_view_like_t, char_t>)
2472 return sValue.data();
2476 QX_STATIC_ASSERT_NO_INSTANTIATION(
"Unexpected type");
2481 template<
class char_t,
class traits_t>
2482 basic_string<char_t, traits_t> operator+(
2483 const basic_string<char_t, traits_t>& lhs,
2484 const basic_string<char_t, traits_t>& rhs) noexcept
2486 basic_string<char_t, traits_t> str(lhs);
2491 template<
class char_t,
class traits_t>
2492 basic_string<char_t, traits_t> operator+(
2493 basic_string<char_t, traits_t>&& lhs,
2494 const basic_string<char_t, traits_t>& rhs) noexcept
2496 basic_string<char_t, traits_t> str(std::move(lhs));
2501 template<
class char_t,
class traits_t>
2502 basic_string<char_t, traits_t> operator+(
2503 const basic_string<char_t, traits_t>& lhs,
2504 typename traits_t::const_pointer rhs) noexcept
2506 basic_string<char_t, traits_t> str(lhs);
2511 template<
class char_t,
class traits_t>
2512 basic_string<char_t, traits_t> operator+(
2513 basic_string<char_t, traits_t>&& lhs,
2514 typename traits_t::const_pointer rhs) noexcept
2516 basic_string<char_t, traits_t> str(std::move(lhs));
2521 template<
class char_t,
class traits_t>
2522 basic_string<char_t, traits_t> operator+(
2523 typename traits_t::const_pointer lhs,
2524 const basic_string<char_t, traits_t>& rhs) noexcept
2526 basic_string<char_t, traits_t> str(lhs);
2531 template<
class char_t,
class traits_t>
2532 basic_string<char_t, traits_t> operator+(
2533 const basic_string<char_t, traits_t>& lhs,
2534 typename traits_t::value_type rhs) noexcept
2536 basic_string<char_t, traits_t> str(lhs);
2541 template<
class char_t,
class traits_t>
2542 basic_string<char_t, traits_t> operator+(
2543 basic_string<char_t, traits_t>&& lhs,
2544 typename traits_t::value_type rhs) noexcept
2546 basic_string<char_t, traits_t> str(std::move(lhs));
2551 template<
class char_t,
class traits_t>
2552 basic_string<char_t, traits_t> operator+(
2553 typename traits_t::value_type lhs,
2554 const basic_string<char_t, traits_t>& rhs) noexcept
2556 basic_string<char_t, traits_t> str(&lhs, 1);
2561 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2562 basic_string<char_t, traits_t> operator+(
const basic_string<char_t, traits_t>& lhs,
const string_t& rhs) noexcept
2564 basic_string<char_t, traits_t> str(lhs);
2569 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2570 basic_string<char_t, traits_t> operator+(basic_string<char_t, traits_t>&& lhs,
const string_t& rhs) noexcept
2572 basic_string<char_t, traits_t> str(std::move(lhs));
2577 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2578 basic_string<char_t, traits_t> operator+(
const string_t& lhs,
const basic_string<char_t, traits_t>& rhs) noexcept
2580 basic_string<char_t, traits_t> str(lhs);
2589 template<
class char_t,
class traits_t>
2590 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::size() const noexcept
2592 return m_Data.size();
2599 template<
class char_t,
class traits_t>
2600 inline typename basic_string<char_t, traits_t>::pointer basic_string<char_t, traits_t>::data() noexcept
2602 return m_Data.data();
2610 template<
class char_t,
class traits_t>
2611 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::at(size_type nIndex) noexcept
2613 return data()[nIndex];
2619 template<
class char_t,
class traits_t>
2620 inline void basic_string<char_t, traits_t>::clear() noexcept
2634 template<
class char_t,
class traits_t>
2635 struct hash<qx::basic_string<char_t, traits_t>>
2639 return traits_t::hash_function(str.data(), traits_t::hash_seed(), str.size());
2645 template<
class char_t,
class traits_t>
2653 template<
class char_t,
class traits_t>
2656 template<
class format_context_type>
2668 template<
class char_t,
class traits_t>
2669 qx::details::ostream<char_t>& operator<<(
2670 qx::details::ostream<char_t>& os,
2677 template<
class char_t,
class traits_t>
2680 typename qx::details::istream<traits_t>::iostate ret_bit = qx::details::istream<traits_t>::goodbit;
2682 auto try_push_back = [&str, &is, &ret_bit](char_t ch)
2684 typename traits_t::size_type nCurrentSize = str.size();
2685 if (str._resize(nCurrentSize + 1))
2687 str[nCurrentSize] = ch;
2693 ret_bit |= qx::details::istream<traits_t>::failbit;
2704 if (!traits_t::is_space(ch))
2714 if (!traits_t::is_space(ch))
2716 if (!try_push_back(ch))
2726 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.
void append(const basic_string &sStr) noexcept
Append string.
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.
requires static format_acceptable_args< 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.
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)
void assign(size_type nSymbols, value_type chSymbol) noexcept
Assign by filling.
requires format_acceptable_args< 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.
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.
requires static format_acceptable_args< 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 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.
string_view substr(size_type nPos, size_type nSymbols=npos) const noexcept
Get substring.
void to_lower() noexcept
Convert string to lowercase.
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 format_acceptable_args< char_t, args_t... > void append_vformat(string_view svFormat, args_t &&... args)
Append the formatted string to the current one.
requires format_acceptable_args< 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 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.
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.
requires format_acceptable_args< 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.
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.
#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.