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>
60 if (_resize(nSymbols))
61 std::fill(begin(), end(), chSymbol);
64 template<
class char_t,
class traits_t>
67 if (pszSource && _resize(nSymbols))
68 std::memmove(data(), pszSource, nSymbols *
sizeof(value_type));
71 template<
class char_t,
class traits_t>
74 if (pszSource != data())
75 assign(pszSource, traits_t::length(pszSource));
78 template<
class char_t,
class traits_t>
84 template<
class char_t,
class traits_t>
87 if (sAnother.data() != data())
88 assign(sAnother.data());
91 template<
class char_t,
class traits_t>
92 template<
class fwd_it_t>
95 if (_resize(std::distance(itFirst, itLast)))
97 fwd_it_t itOther = itFirst;
100 while (itOther != itLast)
109 template<
class char_t,
class traits_t>
110 template<range_of_t_c<
char_t>
string_t>
113 assign(sAnother.cbegin(), sAnother.cend());
116 template<
class char_t,
class traits_t>
117 template<
class... args_t>
118 requires format_acceptable_args_c<char_t, args_t...>
120 const format_string_type<std::type_identity_t<args_t>...> sFormat,
123 vformat(sFormat.get(), std::forward<args_t>(args)...);
126 template<
class char_t,
class traits_t>
127 template<
class... args_t>
128 requires format_acceptable_args_c<char_t, args_t...>
130 const format_string_type<std::type_identity_t<args_t>...> sFormat,
133 return static_vformat(sFormat.get(), std::forward<args_t>(args)...);
136 template<
class char_t,
class traits_t>
137 template<
class... args_t>
138 requires format_acceptable_args_c<char_t, args_t...>
140 const format_string_type<std::type_identity_t<args_t>...> sFormat,
143 append_vformat(sFormat.get(), std::forward<args_t>(args)...);
146 template<
class char_t,
class traits_t>
147 template<
class... args_t>
148 requires format_acceptable_args_c<char_t, args_t...>
152 append_vformat(svFormat, std::forward<args_t>(args)...);
155 template<
class char_t,
class traits_t>
156 template<
class... args_t>
157 requires format_acceptable_args_c<char_t, args_t...>
159 string_view svFormat,
163 sTemp.
vformat(svFormat, std::forward<args_t>(args)...);
167 template<
class char_t,
class traits_t>
168 template<
class... args_t>
169 requires format_acceptable_args_c<char_t, args_t...>
172 if (!svFormat.empty())
173 traits_t::format_to(std::back_inserter(*
this), svFormat, std::forward<args_t>(args)...);
176 template<
class char_t,
class traits_t>
179 std::swap(m_Data, sOther.m_Data);
182 template<
class char_t,
class traits_t>
184 size_type nCapacity) noexcept
186 if (nCapacity > capacity())
187 _resize(nCapacity, sbo_resize_type::reserve);
192 template<
class char_t,
class traits_t>
195 if (!m_Data.is_small() && capacity() > size())
196 _resize(size(), sbo_resize_type::shrink_to_fit);
199 template<
class char_t,
class traits_t>
205 template<
class char_t,
class traits_t>
208 size_type nSymbols)
const noexcept
210 return string_view(data() + nPos, nSymbols != npos ? nSymbols : size() - nPos);
213 template<
class char_t,
class traits_t>
216 for (value_type& ch : *
this)
217 ch = traits_t::to_lower(ch);
220 template<
class char_t,
class traits_t>
223 for (value_type& ch : *
this)
224 ch = traits_t::to_upper(ch);
227 template<
class char_t,
class traits_t>
233 template<
class char_t,
class traits_t>
236 return at(size() - 1);
239 template<
class char_t,
class traits_t>
245 template<
class char_t,
class traits_t>
251 template<
class char_t,
class traits_t>
254 return m_Data.capacity() /
sizeof(value_type) - 1;
257 template<
class char_t,
class traits_t>
260 return std::numeric_limits<size_type>::max() - 1
264 template<
class char_t,
class traits_t>
268 std::optional<to_t> optResult = std::nullopt;
271 std::is_trivial_v<to_t> && std::is_standard_layout_v<to_t> || std::is_pointer_v<to_t>
272 || std::is_same_v<to_t, std::nullptr_t>)
274 if constexpr (std::is_same_v<to_t, std::nullptr_t>)
276 if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"nullptr")) == 0)
281 else if constexpr (std::is_same_v<to_t, bool>)
283 if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"true")) == 0)
287 else if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"false")) == 0)
292 else if (
const auto pszSelectedFormat = pszFormat ? pszFormat : get_format_specifier<value_type, to_t>())
295 constexpr
size_t nBufferSize = 256;
297 const size_t nFormatSpecifierLength = traits_t::length(pszSelectedFormat);
298 if (nFormatSpecifierLength <= nBufferSize - svNSpecifier.size() - 1)
300 value_type formatBuffer[nBufferSize];
301 std::memcpy(formatBuffer, pszSelectedFormat, nFormatSpecifierLength *
sizeof(value_type));
303 formatBuffer + nFormatSpecifierLength,
305 svNSpecifier.size() *
sizeof(value_type));
306 formatBuffer[nFormatSpecifierLength + svNSpecifier.size()] =
QX_CHAR_PREFIX(value_type,
'\0');
310 const int nConvertedArgs = traits_t::sscanf(data(), formatBuffer, &result, &nSymbolsRead);
312 if (
static_cast<size_type
>(nSymbolsRead) == size() && nConvertedArgs == 1)
320 sstream_type ss(data());
328 template<
class char_t,
class traits_t>
332 size_type nPos)
const noexcept
334 size_type nCharsToCopy = 0;
336 if (pDest && nCount > 0 && nPos < size())
338 nCharsToCopy = std::min(nPos + nCount, size()) - nPos;
339 std::memcpy(pDest, data() + nPos, nCharsToCopy *
sizeof(value_type));
345 template<
class char_t,
class traits_t>
346 template<
class from_t>
350 std::is_trivial_v<from_t> && std::is_standard_layout_v<from_t> || std::is_pointer_v<from_t>
351 || std::is_same_v<from_t, std::nullptr_t>)
353 if constexpr (std::is_same_v<from_t, std::nullptr_t>)
355 assign(
QX_STR_PREFIX(
typename traits_t::value_type,
"nullptr"));
357 else if constexpr (std::is_same_v<from_t, bool>)
365 format(
QX_STR_PREFIX(
typename traits_t::value_type,
"{}"), data);
376 template<
class char_t,
class traits_t>
377 template<
class from_t>
382 return std::move(sTemp);
385 template<
class char_t,
class traits_t>
391 template<
class char_t,
class traits_t>
396 const size_type nSize = size();
397 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszStr) : nSymbols;
399 if (_resize(nSize + nSizeSource))
400 std::memcpy(data() + nSize, pszStr, nSizeSource *
sizeof(value_type));
404 template<
class char_t,
class traits_t>
407 append(sStr.data(), sStr.size());
410 template<
class char_t,
class traits_t>
411 template<
class fwd_it_t>
414 for (
auto it = itBegin; it != itEnd; ++it)
418 template<
class char_t,
class traits_t>
419 template<range_of_t_c<
char_t>
string_t>
422 append(sStr.cbegin(), sStr.cend());
425 template<
class char_t,
class traits_t>
428 value_type chSymbol) noexcept
430 return insert(nPos, &chSymbol, 1);
433 template<
class char_t,
class traits_t>
436 const_pointer pszWhat,
437 size_type nSymbols) noexcept
441 const size_type nSize = size();
442 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszWhat) : nSymbols;
444 if (nSizeSource > 0 && _resize(nSize + nSizeSource))
446 std::memmove(data() + nPos + nSizeSource, data() + nPos, (nSize - nPos) *
sizeof(value_type));
447 std::memcpy(data() + nPos, pszWhat, nSizeSource *
sizeof(value_type));
448 return nPos + nSizeSource;
455 template<
class char_t,
class traits_t>
456 template<
class fwd_it_t>
459 fwd_it_t itWhatBegin,
460 fwd_it_t itWhatEnd) noexcept
462 if constexpr (is_random_access_iterator<fwd_it_t>)
464 return insert(nPos, itWhatBegin.operator->(),
static_cast<size_type
>(itWhatEnd - itWhatBegin));
468 size_type nWhatSize = 0;
469 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
472 size_type nStartSymbols = size();
473 if (nWhatSize > 0 && _resize(nStartSymbols + nWhatSize))
475 std::memmove(data() + nPos + nWhatSize, data() + nPos, (nStartSymbols - nPos) *
sizeof(value_type));
477 size_type nWhatPos = 0;
478 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
480 at(nPos + nWhatPos) = *it;
484 return nPos + nWhatSize;
493 template<
class char_t,
class traits_t>
498 return insert(nPos, sWhat.data(), sWhat.size());
501 template<
class char_t,
class traits_t>
502 template<range_of_t_c<
char_t>
string_t>
505 string_t sWhat) noexcept
507 return insert(
static_cast<size_type
>(nPos), sWhat.cbegin(), sWhat.cend());
510 template<
class char_t,
class traits_t>
513 value_type chSymbol) noexcept
515 return insert(
static_cast<size_type
>(itPos - cbegin()), chSymbol);
518 template<
class char_t,
class traits_t>
521 const_pointer pszWhat,
522 size_type nSymbols) noexcept
524 return insert(
static_cast<size_type
>(itPos - cbegin()), pszWhat, nSymbols);
527 template<
class char_t,
class traits_t>
532 return insert(
static_cast<size_type
>(itPos - cbegin()), sWhat.data(), sWhat.size());
535 template<
class char_t,
class traits_t>
536 template<
class fwd_it_t>
539 fwd_it_t itWhatBegin,
540 fwd_it_t itWhatEnd) noexcept
542 return insert(
static_cast<size_type
>(itPos - begin()), itWhatBegin, itWhatEnd);
545 template<
class char_t,
class traits_t>
546 template<range_of_t_c<
char_t>
string_t>
549 string_t sWhat) noexcept
551 return insert(
static_cast<size_type
>(itPos - begin()), sWhat.cbegin(), sWhat.cend());
554 template<
class char_t,
class traits_t>
557 insert(size(), &chSymbol, 1);
560 template<
class char_t,
class traits_t>
563 insert(0, &chSymbol, 1);
566 template<
class char_t,
class traits_t>
569 if (
const typename iterator::difference_type nCharsToErase = itLast - itFirst; nCharsToErase > 0)
571 const size_type nStartSize = size();
572 const size_type nSymbolsToCopy = itLast != end() ? traits_t::length(itLast.operator->()) : 0;
574 if (nSymbolsToCopy > 0)
576 std::memmove(itFirst.operator->(), itLast.operator->(), nSymbolsToCopy *
sizeof(value_type));
579 if (
static_cast<typename iterator::difference_type
>(nStartSize) >= nCharsToErase)
581 _resize(nStartSize - nCharsToErase);
586 template<
class char_t,
class traits_t>
589 erase(itPos, itPos + 1);
592 template<
class char_t,
class traits_t>
598 template<
class char_t,
class traits_t>
604 template<
class char_t,
class traits_t>
607 value_type chRet = back();
612 template<
class char_t,
class traits_t>
615 value_type chRet = front();
620 template<
class char_t,
class traits_t>
626 return traits_t::is_space(ch);
630 template<
class char_t,
class traits_t>
632 value_type chSymbol) noexcept
635 [chSymbol](value_type ch)
637 return ch == chSymbol;
641 template<
class char_t,
class traits_t>
643 const_pointer pszStr) noexcept
648 [pszStr](value_type ch)
650 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
665 template<
class char_t,
class traits_t>
667 const_pointer pszStr,
668 size_type nStrSize) noexcept
673 [pszStr, nStrSize](value_type ch)
675 for (size_type j = 0; j < nStrSize; ++j)
688 template<
class char_t,
class traits_t>
692 return trim_left(sStr.data(), sStr.size());
695 template<
class char_t,
class traits_t>
696 template<
class fwd_it_t>
699 fwd_it_t itEnd) noexcept
702 [itBegin, itEnd](
auto ch)
704 for (
auto it = itBegin; it != itEnd; ++it)
712 template<
class char_t,
class traits_t>
713 template<range_of_t_c<
char_t>
string_t>
715 const string_t& sStr) noexcept
717 return trim_left(sStr.cbegin(), sStr.cend());
720 template<
class char_t,
class traits_t>
726 return traits_t::is_space(ch);
730 template<
class char_t,
class traits_t>
732 value_type chSymbol) noexcept
735 [chSymbol](value_type ch)
737 return ch == chSymbol;
741 template<
class char_t,
class traits_t>
743 const_pointer pszStr) noexcept
748 [pszStr](value_type ch)
750 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
765 template<
class char_t,
class traits_t>
767 const_pointer pszStr,
768 size_type nStrSize) noexcept
773 [pszStr, nStrSize](value_type ch)
775 for (size_type j = 0; j < nStrSize; ++j)
788 template<
class char_t,
class traits_t>
792 return trim_right(sStr.data(), sStr.size());
795 template<
class char_t,
class traits_t>
796 template<
class fwd_it_t>
799 fwd_it_t itEnd) noexcept
802 [itBegin, itEnd](
auto ch)
804 for (
auto it = itBegin; it != itEnd; ++it)
812 template<
class char_t,
class traits_t>
813 template<range_of_t_c<
char_t>
string_t>
815 const string_t& sStr) noexcept
817 return trim_right(sStr.cbegin(), sStr.cend());
820 template<
class char_t,
class traits_t>
826 return traits_t::is_space(ch);
830 template<
class char_t,
class traits_t>
832 value_type chSymbol) noexcept
835 [chSymbol](value_type ch)
837 return ch == chSymbol;
841 template<
class char_t,
class traits_t>
843 const_pointer pszStr) noexcept
848 [pszStr](value_type ch)
850 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
865 template<
class char_t,
class traits_t>
867 const_pointer pszStr,
868 size_type nStrSize) noexcept
873 [pszStr, nStrSize](value_type ch)
875 for (size_type j = 0; j < nStrSize; ++j)
888 template<
class char_t,
class traits_t>
892 return trim(sStr.data(), sStr.size());
895 template<
class char_t,
class traits_t>
896 template<
class fwd_it_t>
899 fwd_it_t itEnd) noexcept
902 [itBegin, itEnd](
auto ch)
904 for (
auto it = itBegin; it != itEnd; ++it)
912 template<
class char_t,
class traits_t>
913 template<range_of_t_c<
char_t>
string_t>
915 const string_t& sStr) noexcept
917 return trim(sStr.cbegin(), sStr.cend());
920 template<
class char_t,
class traits_t>
924 size_type nEnd) noexcept
926 size_type nPos = find(chSymbol, nBegin, nEnd);
934 template<
class char_t,
class traits_t>
936 const_pointer pszStr,
939 size_type nStrSize) noexcept
943 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
944 const size_type nPos = find(pszStr, nBegin, nLocalStrSize, nEnd);
947 erase(nPos, nLocalStrSize);
957 template<
class char_t,
class traits_t>
961 size_type nEnd) noexcept
963 const size_type nPos = find(sStr, nBegin, nEnd);
966 erase(nPos, sStr.size());
971 template<
class char_t,
class traits_t>
972 template<
class fwd_it_t>
977 size_type nEnd) noexcept
979 const size_type nPos = find(itBegin, itEnd, nBegin, nEnd);
982 erase(nPos,
static_cast<size_type
>(std::distance(itBegin, itEnd)));
987 template<
class char_t,
class traits_t>
988 template<range_of_t_c<
char_t>
string_t>
990 const string_t& sStr,
992 size_type nEnd) noexcept
994 return remove(sStr.cbegin(), sStr.cend(), nBegin, nEnd);
997 template<
class char_t,
class traits_t>
1000 return remove(chSymbol,
static_cast<size_type
>(0),
static_cast<size_type
>(1)) != npos;
1003 template<
class char_t,
class traits_t>
1006 return remove(pszStr,
static_cast<size_type
>(0), nStrSize, nStrSize) != npos;
1009 template<
class char_t,
class traits_t>
1012 return remove(sStr,
static_cast<size_type
>(0), sStr.size()) != npos;
1015 template<
class char_t,
class traits_t>
1016 template<
class fwd_it_t>
1019 return remove(itBegin, itEnd,
static_cast<size_type
>(0),
static_cast<size_type
>(std::distance(itBegin, itEnd)))
1023 template<
class char_t,
class traits_t>
1024 template<range_of_t_c<
char_t>
string_t>
1027 return remove_prefix(sStr.cbegin(), sStr.cend());
1030 template<
class char_t,
class traits_t>
1033 const size_type nSize = size();
1034 return remove(chSymbol, nSize - 1, nSize) != npos;
1037 template<
class char_t,
class traits_t>
1042 const size_type nSize = size();
1043 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
1045 return remove(pszStr, nSize - nLocalStrSize, nSize, nLocalStrSize) != npos;
1053 template<
class char_t,
class traits_t>
1056 return remove_suffix(sStr.data(), sStr.size());
1059 template<
class char_t,
class traits_t>
1060 template<
class fwd_it_t>
1063 const size_type nSize = size();
1064 return remove(itBegin, itEnd, nSize -
static_cast<size_type
>(std::distance(itBegin, itEnd)), nSize) != npos;
1067 template<
class char_t,
class traits_t>
1068 template<range_of_t_c<
char_t>
string_t>
1071 return remove_suffix(sStr.cbegin(), sStr.cend());
1074 template<
class char_t,
class traits_t>
1076 value_type chSymbol,
1078 size_type nEnd) noexcept
1080 size_type nOccurrences = 0;
1081 size_type nLastOccurrencePos = nBegin;
1086 nLastOccurrencePos = remove(chSymbol, nLastOccurrencePos, nEnd);
1087 }
while (nLastOccurrencePos != npos);
1089 return nOccurrences - 1;
1092 template<
class char_t,
class traits_t>
1094 const_pointer pszStr,
1097 size_type nStrSize) noexcept
1101 size_type nOccurrences = 0;
1102 size_type nLastOccurrencePos = nBegin;
1107 nLastOccurrencePos = remove(pszStr, nLastOccurrencePos, nEnd, nStrSize);
1108 }
while (nLastOccurrencePos != npos);
1110 return nOccurrences - 1;
1118 template<
class char_t,
class traits_t>
1122 size_type nEnd) noexcept
1124 return remove_all(sStr.data(), nBegin, nEnd, sStr.size());
1127 template<
class char_t,
class traits_t>
1128 template<
class fwd_it_t>
1133 size_type nEnd) noexcept
1135 size_type nOccurrences = 0;
1136 size_type nLastOccurrencePos = nBegin;
1141 nLastOccurrencePos = remove(itFirst, itLast, nLastOccurrencePos, nEnd);
1142 }
while (nLastOccurrencePos != npos);
1144 return nOccurrences - 1;
1147 template<
class char_t,
class traits_t>
1148 template<range_of_t_c<
char_t>
string_t>
1150 const string_t& sStr,
1152 size_type nEnd) noexcept
1154 return remove_all(sStr.cbegin(), sStr.cend(), nBegin, nEnd);
1157 template<
class char_t,
class traits_t>
1161 const_pointer pszReplace,
1162 size_t nReplaceSize) noexcept
1164 const size_type nStartSize = size();
1165 const size_type nNewSize = nStartSize - nSize + nReplaceSize;
1167 _resize(nNewSize, sbo_resize_type::reserve);
1170 data() + nBegin + nReplaceSize,
1171 data() + nBegin + nSize,
1172 (nStartSize - nBegin - nSize) *
sizeof(value_type));
1174 std::memcpy(data() + nBegin, pszReplace, nReplaceSize *
sizeof(value_type));
1178 return nBegin + nReplaceSize;
1181 template<
class char_t,
class traits_t>
1182 template<
class replace_
string_t>
1186 const replace_string_t& sReplace) noexcept
1188 return replace(nBegin, nSize, _get_string_view_like_data(sReplace), _get_string_view_like_size(sReplace));
1191 template<
class char_t,
class traits_t>
1192 template<
class find_
string_t,
class replace_
string_t>
1194 const find_string_t& sFind,
1195 const replace_string_t& sReplace,
1197 size_type nEnd) noexcept
1199 if (size_type nPos = find(sFind, nBegin, nEnd); nPos != npos)
1203 _get_string_view_like_size(sFind),
1204 _get_string_view_like_data(sReplace),
1205 _get_string_view_like_size(sReplace));
1213 template<
class char_t,
class traits_t>
1214 template<
class find_
string_t,
class replace_
string_t>
1216 const find_string_t& sFind,
1217 const replace_string_t& sReplace,
1219 size_type nEnd) noexcept
1221 size_type nOccurrences = 0;
1222 size_type nPos = nBegin;
1226 nPos = replace(sFind, sReplace, nPos, nEnd);
1229 }
while (nPos != npos);
1231 return nOccurrences;
1234 template<
class char_t,
class traits_t>
1237 return compare(&chSymbol, 1);
1240 template<
class char_t,
class traits_t>
1243 return traits_t::compare(data(), pszStr);
1246 template<
class char_t,
class traits_t>
1249 return traits_t::compare_n(data(), pStr, nSymbols);
1252 template<
class char_t,
class traits_t>
1255 return compare(sStr.data(), sStr.size());
1258 template<
class char_t,
class traits_t>
1259 template<
class fwd_it_t>
1262 return iter_strcmp(cbegin(), cend(), itBegin, itEnd);
1265 template<
class char_t,
class traits_t>
1266 template<range_of_t_c<
char_t>
string_t>
1269 return compare(sStr.cbegin(), sStr.cend());
1272 template<
class char_t,
class traits_t>
1274 value_type chSymbol,
1276 size_type nEnd)
const noexcept
1281 [chSymbol](const_pointer pCurrentChar)
1283 return *pCurrentChar == chSymbol;
1287 template<
class char_t,
class traits_t>
1289 const_pointer pszWhat,
1291 size_type nWhatSize,
1292 size_type nEnd)
const noexcept
1296 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1301 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1303 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1312 template<
class char_t,
class traits_t>
1316 size_type nEnd)
const noexcept
1318 return find(sWhat.data(), nBegin, sWhat.size(), nEnd);
1321 template<
class char_t,
class traits_t>
1322 template<
class fwd_it_t>
1324 fwd_it_t itWhatBegin,
1327 size_type nEnd)
const noexcept
1329 const size_t nWhatSize = itWhatEnd - itWhatBegin;
1333 [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
1335 const size_t nStart =
static_cast<size_type
>(pCurrentChar - data());
1344 template<
class char_t,
class traits_t>
1345 template<range_of_t_c<
char_t>
string_t>
1349 size_type nEnd)
const noexcept
1351 return find(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
1354 template<
class char_t,
class traits_t>
1356 value_type chSymbol,
1358 size_type nEnd)
const noexcept
1363 [chSymbol](const_pointer pCurrentChar)
1365 return *pCurrentChar == chSymbol;
1369 template<
class char_t,
class traits_t>
1371 const_pointer pszWhat,
1373 size_type nWhatSize,
1374 size_type nEnd)
const noexcept
1378 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1383 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1385 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1394 template<
class char_t,
class traits_t>
1398 size_type nEnd)
const noexcept
1400 return rfind(sWhat.data(), nBegin, sWhat.size(), nEnd);
1403 template<
class char_t,
class traits_t>
1404 template<
class fwd_it_t>
1406 fwd_it_t itWhatBegin,
1409 size_type nEnd)
const noexcept
1411 const size_t nWhatSize = itWhatEnd - itWhatBegin;
1415 [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
1417 const size_t nStart =
static_cast<size_type
>(pCurrentChar - data());
1426 template<
class char_t,
class traits_t>
1427 template<range_of_t_c<
char_t>
string_t>
1431 size_type nEnd)
const noexcept
1433 return rfind(sWhat.cbegin(), sWhat.cend(), nBegin, nEnd);
1436 template<
class char_t,
class traits_t>
1438 value_type chSymbol,
1439 size_type nBegin)
const noexcept
1441 return find(chSymbol, nBegin);
1444 template<
class char_t,
class traits_t>
1446 const_pointer pszWhat,
1448 size_type nWhatSize)
const noexcept
1452 return _find_first_of(
1454 pszWhat + nWhatSize,
1456 [](const_pointer pChar)
1467 template<
class char_t,
class traits_t>
1469 const_pointer pszWhat,
1470 size_type nBegin)
const noexcept
1474 return _find_first_of(
1476 static_cast<const_pointer
>(
nullptr),
1478 [](const_pointer pChar)
1480 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1489 template<
class char_t,
class traits_t>
1492 size_type nBegin)
const noexcept
1494 return find_first_of(sWhat.data(), nBegin, sWhat.size());
1497 template<
class char_t,
class traits_t>
1498 template<
class fwd_it_t>
1500 fwd_it_t itWhatBegin,
1502 size_type nBegin)
const noexcept
1504 return _find_first_of(
1514 template<
class char_t,
class traits_t>
1515 template<range_of_t_c<
char_t>
string_t>
1518 size_type nBegin)
const noexcept
1520 return find_first_of(sWhat.cbegin(), sWhat.cend(), nBegin);
1523 template<
class char_t,
class traits_t>
1525 value_type chSymbol,
1526 size_type nEnd)
const noexcept
1528 return rfind(chSymbol, npos, nEnd);
1531 template<
class char_t,
class traits_t>
1533 const_pointer pszWhat,
1535 size_type nWhatSize)
const noexcept
1539 return _find_last_of(
1541 pszWhat + nWhatSize,
1543 [](const_pointer pChar)
1554 template<
class char_t,
class traits_t>
1556 const_pointer pszWhat,
1557 size_type nEnd)
const noexcept
1561 return _find_last_of(
1563 static_cast<const_pointer
>(
nullptr),
1565 [](const_pointer pChar)
1567 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1576 template<
class char_t,
class traits_t>
1579 size_type nEnd)
const noexcept
1581 return find_last_of(sWhat.data(), nEnd, sWhat.size());
1584 template<
class char_t,
class traits_t>
1585 template<
class fwd_it_t>
1587 fwd_it_t itWhatBegin,
1589 size_type nEnd)
const noexcept
1591 return _find_last_of(
1601 template<
class char_t,
class traits_t>
1602 template<range_of_t_c<
char_t>
string_t>
1605 size_type nEnd)
const noexcept
1607 return find_last_of(sWhat.cbegin(), sWhat.cend(), nEnd);
1610 template<
class char_t,
class traits_t>
1612 value_type chSymbol,
1613 size_type nBegin)
const noexcept
1618 [chSymbol](const_pointer pCurrentChar)
1620 return *pCurrentChar != chSymbol;
1624 template<
class char_t,
class traits_t>
1626 const_pointer pszWhat,
1628 size_type nWhatSize)
const noexcept
1632 return _find_first_not_of(
1634 pszWhat + nWhatSize,
1636 [](const_pointer pChar)
1647 template<
class char_t,
class traits_t>
1649 const_pointer pszWhat,
1650 size_type nBegin)
const noexcept
1654 return _find_first_not_of(
1656 static_cast<const_pointer
>(
nullptr),
1658 [](const_pointer pChar)
1660 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1669 template<
class char_t,
class traits_t>
1672 size_type nBegin)
const noexcept
1674 return find_first_not_of(sWhat.data(), nBegin, sWhat.size());
1677 template<
class char_t,
class traits_t>
1678 template<
class fwd_it_t>
1680 fwd_it_t itWhatBegin,
1682 size_type nBegin)
const noexcept
1684 return _find_first_not_of(
1694 template<
class char_t,
class traits_t>
1695 template<range_of_t_c<
char_t>
string_t>
1698 size_type nBegin)
const noexcept
1700 return find_first_not_of(sWhat.cbegin(), sWhat.cend(), nBegin);
1703 template<
class char_t,
class traits_t>
1705 value_type chSymbol,
1706 size_type nEnd)
const noexcept
1711 [chSymbol](const_pointer pCurrentChar)
1713 return *pCurrentChar != chSymbol;
1717 template<
class char_t,
class traits_t>
1719 const_pointer pszWhat,
1721 size_type nWhatSize)
const noexcept
1725 return _find_last_not_of(
1727 pszWhat + nWhatSize,
1729 [](const_pointer pChar)
1740 template<
class char_t,
class traits_t>
1742 const_pointer pszWhat,
1743 size_type nEnd)
const noexcept
1747 return _find_last_not_of(
1749 static_cast<const_pointer
>(
nullptr),
1751 [](const_pointer pChar)
1753 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1762 template<
class char_t,
class traits_t>
1765 size_type nEnd)
const noexcept
1767 return find_last_not_of(sWhat.data(), nEnd, sWhat.size());
1770 template<
class char_t,
class traits_t>
1771 template<
class fwd_it_t>
1773 fwd_it_t itWhatBegin,
1775 size_type nEnd)
const noexcept
1777 return _find_last_not_of(
1787 template<
class char_t,
class traits_t>
1788 template<range_of_t_c<
char_t>
string_t>
1791 size_type nEnd)
const noexcept
1793 return find_last_not_of(sWhat.cbegin(), sWhat.cend(), nEnd);
1796 template<
class char_t,
class traits_t>
1798 const value_type chSeparator)
const noexcept
1802 size_type nStart = 0;
1804 while ((nEnd = find(chSeparator, nStart)) != npos)
1806 tokens.emplace_back(substr(nStart, nEnd - nStart));
1808 while (traits_t::compare_n(data() + nStart, &chSeparator, 1) == 0)
1812 if (nStart != size())
1813 tokens.emplace_back(substr(nStart));
1815 return std::move(tokens);
1818 template<
class char_t,
class traits_t>
1820 const_pointer pszSeparator,
1821 size_type nSepLen)
const noexcept
1828 if (nSepLen == npos)
1829 nSepLen = traits_t::length(pszSeparator);
1831 size_type nStart = 0;
1833 while ((nEnd = find(pszSeparator, nStart, nSepLen, npos)) != npos)
1835 tokens.emplace_back(substr(nStart, nEnd - nStart));
1837 while (traits_t::compare_n(data() + nStart, pszSeparator, nSepLen) == 0)
1841 if (nStart != size())
1842 tokens.emplace_back(substr(nStart));
1847 template<
class char_t,
class traits_t>
1851 return split(sSeparator.data(), sSeparator.size());
1854 template<
class char_t,
class traits_t>
1855 template<
class fwd_it_t>
1857 fwd_it_t itSepFirst,
1858 fwd_it_t itSepLast)
const noexcept
1862 const size_type nSepLen =
static_cast<size_type
>(std::distance(itSepFirst, itSepLast));
1864 size_type nStart = 0;
1866 while ((nEnd = find(itSepFirst, itSepLast, nStart)) != npos)
1868 tokens.emplace_back(substr(nStart, nEnd - nStart));
1869 nStart = nEnd + nSepLen;
1871 tokens.emplace_back(substr(nStart));
1876 template<
class char_t,
class traits_t>
1877 template<range_of_t_c<
char_t>
string_t>
1879 const string_t& sSeparator)
const noexcept
1881 return split(sSeparator.cbegin(), sSeparator.cend());
1884 template<
class char_t,
class traits_t>
1888 return at(0) == chSymbol;
1893 template<
class char_t,
class traits_t>
1898 if (size_type nThisSize = size(); nThisSize > 0)
1900 if (nStrSize == npos)
1901 nStrSize = traits_t::length(pszStr);
1903 if (nStrSize <= nThisSize)
1904 return traits_t::compare_n(data(), pszStr, nStrSize) == 0;
1911 template<
class char_t,
class traits_t>
1914 return starts_with(sStr.data(), sStr.size());
1917 template<
class char_t,
class traits_t>
1918 template<
class fwd_it_t>
1921 auto nStrSize = std::distance(itBegin, itEnd);
1922 return iter_strcmp(cbegin(), cbegin() +
static_cast<size_type
>(nStrSize), itBegin, itEnd) == 0;
1925 template<
class char_t,
class traits_t>
1926 template<range_of_t_c<
char_t>
string_t>
1929 return starts_with(sStr.cbegin(), sStr.cend());
1932 template<
class char_t,
class traits_t>
1935 const size_type nSize = size();
1937 return at(nSize - 1) == chSymbol;
1942 template<
class char_t,
class traits_t>
1948 if (nStrSize == npos)
1949 nStrSize = traits_t::length(pszStr);
1951 return ends_with(pszStr, pszStr + nStrSize);
1954 template<
class char_t,
class traits_t>
1957 return ends_with(sStr.data(), sStr.size());
1960 template<
class char_t,
class traits_t>
1961 template<
class fwd_it_t>
1964 const size_t nOtherSize =
static_cast<size_type
>(std::distance(itBegin, itEnd));
1965 if (nOtherSize > size())
1968 return iter_strcmp(cend() - nOtherSize, cend(), itBegin, itEnd) == 0;
1971 template<
class char_t,
class traits_t>
1972 template<range_of_t_c<
char_t>
string_t>
1975 return ends_with(sStr.cbegin(), sStr.cend());
1978 template<
class char_t,
class traits_t>
1981 return find(chSymbol) != npos;
1984 template<
class char_t,
class traits_t>
1987 return find(pszStr, 0, nStrSize) != npos;
1990 template<
class char_t,
class traits_t>
1993 return find(sStr) != npos;
1996 template<
class char_t,
class traits_t>
1997 template<
class fwd_it_t>
2000 return find(itBegin, itEnd) != npos;
2003 template<
class char_t,
class traits_t>
2004 template<range_of_t_c<
char_t>
string_t>
2007 return find(sStr) != npos;
2010 template<
class char_t,
class traits_t>
2017 template<
class char_t,
class traits_t>
2018 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(basic_string&& sStr) noexcept
2020 assign(std::move(sStr));
2024 template<
class char_t,
class traits_t>
2025 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const basic_string& sStr) noexcept
2031 template<
class char_t,
class traits_t>
2032 template<range_of_t_c<
char_t>
string_t>
2033 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const string_t& sStr) noexcept
2039 template<
class char_t,
class traits_t>
2040 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(value_type chSymbol) noexcept
2046 template<
class char_t,
class traits_t>
2047 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(const_pointer pszSource) noexcept
2050 append(pszSource, traits_t::length(pszSource));
2055 template<
class char_t,
class traits_t>
2056 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const basic_string& sStr) noexcept
2058 append(sStr.data(), sStr.size());
2062 template<
class char_t,
class traits_t>
2063 template<range_of_t_c<
char_t>
string_t>
2064 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const string_t& sStr) noexcept
2066 append(sStr.cbegin(), sStr.cend());
2070 template<
class char_t,
class traits_t>
2071 inline bool basic_string<char_t, traits_t>::operator==(value_type chSymbol)
const noexcept
2073 return size() == 1 && at(0) == chSymbol;
2076 template<
class char_t,
class traits_t>
2077 inline bool basic_string<char_t, traits_t>::operator==(const_pointer pszSource)
const noexcept
2079 return compare(pszSource) == 0;
2082 template<
class char_t,
class traits_t>
2083 inline bool basic_string<char_t, traits_t>::operator==(
const basic_string& sStr)
const noexcept
2085 return size() == sStr.size() && compare(sStr.data(), sStr.size()) == 0;
2088 template<
class char_t,
class traits_t>
2089 template<range_of_t_c<
char_t>
string_t>
2090 inline bool basic_string<char_t, traits_t>::operator==(
const string_t& sStr)
const noexcept
2092 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) == 0;
2095 template<
class char_t,
class traits_t>
2096 inline bool basic_string<char_t, traits_t>::operator!=(value_type chSymbol)
const noexcept
2098 return !operator==(chSymbol);
2101 template<
class char_t,
class traits_t>
2102 inline bool basic_string<char_t, traits_t>::operator!=(const_pointer pszSource)
const noexcept
2104 return !operator==(pszSource);
2107 template<
class char_t,
class traits_t>
2108 inline bool basic_string<char_t, traits_t>::operator!=(
const basic_string& sStr)
const noexcept
2110 return !operator==(sStr);
2113 template<
class char_t,
class traits_t>
2114 template<range_of_t_c<
char_t>
string_t>
2115 inline bool basic_string<char_t, traits_t>::operator!=(
const string_t& sStr)
const noexcept
2117 return !operator==(sStr);
2120 template<
class char_t,
class traits_t>
2121 inline bool basic_string<char_t, traits_t>::operator<(value_type chSymbol)
const noexcept
2123 return compare(&chSymbol, 1) < 0;
2126 template<
class char_t,
class traits_t>
2127 inline bool basic_string<char_t, traits_t>::operator<(const_pointer pszSource)
const noexcept
2129 return compare(pszSource) < 0;
2132 template<
class char_t,
class traits_t>
2133 inline bool basic_string<char_t, traits_t>::operator<(
const basic_string& sStr)
const noexcept
2135 return compare(sStr.data(), sStr.size()) < 0;
2138 template<
class char_t,
class traits_t>
2139 template<range_of_t_c<
char_t>
string_t>
2140 inline bool basic_string<char_t, traits_t>::operator<(
const string_t& sStr)
const noexcept
2142 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) < 0;
2145 template<
class char_t,
class traits_t>
2146 inline bool basic_string<char_t, traits_t>::operator<=(value_type chSymbol)
const noexcept
2148 return compare(&chSymbol, 1) <= 0;
2151 template<
class char_t,
class traits_t>
2152 inline bool basic_string<char_t, traits_t>::operator<=(const_pointer pszSource)
const noexcept
2154 return compare(pszSource) <= 0;
2157 template<
class char_t,
class traits_t>
2158 inline bool basic_string<char_t, traits_t>::operator<=(
const basic_string& sStr)
const noexcept
2160 return compare(sStr.data(), sStr.size()) <= 0;
2163 template<
class char_t,
class traits_t>
2164 template<range_of_t_c<
char_t>
string_t>
2165 inline bool basic_string<char_t, traits_t>::operator<=(
const string_t& sStr)
const noexcept
2167 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) <= 0;
2170 template<
class char_t,
class traits_t>
2171 inline bool basic_string<char_t, traits_t>::operator>(value_type chSymbol)
const noexcept
2173 return compare(&chSymbol, 1) > 0;
2176 template<
class char_t,
class traits_t>
2177 inline bool basic_string<char_t, traits_t>::operator>(const_pointer pszSource)
const noexcept
2179 return compare(pszSource) > 0;
2182 template<
class char_t,
class traits_t>
2183 inline bool basic_string<char_t, traits_t>::operator>(
const basic_string& sStr)
const noexcept
2185 return compare(sStr.data(), sStr.size()) > 0;
2188 template<
class char_t,
class traits_t>
2189 template<range_of_t_c<
char_t>
string_t>
2190 inline bool basic_string<char_t, traits_t>::operator>(
const string_t& sStr)
const noexcept
2192 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) > 0;
2195 template<
class char_t,
class traits_t>
2196 inline bool basic_string<char_t, traits_t>::operator>=(value_type chSymbol)
const noexcept
2198 return compare(&chSymbol, 1) >= 0;
2201 template<
class char_t,
class traits_t>
2202 inline bool basic_string<char_t, traits_t>::operator>=(const_pointer pszSource)
const noexcept
2204 return compare(pszSource) >= 0;
2207 template<
class char_t,
class traits_t>
2208 inline bool basic_string<char_t, traits_t>::operator>=(
const basic_string& sStr)
const noexcept
2210 return compare(sStr.data(), sStr.size()) >= 0;
2213 template<
class char_t,
class traits_t>
2214 template<range_of_t_c<
char_t>
string_t>
2215 inline bool basic_string<char_t, traits_t>::operator>=(
const string_t& sStr)
const noexcept
2217 return iter_strcmp(cbegin(), cend(), sStr.cbegin(), sStr.cend()) >= 0;
2220 template<
class char_t,
class traits_t>
2221 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::operator[](
2222 size_type nSymbol) noexcept
2224 return data()[nSymbol];
2227 template<
class char_t,
class traits_t>
2228 inline typename basic_string<char_t, traits_t>::const_reference basic_string<char_t, traits_t>::operator[](
2229 size_type nSymbol)
const noexcept
2231 return data()[nSymbol];
2234 template<
class char_t,
class traits_t>
2235 inline basic_string<char_t, traits_t>::operator std::basic_string_view<
2236 typename basic_string<char_t, traits_t>::value_type>()
const noexcept
2238 return string_view(data(), size());
2241 template<
class char_t,
class traits_t>
2242 inline basic_string<char_t, traits_t>::operator bool() const noexcept
2247 template<
class char_t,
class traits_t>
2248 inline bool basic_string<char_t, traits_t>::_resize(size_type nSymbols, sbo_resize_type eType) noexcept
2250 const bool bRet = m_Data.resize(
2251 (nSymbols + 1) *
sizeof(value_type),
2252 traits_t::align() *
sizeof(value_type),
2256 if (bRet && eType != sbo_resize_type::reserve)
2257 (*this)[nSymbols] =
QX_CHAR_PREFIX(
typename traits_t::value_type,
'\0');
2262 template<
class char_t,
class traits_t>
2263 template<
class searcher_t>
2264 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_left(
2265 const searcher_t& searcher) noexcept
2267 size_type nSymbols = 0;
2269 for (size_type i = 0; i < size(); ++i)
2271 if (searcher(at(i)))
2281 template<
class char_t,
class traits_t>
2282 template<
class searcher_t>
2283 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_right(
2284 const searcher_t& searcher) noexcept
2286 size_type nSymbols = 0;
2287 size_type nSize = size();
2289 for (size_type i = nSize - 1; i != std::numeric_limits<size_type>::max(); --i)
2291 if (searcher(at(i)))
2297 erase(nSize - nSymbols, nSymbols);
2301 template<
class char_t,
class traits_t>
2302 template<
class searcher_t>
2303 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim(
2304 const searcher_t& searcher) noexcept
2306 const size_type nSize = size();
2307 size_type nStartPos = 0;
2308 size_type nEndPos = nSize;
2310 while (nStartPos < nSize && searcher(at(nStartPos)))
2313 while (nEndPos > nStartPos && searcher(at(nEndPos - 1)))
2316 size_type nNewSize = nEndPos - nStartPos;
2318 std::memmove(data(), data() + nStartPos, nNewSize *
sizeof(value_type));
2321 return nSize - nNewSize;
2324 template<
class char_t,
class traits_t>
2325 template<
class comparator_t>
2326 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find(
2329 const comparator_t& comparator)
const noexcept
2334 const_pointer pData = data();
2335 const_pointer pCurrentChar = pData + nBegin;
2336 const_pointer pEnd = pData + nEnd;
2338 while (pCurrentChar < pEnd)
2340 if (comparator(pCurrentChar))
2341 return static_cast<size_type
>(pCurrentChar - pData);
2349 template<
class char_t,
class traits_t>
2350 template<
class comparator_t>
2351 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_rfind(
2354 const comparator_t& comparator)
const noexcept
2357 nBegin = size() - 1;
2359 const_pointer pData = data();
2360 const_pointer pCurrentChar = pData + nBegin;
2361 const_pointer pEnd = pData + nEnd;
2363 while (pCurrentChar >= pEnd)
2365 if (comparator(pCurrentChar))
2366 return static_cast<size_type
>(pCurrentChar - pData);
2374 template<
class char_t,
class traits_t>
2375 template<
class incrementer_t,
class fwd_it_t>
2376 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_first_of(
2380 const incrementer_t& incrementer)
const noexcept
2382 for (size_type i = nBegin; i < size(); ++i)
2383 for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
2390 template<
class char_t,
class traits_t>
2391 template<
class incrementer_t,
class fwd_it_t>
2392 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_of(
2396 const incrementer_t& incrementer)
const noexcept
2398 for (size_type i = size() - 1; i != nEnd - 1; --i)
2399 for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
2406 template<
class char_t,
class traits_t>
2407 template<
class incrementer_t,
class fwd_it_t>
2408 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_first_not_of(
2412 const incrementer_t& incrementer)
const noexcept
2414 for (size_type i = nBegin; i < size(); ++i)
2416 bool bFoundOneOf =
false;
2417 for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
2418 bFoundOneOf |= *it == at(i);
2427 template<
class char_t,
class traits_t>
2428 template<
class incrementer_t,
class fwd_it_t>
2429 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_not_of(
2433 const incrementer_t& incrementer)
const noexcept
2435 for (size_type i = size() - 1; i != nEnd - 1; --i)
2437 bool bFoundOneOf =
false;
2438 for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
2439 bFoundOneOf |= *it == at(i);
2448 template<
class char_t,
class traits_t>
2449 template<
class string_view_like_t>
2450 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_get_string_view_like_size(
2451 const string_view_like_t& sValue) noexcept
2453 if constexpr (std::is_same_v<string_view_like_t, value_type>)
2457 else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
2459 return traits_t::length(sValue);
2461 else if constexpr (range_of_t_c<string_view_like_t, char_t>)
2463 return sValue.size();
2472 template<
class char_t,
class traits_t>
2473 template<
class string_view_like_t>
2474 inline typename basic_string<char_t, traits_t>::const_pointer basic_string<char_t, traits_t>::
2475 _get_string_view_like_data(
const string_view_like_t& sValue) noexcept
2477 if constexpr (std::is_same_v<string_view_like_t, value_type>)
2481 else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
2485 else if constexpr (range_of_t_c<string_view_like_t, char_t>)
2487 return sValue.data();
2496 template<
class T,
class char_t,
class traits_t>
2502 template<
class char_t,
class traits_t>
2503 basic_string<char_t, traits_t> operator+(
2504 const basic_string<char_t, traits_t>& lhs,
2505 const basic_string<char_t, traits_t>& rhs) noexcept
2507 basic_string<char_t, traits_t> str(lhs);
2512 template<
class char_t,
class traits_t>
2513 basic_string<char_t, traits_t> operator+(
2514 basic_string<char_t, traits_t>&& lhs,
2515 const basic_string<char_t, traits_t>& rhs) noexcept
2517 basic_string<char_t, traits_t> str(std::move(lhs));
2522 template<
class char_t,
class traits_t>
2523 basic_string<char_t, traits_t> operator+(
2524 const basic_string<char_t, traits_t>& lhs,
2525 typename traits_t::const_pointer rhs) noexcept
2527 basic_string<char_t, traits_t> str(lhs);
2532 template<
class char_t,
class traits_t>
2533 basic_string<char_t, traits_t> operator+(
2534 basic_string<char_t, traits_t>&& lhs,
2535 typename traits_t::const_pointer rhs) noexcept
2537 basic_string<char_t, traits_t> str(std::move(lhs));
2542 template<
class char_t,
class traits_t>
2543 basic_string<char_t, traits_t> operator+(
2544 typename traits_t::const_pointer lhs,
2545 const basic_string<char_t, traits_t>& rhs) noexcept
2547 basic_string<char_t, traits_t> str(lhs);
2552 template<
class char_t,
class traits_t>
2553 basic_string<char_t, traits_t> operator+(
2554 const basic_string<char_t, traits_t>& lhs,
2555 typename traits_t::value_type rhs) noexcept
2557 basic_string<char_t, traits_t> str(lhs);
2562 template<
class char_t,
class traits_t>
2563 basic_string<char_t, traits_t> operator+(
2564 basic_string<char_t, traits_t>&& lhs,
2565 typename traits_t::value_type rhs) noexcept
2567 basic_string<char_t, traits_t> str(std::move(lhs));
2572 template<
class char_t,
class traits_t>
2573 basic_string<char_t, traits_t> operator+(
2574 typename traits_t::value_type lhs,
2575 const basic_string<char_t, traits_t>& rhs) noexcept
2577 basic_string<char_t, traits_t> str(&lhs, 1);
2582 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2583 basic_string<char_t, traits_t> operator+(
const basic_string<char_t, traits_t>& lhs,
const string_t& rhs) noexcept
2585 basic_string<char_t, traits_t> str(lhs);
2590 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2591 basic_string<char_t, traits_t> operator+(basic_string<char_t, traits_t>&& lhs,
const string_t& rhs) noexcept
2593 basic_string<char_t, traits_t> str(std::move(lhs));
2598 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2599 basic_string<char_t, traits_t> operator+(
const string_t& lhs,
const basic_string<char_t, traits_t>& rhs) noexcept
2601 basic_string<char_t, traits_t> str(lhs);
2610 template<
class char_t,
class traits_t>
2611 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::size() const noexcept
2613 const size_type nSize = m_Data.size() /
sizeof(value_type);
2614 return nSize == 0 ? 0 : nSize - 1;
2621 template<
class char_t,
class traits_t>
2622 inline typename basic_string<char_t, traits_t>::pointer basic_string<char_t, traits_t>::data() noexcept
2624 return reinterpret_cast<pointer
>(m_Data.data());
2632 template<
class char_t,
class traits_t>
2633 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::at(size_type nIndex)
2635 if (nIndex >= size())
2636 throw std::out_of_range(
"invalid string position");
2638 return data()[nIndex];
2644 template<
class char_t,
class traits_t>
2645 inline void basic_string<char_t, traits_t>::clear() noexcept
2659 template<
class char_t,
class traits_t>
2660 struct hash<qx::basic_string<char_t, traits_t>>
2664 return traits_t::hash_function(str.data(), traits_t::hash_seed(), str.size());
2670 template<
class char_t,
class traits_t>
2678 template<
class char_t,
class traits_t>
2681 template<
class format_context_type>
2693 template<
class char_t,
class traits_t>
2694 qx::details::ostream<char_t>& operator<<(
2695 qx::details::ostream<char_t>& os,
2702 template<
class char_t,
class traits_t>
2705 typename qx::details::istream<traits_t>::iostate ret_bit = qx::details::istream<traits_t>::goodbit;
2707 auto try_push_back = [&str, &is, &ret_bit](char_t ch)
2709 typename traits_t::size_type nCurrentSize = str.size();
2710 if (str._resize(nCurrentSize + 1))
2712 str[nCurrentSize] = ch;
2718 ret_bit |= qx::details::istream<traits_t>::failbit;
2729 if (!traits_t::is_space(ch))
2739 if (!traits_t::is_space(ch))
2741 if (!try_push_back(ch))
2751 is.setstate(ret_bit);
void push_back(value_type chSymbol) noexcept
Insert char in the end of the string.
void erase(iterator itFirst, iterator itLast) noexcept
Erase substring.
size_type find(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) const noexcept
Find substring.
bool remove_prefix(value_type chSymbol) noexcept
Remove string prefix if matches.
size_type remove_all(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) noexcept
Remove all occurrences of a substring in a string.
std::optional< to_t > to(const_pointer pszFormat=nullptr) const noexcept
Convert string to specified type.
int compare(value_type chSymbol) const noexcept
Performs a binary comparison of the characters.
size_type find_last_of(value_type chSymbol, size_type nEnd=0) const noexcept
Find last position of character.
void push_front(value_type chSymbol) noexcept
Insert char in the beginning of the string.
size_type capacity() const noexcept
Get allocated memory size (including null terminator)
value_type pop_back() noexcept
Erase last char and return it.
size_type copy(pointer pDest, size_type nCount, size_type nPos=0) const noexcept
Copies a substring [nPos, nPos + nCount) to character string pointed to by pDest.
views split(const value_type chSeparator) const noexcept
Split string by separator.
size_type rfind(value_type chSymbol, size_type nBegin=npos, size_type nEnd=0) const noexcept
Find substring (reverse direction)
size_type length() const noexcept
Get string length.
void free() noexcept
Clear string and free allocated memory.
void from(const from_t &data)
Construct string from custom type.
size_type trim_right() noexcept
Trim the string to the right (whitespace characters)
requires format_acceptable_args_c< char_t, args_t... > void vformat(string_view svFormat, args_t &&... args)
Clear the string and format it with the format string and the args.
void assign(size_type nSymbols, value_type chSymbol) noexcept
Assign by filling.
size_type replace_all(const find_string_t &sFind, const replace_string_t &sReplace, size_type nBegin=0, size_type nEnd=npos) noexcept
Replace all occurrences of sFind with sReplace.
size_type insert(const_iterator itPos, fwd_it_t itWhatBegin, fwd_it_t itWhatEnd) noexcept
Insert substring.
bool ends_with(value_type chSymbol) const noexcept
Check if current string ends with char.
void swap(basic_string &sOther) noexcept
Swap this str and other.
value_type pop_front() noexcept
Erase first char and return it.
void append(value_type chSymbol) noexcept
Append char.
bool contains(value_type chSymbol) const noexcept
Check if string contains char.
size_type trim() noexcept
Trim the string to the both sides (whitespace characters)
void to_upper() noexcept
Convert string to uppercase.
void shrink_to_fit() noexcept
Fit allocated size to string's actual size.
static basic_string static_from(const from_t &data)
Construct string from custom type and get it.
size_type find_last_not_of(value_type chSymbol, size_type nEnd=0) const noexcept
Finds the last character not equal to chSymbol.
size_type trim_left() noexcept
Trim the string to the left (whitespace characters)
size_type reserve(size_type nCapacity) noexcept
Reserve memory for the string.
requires format_acceptable_args_c< char_t, args_t... > void append_vformat(string_view svFormat, args_t &&... args)
Append the formatted string to the current one.
string_view substr(size_type nPos, size_type nSymbols=npos) const noexcept
Get substring.
requires format_acceptable_args_c< char_t, args_t... > void append_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args)
Append the formatted string to the current one.
void to_lower() noexcept
Convert string to lowercase.
requires format_acceptable_args_c< char_t, args_t... > void format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args)
Clear the string and format it with the format string and the args.
size_type insert(size_type nPos, value_type chSymbol) noexcept
Insert substring.
bool remove_suffix(value_type chSymbol) noexcept
Remove string suffix if matches.
const_pointer c_str() const noexcept
Get pointer to string zero terminated.
requires static format_acceptable_args_c< char_t, args_t... > basic_string static_vformat(string_view svFormat, args_t &&... args)
Create a string by formatting it with the format string and the args.
size_type remove(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) noexcept
Remove the first occurrence of a substring in a string.
static constexpr size_type max_size() noexcept
Get the theoretical maximum of string size.
bool starts_with(value_type chSymbol) const noexcept
Check if current string starts with char.
value_type front() const noexcept
Get first char of the string.
value_type back() const noexcept
Get last char of the string.
requires static format_acceptable_args_c< char_t, args_t... > basic_string static_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args)
Create a string by formatting it with the format string and the args.
size_type replace(size_type nBegin, size_type nSize, const_pointer pszReplace, size_t nReplaceSize) noexcept
Replace a substring with a given string.
size_type find_first_of(value_type chSymbol, size_type nBegin=0) const noexcept
Find first position of character.
size_type find_first_not_of(value_type chSymbol, size_type nBegin=0) const noexcept
Finds the first character not equal to chSymbol.
Const random access iterator type.
Non-const random access iterator type.
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
#define QX_STATIC_ASSERT_NO_INSTANTIATION(Message)
This static assert will fail if block it placed in must not be instantiated.
basic_string< char_t, traits_t > convert_to_string(const T &value)
Converts any type that has a std::formatter overload to qx::basic_string.
#define QX_CHAR_PREFIX(value_t, ch)
Chose witch of prefixes add to char : L or none.
constexpr int iter_strcmp(fwd_it_1_t itBegin1, fwd_it_1_t itEnd1, fwd_it_2_t itBegin2, fwd_it_2_t itEnd2) noexcept
Compares string 1 with string 2.
#define QX_STR_PREFIX(value_t, str)
Chose witch of prefixes add to string : L or none.