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>
1148 template<
class find_
string_t,
class replace_
string_t>
1150 const find_string_t& sFind,
1151 const replace_string_t& sReplace,
1153 size_type nEnd) noexcept
1155 auto get_size = []<
class T>(const T& val) -> size_type
1157 if constexpr (std::is_same_v<T, value_type>)
1161 else if constexpr (std::is_convertible_v<T, const_pointer>)
1163 return traits_t::length(val);
1165 else if constexpr (range_of_t_c<T, char_t>)
1171 QX_STATIC_ASSERT_NO_INSTANTIATION(
"Unexpected type");
1176 auto get_data = []<
class T>(const T& val) -> const_pointer
1178 if constexpr (std::is_same_v<T, value_type>)
1182 else if constexpr (std::is_convertible_v<T, const_pointer>)
1186 else if constexpr (range_of_t_c<T, char_t>)
1192 QX_STATIC_ASSERT_NO_INSTANTIATION(
"Unexpected type");
1197 if (size_type nPos = find(sFind, nBegin, nEnd); nPos != npos)
1199 const size_type nStartSize = size();
1200 const size_type nFindSize = get_size(sFind);
1201 const size_type nReplaceSize = get_size(sReplace);
1202 const size_type nNewSize = nStartSize - nFindSize + nReplaceSize;
1204 _resize(nNewSize, string_resize_type::reserve);
1207 data() + nPos + nReplaceSize,
1208 data() + nPos + nFindSize,
1209 (nStartSize - nPos - nFindSize) *
sizeof(value_type));
1211 std::memcpy(data() + nPos, get_data(sReplace), nReplaceSize *
sizeof(value_type));
1215 return nPos + nReplaceSize;
1223 template<
class char_t,
class traits_t>
1224 template<
class find_
string_t,
class replace_
string_t>
1226 const find_string_t& sFind,
1227 const replace_string_t& sReplace,
1229 size_type nEnd) noexcept
1231 size_type nOccurrences = 0;
1232 size_type nPos = nBegin;
1236 nPos = replace(sFind, sReplace, nPos, nEnd);
1239 }
while (nPos != npos);
1241 return nOccurrences;
1244 template<
class char_t,
class traits_t>
1247 return compare(&chSymbol, 1);
1250 template<
class char_t,
class traits_t>
1253 return traits_t::compare(data(), pszStr);
1256 template<
class char_t,
class traits_t>
1259 return traits_t::compare_n(data(), pStr, nSymbols);
1262 template<
class char_t,
class traits_t>
1265 return compare(sStr.data(), sStr.size());
1268 template<
class char_t,
class traits_t>
1269 template<
class fwd_it_t>
1272 return iter_strcmp(cbegin(), cend(), itBegin, itEnd);
1275 template<
class char_t,
class traits_t>
1276 template<range_of_t_c<
char_t>
string_t>
1279 return compare(sStr.cbegin(), sStr.cend());
1282 template<
class char_t,
class traits_t>
1284 value_type chSymbol,
1286 size_type nEnd)
const noexcept
1291 [chSymbol](const_pointer pCurrentChar)
1293 return *pCurrentChar == chSymbol;
1297 template<
class char_t,
class traits_t>
1299 const_pointer pszWhat,
1301 size_type nWhatSize,
1302 size_type nEnd)
const noexcept
1306 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1311 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1313 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1322 template<
class char_t,
class traits_t>
1326 size_type nEnd)
const noexcept
1328 return find(sWhat.data(), nBegin, sWhat.size(), nEnd);
1331 template<
class char_t,
class traits_t>
1332 template<
class fwd_it_t>
1334 fwd_it_t itWhatBegin,
1337 size_type nEnd)
const noexcept
1342 [
this, itWhatBegin, itWhatEnd, nEnd](const_pointer pCurrentChar)
1345 const_iterator(
this,
static_cast<size_type
>(pCurrentChar - data())),
1352 template<
class char_t,
class traits_t>
1353 template<range_of_t_c<
char_t>
string_t>
1357 size_type nEnd)
const noexcept
1359 return find(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
1362 template<
class char_t,
class traits_t>
1364 value_type chSymbol,
1366 size_type nEnd)
const noexcept
1371 [chSymbol](const_pointer pCurrentChar)
1373 return *pCurrentChar == chSymbol;
1377 template<
class char_t,
class traits_t>
1379 const_pointer pszWhat,
1381 size_type nWhatSize,
1382 size_type nEnd)
const noexcept
1386 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1391 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1393 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1402 template<
class char_t,
class traits_t>
1406 size_type nEnd)
const noexcept
1408 return rfind(sWhat.data(), nBegin, sWhat.size(), nEnd);
1411 template<
class char_t,
class traits_t>
1412 template<
class fwd_it_t>
1414 fwd_it_t itWhatBegin,
1417 size_type nEnd)
const noexcept
1422 [
this, itWhatBegin, itWhatEnd, nEnd](const_pointer pCurrentChar)
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 basic_string<char_t, traits_t> operator+(
2455 const basic_string<char_t, traits_t>& lhs,
2456 const basic_string<char_t, traits_t>& rhs) noexcept
2458 basic_string<char_t, traits_t> str(lhs);
2463 template<
class char_t,
class traits_t>
2464 basic_string<char_t, traits_t> operator+(
2465 basic_string<char_t, traits_t>&& lhs,
2466 const basic_string<char_t, traits_t>& rhs) noexcept
2468 basic_string<char_t, traits_t> str(std::move(lhs));
2473 template<
class char_t,
class traits_t>
2474 basic_string<char_t, traits_t> operator+(
2475 const basic_string<char_t, traits_t>& lhs,
2476 typename traits_t::const_pointer rhs) noexcept
2478 basic_string<char_t, traits_t> str(lhs);
2483 template<
class char_t,
class traits_t>
2484 basic_string<char_t, traits_t> operator+(
2485 basic_string<char_t, traits_t>&& lhs,
2486 typename traits_t::const_pointer rhs) noexcept
2488 basic_string<char_t, traits_t> str(std::move(lhs));
2493 template<
class char_t,
class traits_t>
2494 basic_string<char_t, traits_t> operator+(
2495 typename traits_t::const_pointer lhs,
2496 const basic_string<char_t, traits_t>& rhs) noexcept
2498 basic_string<char_t, traits_t> str(lhs);
2503 template<
class char_t,
class traits_t>
2504 basic_string<char_t, traits_t> operator+(
2505 const basic_string<char_t, traits_t>& lhs,
2506 typename traits_t::value_type rhs) noexcept
2508 basic_string<char_t, traits_t> str(lhs);
2513 template<
class char_t,
class traits_t>
2514 basic_string<char_t, traits_t> operator+(
2515 basic_string<char_t, traits_t>&& lhs,
2516 typename traits_t::value_type rhs) noexcept
2518 basic_string<char_t, traits_t> str(std::move(lhs));
2523 template<
class char_t,
class traits_t>
2524 basic_string<char_t, traits_t> operator+(
2525 typename traits_t::value_type lhs,
2526 const basic_string<char_t, traits_t>& rhs) noexcept
2528 basic_string<char_t, traits_t> str(&lhs, 1);
2533 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2534 basic_string<char_t, traits_t> operator+(
const basic_string<char_t, traits_t>& lhs,
const string_t& rhs) noexcept
2536 basic_string<char_t, traits_t> str(lhs);
2541 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2542 basic_string<char_t, traits_t> operator+(basic_string<char_t, traits_t>&& lhs,
const string_t& rhs) noexcept
2544 basic_string<char_t, traits_t> str(std::move(lhs));
2549 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2550 basic_string<char_t, traits_t> operator+(
const string_t& lhs,
const basic_string<char_t, traits_t>& rhs) noexcept
2552 basic_string<char_t, traits_t> str(lhs);
2561 template<
class char_t,
class traits_t>
2562 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::size() const noexcept
2564 return m_Data.size();
2571 template<
class char_t,
class traits_t>
2572 inline typename basic_string<char_t, traits_t>::pointer basic_string<char_t, traits_t>::data() noexcept
2574 return m_Data.data();
2582 template<
class char_t,
class traits_t>
2583 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::at(size_type nIndex) noexcept
2585 return data()[nIndex];
2591 template<
class char_t,
class traits_t>
2592 inline void basic_string<char_t, traits_t>::clear() noexcept
2606 template<
class char_t,
class traits_t>
2607 struct hash<qx::basic_string<char_t, traits_t>>
2611 return traits_t::hash_function(str.data(), traits_t::hash_seed(), str.size());
2617 template<
class char_t,
class traits_t>
2625 template<
class char_t,
class traits_t>
2628 template<
class format_context_type>
2640 template<
class char_t,
class traits_t>
2641 qx::details::ostream<char_t>& operator<<(
2642 qx::details::ostream<char_t>& os,
2649 template<
class char_t,
class traits_t>
2652 typename qx::details::istream<traits_t>::iostate ret_bit = qx::details::istream<traits_t>::goodbit;
2654 auto try_push_back = [&str, &is, &ret_bit](char_t ch)
2656 typename traits_t::size_type nCurrentSize = str.size();
2657 if (str._resize(nCurrentSize + 1))
2659 str[nCurrentSize] = ch;
2665 ret_bit |= qx::details::istream<traits_t>::failbit;
2676 if (!traits_t::is_space(ch))
2686 if (!traits_t::is_space(ch))
2688 if (!try_push_back(ch))
2698 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 replace(const find_string_t &sFind, const replace_string_t &sReplace, size_type nBegin=0, size_type nEnd=npos) noexcept
Replace first occurrence of sFind with sReplace.
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 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.