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>
97 for (fwd_it_t it = itFirst; it != itLast; ++it)
107 template<
class char_t,
class traits_t>
108 template<range_of_t_c<
char_t>
string_t>
111 if constexpr (std::ranges::contiguous_range<string_t> && std::ranges::sized_range<string_t>)
113 assign(sAnother.data(), sAnother.size());
117 assign(sAnother.begin(), sAnother.end());
121 template<
class char_t,
class traits_t>
122 template<
class... args_t>
123 requires format_acceptable_args_c<char_t, args_t...>
125 const format_string_type<std::type_identity_t<args_t>...> sFormat,
126 args_t&&... args) noexcept
128 vformat(string_view(sFormat.get().data(), sFormat.get().size()), std::forward<args_t>(args)...);
131 template<
class char_t,
class traits_t>
132 template<
class... args_t>
133 requires format_acceptable_args_c<char_t, args_t...>
135 const format_string_type<std::type_identity_t<args_t>...> sFormat,
136 args_t&&... args) noexcept
143 template<
class char_t,
class traits_t>
144 template<
class... args_t>
145 requires format_acceptable_args_c<char_t, args_t...>
147 const format_string_type<std::type_identity_t<args_t>...> sFormat,
148 args_t&&... args) noexcept
150 append_vformat(string_view(sFormat.get().data(), sFormat.get().size()), std::forward<args_t>(args)...);
153 template<
class char_t,
class traits_t>
154 template<
class... args_t>
155 requires format_acceptable_args_c<char_t, args_t...>
159 append_vformat(svFormat, std::forward<args_t>(args)...);
162 template<
class char_t,
class traits_t>
163 template<
class... args_t>
164 requires format_acceptable_args_c<char_t, args_t...>
166 string_view svFormat,
174 template<
class char_t,
class traits_t>
175 template<
class... args_t>
176 requires format_acceptable_args_c<char_t, args_t...>
179 #if QX_CONF_FMT_LIB == QX_FMT_LIB_FMT
181 fmt::basic_memory_buffer<value_type, traits_type::nMemoryBufferSize> buffer;
182 fmt::vformat_to(std::back_inserter(buffer), svFormat, traits_type::make_format_args(args...));
183 append(buffer.data(),
static_cast<size_type
>(buffer.size()));
185 #elif QX_CONF_FMT_LIB == QX_FMT_LIB_STD
187 std::vformat_to(std::back_inserter(*
this), svFormat, traits_type::make_format_args(args...));
190 #error No fmt lib selected
194 template<
class char_t,
class traits_t>
197 std::swap(m_Data, sOther.m_Data);
200 template<
class char_t,
class traits_t>
202 size_type nCapacity) noexcept
204 m_Data.reserve(nCapacity *
sizeof(value_type));
208 template<
class char_t,
class traits_t>
211 m_Data.shrink_to_fit();
214 template<
class char_t,
class traits_t>
221 template<
class char_t,
class traits_t>
224 size_type nSymbols)
const noexcept
226 return string_view(data() + nPos, nSymbols != npos ? nSymbols : size() - nPos);
229 template<
class char_t,
class traits_t>
232 for (value_type& ch : *
this)
233 ch = traits_t::to_lower(ch);
236 template<
class char_t,
class traits_t>
239 for (value_type& ch : *
this)
240 ch = traits_t::to_upper(ch);
243 template<
class char_t,
class traits_t>
249 template<
class char_t,
class traits_t>
252 return at(size() - 1);
255 template<
class char_t,
class traits_t>
261 template<
class char_t,
class traits_t>
267 template<
class char_t,
class traits_t>
270 return m_Data.capacity() /
sizeof(value_type) - 1;
273 template<
class char_t,
class traits_t>
276 return std::numeric_limits<size_type>::max() - 1
280 template<
class char_t,
class traits_t>
284 std::optional<to_t> optResult = std::nullopt;
287 std::is_trivial_v<to_t> && std::is_standard_layout_v<to_t> || std::is_pointer_v<to_t>
288 || std::is_same_v<to_t, std::nullptr_t>)
290 if constexpr (std::is_same_v<to_t, std::nullptr_t>)
292 if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"nullptr")) == 0)
297 else if constexpr (std::is_same_v<to_t, bool>)
299 if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"true")) == 0)
303 else if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"false")) == 0)
308 else if (
const auto pszSelectedFormat = pszFormat ? pszFormat : get_format_specifier<value_type, to_t>())
310 constexpr string_view svNSpecifier(
QX_STR_PREFIX(value_type,
"%n"));
311 constexpr
size_t nBufferSize = 256;
313 const size_t nFormatSpecifierLength = traits_t::length(pszSelectedFormat);
314 if (nFormatSpecifierLength <= nBufferSize - svNSpecifier.size() - 1)
316 value_type formatBuffer[nBufferSize];
317 std::memcpy(formatBuffer, pszSelectedFormat, nFormatSpecifierLength *
sizeof(value_type));
319 formatBuffer + nFormatSpecifierLength,
321 svNSpecifier.size() *
sizeof(value_type));
322 formatBuffer[nFormatSpecifierLength + svNSpecifier.size()] =
QX_CHAR_PREFIX(value_type,
'\0');
326 const int nConvertedArgs = traits_t::sscanf(data(), formatBuffer, &result, &nSymbolsRead);
328 if (
static_cast<size_type
>(nSymbolsRead) == size() && nConvertedArgs == 1)
336 sstream_type ss(data());
344 template<
class char_t,
class traits_t>
348 size_type nPos)
const noexcept
350 size_type nCharsToCopy = 0;
352 if (pDest && nCount > 0 && nPos < size())
354 nCharsToCopy = std::min(nPos + nCount, size()) - nPos;
355 std::memcpy(pDest, data() + nPos, nCharsToCopy *
sizeof(value_type));
361 template<
class char_t,
class traits_t>
362 template<
class from_t>
366 std::is_trivial_v<from_t> && std::is_standard_layout_v<from_t> || std::is_pointer_v<from_t>
367 || std::is_same_v<from_t, std::nullptr_t>)
369 if constexpr (std::is_same_v<from_t, std::nullptr_t>)
371 assign(
QX_STR_PREFIX(
typename traits_t::value_type,
"nullptr"));
373 else if constexpr (std::is_same_v<from_t, bool>)
392 template<
class char_t,
class traits_t>
393 template<
class from_t>
398 return std::move(sTemp);
401 template<
class char_t,
class traits_t>
407 template<
class char_t,
class traits_t>
412 const size_type nSize = size();
413 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszStr) : nSymbols;
415 if (_resize(nSize + nSizeSource))
416 std::memcpy(data() + nSize, pszStr, nSizeSource *
sizeof(value_type));
420 template<
class char_t,
class traits_t>
426 template<
class char_t,
class traits_t>
427 template<
class fwd_it_t>
430 for (
auto it = itBegin; it != itEnd; ++it)
434 template<
class char_t,
class traits_t>
435 template<range_of_t_c<
char_t>
string_t>
438 if constexpr (std::ranges::contiguous_range<string_t> && std::ranges::sized_range<string_t>)
440 append(sStr.data(), sStr.size());
444 append(sStr.begin(), sStr.end());
448 template<
class char_t,
class traits_t>
451 value_type chSymbol) noexcept
453 return insert(nPos, &chSymbol, 1);
456 template<
class char_t,
class traits_t>
459 const_pointer pszWhat,
460 size_type nSymbols) noexcept
464 const size_type nSize = size();
465 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszWhat) : nSymbols;
467 if (nSizeSource > 0 && _resize(nSize + nSizeSource))
469 std::memmove(data() + nPos + nSizeSource, data() + nPos, (nSize - nPos) *
sizeof(value_type));
470 std::memcpy(data() + nPos, pszWhat, nSizeSource *
sizeof(value_type));
471 return nPos + nSizeSource;
478 template<
class char_t,
class traits_t>
479 template<
class fwd_it_t>
482 fwd_it_t itWhatBegin,
483 fwd_it_t itWhatEnd) noexcept
485 if constexpr (is_random_access_iterator<fwd_it_t>)
487 return insert(nPos, itWhatBegin.operator->(),
static_cast<size_type
>(itWhatEnd - itWhatBegin));
491 size_type nWhatSize = 0;
492 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
495 size_type nStartSymbols = size();
496 if (nWhatSize > 0 && _resize(nStartSymbols + nWhatSize))
498 std::memmove(data() + nPos + nWhatSize, data() + nPos, (nStartSymbols - nPos) *
sizeof(value_type));
500 size_type nWhatPos = 0;
501 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
503 at(nPos + nWhatPos) = *it;
507 return nPos + nWhatSize;
516 template<
class char_t,
class traits_t>
521 return insert(nPos, sWhat.data(), sWhat.size());
524 template<
class char_t,
class traits_t>
525 template<range_of_t_c<
char_t>
string_t>
528 string_t sWhat) noexcept
530 return insert(
static_cast<size_type
>(nPos), sWhat.begin(), sWhat.end());
533 template<
class char_t,
class traits_t>
536 value_type chSymbol) noexcept
538 return insert(
static_cast<size_type
>(itPos - cbegin()), chSymbol);
541 template<
class char_t,
class traits_t>
544 const_pointer pszWhat,
545 size_type nSymbols) noexcept
547 return insert(
static_cast<size_type
>(itPos - cbegin()), pszWhat, nSymbols);
550 template<
class char_t,
class traits_t>
555 return insert(
static_cast<size_type
>(itPos - cbegin()), sWhat.data(), sWhat.size());
558 template<
class char_t,
class traits_t>
559 template<
class fwd_it_t>
562 fwd_it_t itWhatBegin,
563 fwd_it_t itWhatEnd) noexcept
565 return insert(
static_cast<size_type
>(itPos - begin()), itWhatBegin, itWhatEnd);
568 template<
class char_t,
class traits_t>
569 template<range_of_t_c<
char_t>
string_t>
572 string_t sWhat) noexcept
574 return insert(
static_cast<size_type
>(itPos - begin()), sWhat.begin(), sWhat.end());
577 template<
class char_t,
class traits_t>
580 const size_t nStartSize = size();
581 _resize(nStartSize + 1);
582 (*this)[nStartSize] = chSymbol;
585 template<
class char_t,
class traits_t>
588 insert(0, &chSymbol, 1);
591 template<
class char_t,
class traits_t>
594 if (
const typename iterator::difference_type nCharsToErase = itLast - itFirst; nCharsToErase > 0)
596 const size_type nStartSize = size();
597 const size_type nSymbolsToCopy = itLast != end() ? traits_t::length(itLast.operator->()) : 0;
599 if (nSymbolsToCopy > 0)
601 std::memmove(itFirst.operator->(), itLast.operator->(), nSymbolsToCopy *
sizeof(value_type));
604 if (
static_cast<typename iterator::difference_type
>(nStartSize) >= nCharsToErase)
606 _resize(nStartSize - nCharsToErase);
611 template<
class char_t,
class traits_t>
614 erase(itPos, itPos + 1);
617 template<
class char_t,
class traits_t>
623 template<
class char_t,
class traits_t>
629 template<
class char_t,
class traits_t>
632 value_type chRet = back();
637 template<
class char_t,
class traits_t>
640 value_type chRet = front();
645 template<
class char_t,
class traits_t>
651 return traits_t::is_space(ch);
655 template<
class char_t,
class traits_t>
657 value_type chSymbol) noexcept
660 [chSymbol](value_type ch)
662 return ch == chSymbol;
666 template<
class char_t,
class traits_t>
668 const_pointer pszStr) noexcept
673 [pszStr](value_type ch)
675 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
690 template<
class char_t,
class traits_t>
692 const_pointer pszStr,
693 size_type nStrSize) noexcept
698 [pszStr, nStrSize](value_type ch)
700 for (size_type j = 0; j < nStrSize; ++j)
713 template<
class char_t,
class traits_t>
717 return trim_left(sStr.data(), sStr.size());
720 template<
class char_t,
class traits_t>
721 template<
class fwd_it_t>
724 fwd_it_t itEnd) noexcept
727 [itBegin, itEnd](
auto ch)
729 for (
auto it = itBegin; it != itEnd; ++it)
737 template<
class char_t,
class traits_t>
738 template<range_of_t_c<
char_t>
string_t>
740 const string_t& sStr) noexcept
742 return trim_left(sStr.begin(), sStr.end());
745 template<
class char_t,
class traits_t>
751 return traits_t::is_space(ch);
755 template<
class char_t,
class traits_t>
757 value_type chSymbol) noexcept
760 [chSymbol](value_type ch)
762 return ch == chSymbol;
766 template<
class char_t,
class traits_t>
768 const_pointer pszStr) noexcept
773 [pszStr](value_type ch)
775 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
790 template<
class char_t,
class traits_t>
792 const_pointer pszStr,
793 size_type nStrSize) noexcept
798 [pszStr, nStrSize](value_type ch)
800 for (size_type j = 0; j < nStrSize; ++j)
813 template<
class char_t,
class traits_t>
817 return trim_right(sStr.data(), sStr.size());
820 template<
class char_t,
class traits_t>
821 template<
class fwd_it_t>
824 fwd_it_t itEnd) noexcept
827 [itBegin, itEnd](
auto ch)
829 for (
auto it = itBegin; it != itEnd; ++it)
837 template<
class char_t,
class traits_t>
838 template<range_of_t_c<
char_t>
string_t>
840 const string_t& sStr) noexcept
842 return trim_right(sStr.begin(), sStr.end());
845 template<
class char_t,
class traits_t>
851 return traits_t::is_space(ch);
855 template<
class char_t,
class traits_t>
857 value_type chSymbol) noexcept
860 [chSymbol](value_type ch)
862 return ch == chSymbol;
866 template<
class char_t,
class traits_t>
868 const_pointer pszStr) noexcept
873 [pszStr](value_type ch)
875 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
890 template<
class char_t,
class traits_t>
892 const_pointer pszStr,
893 size_type nStrSize) noexcept
898 [pszStr, nStrSize](value_type ch)
900 for (size_type j = 0; j < nStrSize; ++j)
913 template<
class char_t,
class traits_t>
917 return trim(sStr.data(), sStr.size());
920 template<
class char_t,
class traits_t>
921 template<
class fwd_it_t>
924 fwd_it_t itEnd) noexcept
927 [itBegin, itEnd](
auto ch)
929 for (
auto it = itBegin; it != itEnd; ++it)
937 template<
class char_t,
class traits_t>
938 template<range_of_t_c<
char_t>
string_t>
940 const string_t& sStr) noexcept
942 return trim(sStr.begin(), sStr.end());
945 template<
class char_t,
class traits_t>
949 size_type nEnd) noexcept
951 size_type nPos = find(chSymbol, nBegin, nEnd);
959 template<
class char_t,
class traits_t>
961 const_pointer pszStr,
964 size_type nStrSize) noexcept
968 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
969 const size_type nPos = find(pszStr, nBegin, nLocalStrSize, nEnd);
972 erase(nPos, nLocalStrSize);
982 template<
class char_t,
class traits_t>
986 size_type nEnd) noexcept
988 const size_type nPos = find(sStr, nBegin, nEnd);
991 erase(nPos, sStr.size());
996 template<
class char_t,
class traits_t>
997 template<
class fwd_it_t>
1002 size_type nEnd) noexcept
1004 const size_type nPos = find(itBegin, itEnd, nBegin, nEnd);
1007 erase(nPos,
static_cast<size_type
>(std::distance(itBegin, itEnd)));
1012 template<
class char_t,
class traits_t>
1013 template<range_of_t_c<
char_t>
string_t>
1015 const string_t& sStr,
1017 size_type nEnd) noexcept
1019 return remove(sStr.begin(), sStr.end(), nBegin, nEnd);
1022 template<
class char_t,
class traits_t>
1025 return remove(chSymbol,
static_cast<size_type
>(0),
static_cast<size_type
>(1)) != npos;
1028 template<
class char_t,
class traits_t>
1031 return remove(pszStr,
static_cast<size_type
>(0), nStrSize, nStrSize) != npos;
1034 template<
class char_t,
class traits_t>
1037 return remove(sStr,
static_cast<size_type
>(0), sStr.size()) != npos;
1040 template<
class char_t,
class traits_t>
1041 template<
class fwd_it_t>
1044 return remove(itBegin, itEnd,
static_cast<size_type
>(0),
static_cast<size_type
>(std::distance(itBegin, itEnd)))
1048 template<
class char_t,
class traits_t>
1049 template<range_of_t_c<
char_t>
string_t>
1052 return remove_prefix(sStr.begin(), sStr.end());
1055 template<
class char_t,
class traits_t>
1058 const size_type nSize = size();
1059 return remove(chSymbol, nSize - 1, nSize) != npos;
1062 template<
class char_t,
class traits_t>
1067 const size_type nSize = size();
1068 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
1070 return remove(pszStr, nSize - nLocalStrSize, nSize, nLocalStrSize) != npos;
1078 template<
class char_t,
class traits_t>
1081 return remove_suffix(sStr.data(), sStr.size());
1084 template<
class char_t,
class traits_t>
1085 template<
class fwd_it_t>
1088 const size_type nSize = size();
1089 return remove(itBegin, itEnd, nSize -
static_cast<size_type
>(std::distance(itBegin, itEnd)), nSize) != npos;
1092 template<
class char_t,
class traits_t>
1093 template<range_of_t_c<
char_t>
string_t>
1096 return remove_suffix(sStr.begin(), sStr.end());
1099 template<
class char_t,
class traits_t>
1101 value_type chSymbol,
1103 size_type nEnd) noexcept
1105 size_type nOccurrences = 0;
1106 size_type nLastOccurrencePos = nBegin;
1111 nLastOccurrencePos = remove(chSymbol, nLastOccurrencePos, nEnd);
1112 }
while (nLastOccurrencePos != npos);
1114 return nOccurrences - 1;
1117 template<
class char_t,
class traits_t>
1119 const_pointer pszStr,
1122 size_type nStrSize) noexcept
1126 size_type nOccurrences = 0;
1127 size_type nLastOccurrencePos = nBegin;
1132 nLastOccurrencePos = remove(pszStr, nLastOccurrencePos, nEnd, nStrSize);
1133 }
while (nLastOccurrencePos != npos);
1135 return nOccurrences - 1;
1143 template<
class char_t,
class traits_t>
1147 size_type nEnd) noexcept
1149 return remove_all(sStr.data(), nBegin, nEnd, sStr.size());
1152 template<
class char_t,
class traits_t>
1153 template<
class fwd_it_t>
1158 size_type nEnd) noexcept
1160 size_type nOccurrences = 0;
1161 size_type nLastOccurrencePos = nBegin;
1166 nLastOccurrencePos = remove(itFirst, itLast, nLastOccurrencePos, nEnd);
1167 }
while (nLastOccurrencePos != npos);
1169 return nOccurrences - 1;
1172 template<
class char_t,
class traits_t>
1173 template<range_of_t_c<
char_t>
string_t>
1175 const string_t& sStr,
1177 size_type nEnd) noexcept
1179 return remove_all(sStr.begin(), sStr.end(), nBegin, nEnd);
1182 template<
class char_t,
class traits_t>
1186 const_pointer pszReplace,
1187 size_t nReplaceSize) noexcept
1189 const size_type nStartSize = size();
1190 const size_type nNewSize = nStartSize - nSize + nReplaceSize;
1195 data() + nBegin + nReplaceSize,
1196 data() + nBegin + nSize,
1197 (nStartSize - nBegin - nSize) *
sizeof(value_type));
1199 std::memcpy(data() + nBegin, pszReplace, nReplaceSize *
sizeof(value_type));
1203 return nBegin + nReplaceSize;
1206 template<
class char_t,
class traits_t>
1207 template<
class replace_
string_t>
1211 const replace_string_t& sReplace) noexcept
1213 return replace(nBegin, nSize, _get_string_view_like_data(sReplace), _get_string_view_like_size(sReplace));
1216 template<
class char_t,
class traits_t>
1217 template<
class find_
string_t,
class replace_
string_t>
1219 const find_string_t& sFind,
1220 const replace_string_t& sReplace,
1222 size_type nEnd) noexcept
1224 if (size_type nPos = find(sFind, nBegin, nEnd); nPos != npos)
1228 _get_string_view_like_size(sFind),
1229 _get_string_view_like_data(sReplace),
1230 _get_string_view_like_size(sReplace));
1238 template<
class char_t,
class traits_t>
1239 template<
class find_
string_t,
class replace_
string_t>
1241 const find_string_t& sFind,
1242 const replace_string_t& sReplace,
1244 size_type nEnd) noexcept
1246 size_type nOccurrences = 0;
1247 size_type nPos = nBegin;
1251 nPos = replace(sFind, sReplace, nPos, nEnd);
1254 }
while (nPos != npos);
1256 return nOccurrences;
1259 template<
class char_t,
class traits_t>
1262 return compare(&chSymbol, 1);
1265 template<
class char_t,
class traits_t>
1268 return traits_t::compare(data(), pszStr);
1271 template<
class char_t,
class traits_t>
1274 return traits_t::compare_n(data(), pStr, nSymbols);
1277 template<
class char_t,
class traits_t>
1280 return compare(sStr.data(), sStr.size());
1283 template<
class char_t,
class traits_t>
1284 template<
class fwd_it_t>
1287 return iter_strcmp(cbegin(), cend(), itBegin, itEnd);
1290 template<
class char_t,
class traits_t>
1291 template<range_of_t_c<
char_t>
string_t>
1294 return compare(sStr.begin(), sStr.end());
1297 template<
class char_t,
class traits_t>
1299 value_type chSymbol,
1301 size_type nEnd)
const noexcept
1306 [chSymbol](const_pointer pCurrentChar)
1308 return *pCurrentChar == chSymbol;
1312 template<
class char_t,
class traits_t>
1314 const_pointer pszWhat,
1316 size_type nWhatSize,
1317 size_type nEnd)
const noexcept
1321 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1326 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1328 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1337 template<
class char_t,
class traits_t>
1341 size_type nEnd)
const noexcept
1343 return find(sWhat.data(), nBegin, sWhat.size(), nEnd);
1346 template<
class char_t,
class traits_t>
1347 template<
class fwd_it_t>
1349 fwd_it_t itWhatBegin,
1352 size_type nEnd)
const noexcept
1354 const size_t nWhatSize = itWhatEnd - itWhatBegin;
1358 [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
1360 const size_t nStart =
static_cast<size_type
>(pCurrentChar - data());
1369 template<
class char_t,
class traits_t>
1370 template<range_of_t_c<
char_t>
string_t>
1374 size_type nEnd)
const noexcept
1376 return find(sWhat.begin(), sWhat.end(), nBegin, nEnd);
1379 template<
class char_t,
class traits_t>
1381 value_type chSymbol,
1383 size_type nEnd)
const noexcept
1388 [chSymbol](const_pointer pCurrentChar)
1390 return *pCurrentChar == chSymbol;
1394 template<
class char_t,
class traits_t>
1396 const_pointer pszWhat,
1398 size_type nWhatSize,
1399 size_type nEnd)
const noexcept
1403 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1408 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1410 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1419 template<
class char_t,
class traits_t>
1423 size_type nEnd)
const noexcept
1425 return rfind(sWhat.data(), nBegin, sWhat.size(), nEnd);
1428 template<
class char_t,
class traits_t>
1429 template<
class fwd_it_t>
1431 fwd_it_t itWhatBegin,
1434 size_type nEnd)
const noexcept
1436 const size_t nWhatSize = itWhatEnd - itWhatBegin;
1440 [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
1442 const size_t nStart =
static_cast<size_type
>(pCurrentChar - data());
1451 template<
class char_t,
class traits_t>
1452 template<range_of_t_c<
char_t>
string_t>
1456 size_type nEnd)
const noexcept
1458 return rfind(sWhat.begin(), sWhat.end(), nBegin, nEnd);
1461 template<
class char_t,
class traits_t>
1463 value_type chSymbol,
1464 size_type nBegin)
const noexcept
1466 return find(chSymbol, nBegin);
1469 template<
class char_t,
class traits_t>
1471 const_pointer pszWhat,
1473 size_type nWhatSize)
const noexcept
1477 return _find_first_of(
1479 pszWhat + nWhatSize,
1481 [](const_pointer pChar)
1492 template<
class char_t,
class traits_t>
1494 const_pointer pszWhat,
1495 size_type nBegin)
const noexcept
1499 return _find_first_of(
1501 static_cast<const_pointer
>(
nullptr),
1503 [](const_pointer pChar)
1505 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1514 template<
class char_t,
class traits_t>
1517 size_type nBegin)
const noexcept
1519 return find_first_of(sWhat.data(), nBegin, sWhat.size());
1522 template<
class char_t,
class traits_t>
1523 template<
class fwd_it_t>
1525 fwd_it_t itWhatBegin,
1527 size_type nBegin)
const noexcept
1529 return _find_first_of(
1539 template<
class char_t,
class traits_t>
1540 template<range_of_t_c<
char_t>
string_t>
1543 size_type nBegin)
const noexcept
1545 return find_first_of(sWhat.begin(), sWhat.end(), nBegin);
1548 template<
class char_t,
class traits_t>
1550 value_type chSymbol,
1551 size_type nEnd)
const noexcept
1553 return rfind(chSymbol, npos, nEnd);
1556 template<
class char_t,
class traits_t>
1558 const_pointer pszWhat,
1560 size_type nWhatSize)
const noexcept
1564 return _find_last_of(
1566 pszWhat + nWhatSize,
1568 [](const_pointer pChar)
1579 template<
class char_t,
class traits_t>
1581 const_pointer pszWhat,
1582 size_type nEnd)
const noexcept
1586 return _find_last_of(
1588 static_cast<const_pointer
>(
nullptr),
1590 [](const_pointer pChar)
1592 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1601 template<
class char_t,
class traits_t>
1604 size_type nEnd)
const noexcept
1606 return find_last_of(sWhat.data(), nEnd, sWhat.size());
1609 template<
class char_t,
class traits_t>
1610 template<
class fwd_it_t>
1612 fwd_it_t itWhatBegin,
1614 size_type nEnd)
const noexcept
1616 return _find_last_of(
1626 template<
class char_t,
class traits_t>
1627 template<range_of_t_c<
char_t>
string_t>
1630 size_type nEnd)
const noexcept
1632 return find_last_of(sWhat.begin(), sWhat.end(), nEnd);
1635 template<
class char_t,
class traits_t>
1637 value_type chSymbol,
1638 size_type nBegin)
const noexcept
1643 [chSymbol](const_pointer pCurrentChar)
1645 return *pCurrentChar != chSymbol;
1649 template<
class char_t,
class traits_t>
1651 const_pointer pszWhat,
1653 size_type nWhatSize)
const noexcept
1657 return _find_first_not_of(
1659 pszWhat + nWhatSize,
1661 [](const_pointer pChar)
1672 template<
class char_t,
class traits_t>
1674 const_pointer pszWhat,
1675 size_type nBegin)
const noexcept
1679 return _find_first_not_of(
1681 static_cast<const_pointer
>(
nullptr),
1683 [](const_pointer pChar)
1685 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1694 template<
class char_t,
class traits_t>
1697 size_type nBegin)
const noexcept
1699 return find_first_not_of(sWhat.data(), nBegin, sWhat.size());
1702 template<
class char_t,
class traits_t>
1703 template<
class fwd_it_t>
1705 fwd_it_t itWhatBegin,
1707 size_type nBegin)
const noexcept
1709 return _find_first_not_of(
1719 template<
class char_t,
class traits_t>
1720 template<range_of_t_c<
char_t>
string_t>
1723 size_type nBegin)
const noexcept
1725 return find_first_not_of(sWhat.begin(), sWhat.end(), nBegin);
1728 template<
class char_t,
class traits_t>
1730 value_type chSymbol,
1731 size_type nEnd)
const noexcept
1736 [chSymbol](const_pointer pCurrentChar)
1738 return *pCurrentChar != chSymbol;
1742 template<
class char_t,
class traits_t>
1744 const_pointer pszWhat,
1746 size_type nWhatSize)
const noexcept
1750 return _find_last_not_of(
1752 pszWhat + nWhatSize,
1754 [](const_pointer pChar)
1765 template<
class char_t,
class traits_t>
1767 const_pointer pszWhat,
1768 size_type nEnd)
const noexcept
1772 return _find_last_not_of(
1774 static_cast<const_pointer
>(
nullptr),
1776 [](const_pointer pChar)
1778 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1787 template<
class char_t,
class traits_t>
1790 size_type nEnd)
const noexcept
1792 return find_last_not_of(sWhat.data(), nEnd, sWhat.size());
1795 template<
class char_t,
class traits_t>
1796 template<
class fwd_it_t>
1798 fwd_it_t itWhatBegin,
1800 size_type nEnd)
const noexcept
1802 return _find_last_not_of(
1812 template<
class char_t,
class traits_t>
1813 template<range_of_t_c<
char_t>
string_t>
1816 size_type nEnd)
const noexcept
1818 return find_last_not_of(sWhat.begin(), sWhat.end(), nEnd);
1821 template<
class char_t,
class traits_t>
1823 const value_type chSeparator)
const noexcept
1827 size_type nStart = 0;
1829 while ((nEnd = find(chSeparator, nStart)) != npos)
1831 tokens.emplace_back(substr(nStart, nEnd - nStart));
1833 while (traits_t::compare_n(data() + nStart, &chSeparator, 1) == 0)
1837 if (nStart != size())
1838 tokens.emplace_back(substr(nStart));
1840 return std::move(tokens);
1843 template<
class char_t,
class traits_t>
1845 const_pointer pszSeparator,
1846 size_type nSepLen)
const noexcept
1853 if (nSepLen == npos)
1854 nSepLen = traits_t::length(pszSeparator);
1856 size_type nStart = 0;
1858 while ((nEnd = find(pszSeparator, nStart, nSepLen, npos)) != npos)
1860 tokens.emplace_back(substr(nStart, nEnd - nStart));
1862 while (traits_t::compare_n(data() + nStart, pszSeparator, nSepLen) == 0)
1866 if (nStart != size())
1867 tokens.emplace_back(substr(nStart));
1872 template<
class char_t,
class traits_t>
1876 return split(sSeparator.data(), sSeparator.size());
1879 template<
class char_t,
class traits_t>
1880 template<
class fwd_it_t>
1882 fwd_it_t itSepFirst,
1883 fwd_it_t itSepLast)
const noexcept
1887 const size_type nSepLen =
static_cast<size_type
>(std::distance(itSepFirst, itSepLast));
1889 size_type nStart = 0;
1891 while ((nEnd = find(itSepFirst, itSepLast, nStart)) != npos)
1893 tokens.emplace_back(substr(nStart, nEnd - nStart));
1894 nStart = nEnd + nSepLen;
1896 tokens.emplace_back(substr(nStart));
1901 template<
class char_t,
class traits_t>
1902 template<range_of_t_c<
char_t>
string_t>
1904 const string_t& sSeparator)
const noexcept
1906 return split(sSeparator.begin(), sSeparator.end());
1909 template<
class char_t,
class traits_t>
1913 return at(0) == chSymbol;
1918 template<
class char_t,
class traits_t>
1923 if (size_type nThisSize = size(); nThisSize > 0)
1925 if (nStrSize == npos)
1926 nStrSize = traits_t::length(pszStr);
1928 if (nStrSize <= nThisSize)
1929 return traits_t::compare_n(data(), pszStr, nStrSize) == 0;
1936 template<
class char_t,
class traits_t>
1939 return starts_with(sStr.data(), sStr.size());
1942 template<
class char_t,
class traits_t>
1943 template<
class fwd_it_t>
1946 auto nStrSize = std::distance(itBegin, itEnd);
1947 return iter_strcmp(cbegin(), cbegin() +
static_cast<size_type
>(nStrSize), itBegin, itEnd) == 0;
1950 template<
class char_t,
class traits_t>
1951 template<range_of_t_c<
char_t>
string_t>
1954 return starts_with(sStr.begin(), sStr.end());
1957 template<
class char_t,
class traits_t>
1960 const size_type nSize = size();
1962 return at(nSize - 1) == chSymbol;
1967 template<
class char_t,
class traits_t>
1973 if (nStrSize == npos)
1974 nStrSize = traits_t::length(pszStr);
1976 return ends_with(pszStr, pszStr + nStrSize);
1979 template<
class char_t,
class traits_t>
1982 return ends_with(sStr.data(), sStr.size());
1985 template<
class char_t,
class traits_t>
1986 template<
class fwd_it_t>
1989 const size_t nOtherSize =
static_cast<size_type
>(std::distance(itBegin, itEnd));
1990 if (nOtherSize > size())
1993 return iter_strcmp(cend() - nOtherSize, cend(), itBegin, itEnd) == 0;
1996 template<
class char_t,
class traits_t>
1997 template<range_of_t_c<
char_t>
string_t>
2000 return ends_with(sStr.begin(), sStr.end());
2003 template<
class char_t,
class traits_t>
2006 return find(chSymbol) != npos;
2009 template<
class char_t,
class traits_t>
2012 return find(pszStr, 0, nStrSize) != npos;
2015 template<
class char_t,
class traits_t>
2018 return find(sStr) != npos;
2021 template<
class char_t,
class traits_t>
2022 template<
class fwd_it_t>
2025 return find(itBegin, itEnd) != npos;
2028 template<
class char_t,
class traits_t>
2029 template<range_of_t_c<
char_t>
string_t>
2032 return find(sStr) != npos;
2035 template<
class char_t,
class traits_t>
2042 template<
class char_t,
class traits_t>
2043 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(basic_string&& sStr) noexcept
2045 assign(std::move(sStr));
2049 template<
class char_t,
class traits_t>
2050 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const basic_string& sStr) noexcept
2056 template<
class char_t,
class traits_t>
2057 template<range_of_t_c<
char_t>
string_t>
2058 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const string_t& sStr) noexcept
2064 template<
class char_t,
class traits_t>
2065 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(value_type chSymbol) noexcept
2071 template<
class char_t,
class traits_t>
2072 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(const_pointer pszSource) noexcept
2075 append(pszSource, traits_t::length(pszSource));
2080 template<
class char_t,
class traits_t>
2081 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const basic_string& sStr) noexcept
2083 append(sStr.data(), sStr.size());
2087 template<
class char_t,
class traits_t>
2088 template<range_of_t_c<
char_t>
string_t>
2089 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const string_t& sStr) noexcept
2091 append(sStr.begin(), sStr.end());
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 size() == 1 && at(0) == 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 compare(pszSource) == 0;
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 size() == sStr.size() && compare(sStr.data(), sStr.size()) == 0;
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 iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) == 0;
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 !operator==(chSymbol);
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 !operator==(pszSource);
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 !operator==(sStr);
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 !operator==(sStr);
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.begin(), sStr.end()) < 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.begin(), sStr.end()) <= 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.begin(), sStr.end()) > 0;
2220 template<
class char_t,
class traits_t>
2221 inline bool basic_string<char_t, traits_t>::operator>=(value_type chSymbol)
const noexcept
2223 return compare(&chSymbol, 1) >= 0;
2226 template<
class char_t,
class traits_t>
2227 inline bool basic_string<char_t, traits_t>::operator>=(const_pointer pszSource)
const noexcept
2229 return compare(pszSource) >= 0;
2232 template<
class char_t,
class traits_t>
2233 inline bool basic_string<char_t, traits_t>::operator>=(
const basic_string& sStr)
const noexcept
2235 return compare(sStr.data(), sStr.size()) >= 0;
2238 template<
class char_t,
class traits_t>
2239 template<range_of_t_c<
char_t>
string_t>
2240 inline bool basic_string<char_t, traits_t>::operator>=(
const string_t& sStr)
const noexcept
2242 return iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) >= 0;
2245 template<
class char_t,
class traits_t>
2246 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::operator[](
2247 size_type nSymbol) noexcept
2249 return data()[nSymbol];
2252 template<
class char_t,
class traits_t>
2253 inline typename basic_string<char_t, traits_t>::const_reference basic_string<char_t, traits_t>::operator[](
2254 size_type nSymbol)
const noexcept
2256 return data()[nSymbol];
2259 template<
class char_t,
class traits_t>
2260 inline basic_string<char_t, traits_t>::operator std::basic_string_view<
2261 typename basic_string<char_t, traits_t>::value_type>()
const noexcept
2263 return string_view(data(), size());
2266 template<
class char_t,
class traits_t>
2267 inline basic_string<char_t, traits_t>::operator bool() const noexcept
2272 template<
class char_t,
class traits_t>
2273 inline bool basic_string<char_t, traits_t>::_resize(size_type nSymbols) noexcept
2276 const bool bRet = m_Data.resize((nSymbols > 0 ? nSymbols + 1 : 0) *
sizeof(value_type));
2278 (*this)[nSymbols] =
QX_CHAR_PREFIX(
typename traits_t::value_type,
'\0');
2283 template<
class char_t,
class traits_t>
2284 template<
class searcher_t>
2285 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_left(
2286 const searcher_t& searcher) noexcept
2288 size_type nSymbols = 0;
2290 for (size_type i = 0; i < size(); ++i)
2292 if (searcher(at(i)))
2302 template<
class char_t,
class traits_t>
2303 template<
class searcher_t>
2304 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim_right(
2305 const searcher_t& searcher) noexcept
2307 size_type nSymbols = 0;
2308 size_type nSize = size();
2310 for (size_type i = nSize - 1; i != std::numeric_limits<size_type>::max(); --i)
2312 if (searcher(at(i)))
2318 erase(nSize - nSymbols, nSymbols);
2322 template<
class char_t,
class traits_t>
2323 template<
class searcher_t>
2324 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_trim(
2325 const searcher_t& searcher) noexcept
2327 const size_type nSize = size();
2328 size_type nStartPos = 0;
2329 size_type nEndPos = nSize;
2331 while (nStartPos < nSize && searcher(at(nStartPos)))
2334 while (nEndPos > nStartPos && searcher(at(nEndPos - 1)))
2337 size_type nNewSize = nEndPos - nStartPos;
2339 std::memmove(data(), data() + nStartPos, nNewSize *
sizeof(value_type));
2342 return nSize - nNewSize;
2345 template<
class char_t,
class traits_t>
2346 template<
class comparator_t>
2347 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find(
2350 const comparator_t& comparator)
const noexcept
2355 const_pointer pData = data();
2356 const_pointer pCurrentChar = pData + nBegin;
2357 const_pointer pEnd = pData + nEnd;
2359 while (pCurrentChar < pEnd)
2361 if (comparator(pCurrentChar))
2362 return static_cast<size_type
>(pCurrentChar - pData);
2370 template<
class char_t,
class traits_t>
2371 template<
class comparator_t>
2372 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_rfind(
2375 const comparator_t& comparator)
const noexcept
2378 nBegin = size() - 1;
2380 const_pointer pData = data();
2381 const_pointer pCurrentChar = pData + nBegin;
2382 const_pointer pEnd = pData + nEnd;
2384 while (pCurrentChar >= pEnd)
2386 if (comparator(pCurrentChar))
2387 return static_cast<size_type
>(pCurrentChar - pData);
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_first_of(
2401 const incrementer_t& incrementer)
const noexcept
2403 for (size_type i = nBegin; i < size(); ++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_last_of(
2417 const incrementer_t& incrementer)
const noexcept
2419 for (size_type i = size() - 1; i != nEnd - 1; --i)
2420 for (fwd_it_t it = itBegin; it != itEnd; it = incrementer(it))
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_first_not_of(
2433 const incrementer_t& incrementer)
const noexcept
2435 for (size_type i = nBegin; i < size(); ++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 incrementer_t,
class fwd_it_t>
2450 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_find_last_not_of(
2454 const incrementer_t& incrementer)
const noexcept
2456 for (size_type i = size() - 1; i != nEnd - 1; --i)
2458 bool bFoundOneOf =
false;
2459 for (fwd_it_t it = itBegin; !bFoundOneOf && it != itEnd; it = incrementer(it))
2460 bFoundOneOf |= *it == at(i);
2469 template<
class char_t,
class traits_t>
2470 template<
class string_view_like_t>
2471 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::_get_string_view_like_size(
2472 const string_view_like_t& sValue) noexcept
2474 if constexpr (std::is_same_v<string_view_like_t, value_type>)
2478 else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
2480 return traits_t::length(sValue);
2482 else if constexpr (range_of_t_c<string_view_like_t, char_t>)
2484 return sValue.size();
2493 template<
class char_t,
class traits_t>
2494 template<
class string_view_like_t>
2495 inline typename basic_string<char_t, traits_t>::const_pointer basic_string<char_t, traits_t>::
2496 _get_string_view_like_data(
const string_view_like_t& sValue) noexcept
2498 if constexpr (std::is_same_v<string_view_like_t, value_type>)
2502 else if constexpr (std::is_convertible_v<string_view_like_t, const_pointer>)
2506 else if constexpr (range_of_t_c<string_view_like_t, char_t>)
2508 return sValue.data();
2517 template<
class char_t,
class traits_t>
2518 basic_string<char_t, traits_t> operator+(
2519 const basic_string<char_t, traits_t>& lhs,
2520 const basic_string<char_t, traits_t>& rhs) noexcept
2522 basic_string<char_t, traits_t> str(lhs);
2527 template<
class char_t,
class traits_t>
2528 basic_string<char_t, traits_t> operator+(
2529 basic_string<char_t, traits_t>&& lhs,
2530 const basic_string<char_t, traits_t>& rhs) noexcept
2532 basic_string<char_t, traits_t> str(std::move(lhs));
2537 template<
class char_t,
class traits_t>
2538 basic_string<char_t, traits_t> operator+(
2539 const basic_string<char_t, traits_t>& lhs,
2540 typename traits_t::const_pointer rhs) noexcept
2542 basic_string<char_t, traits_t> str(lhs);
2547 template<
class char_t,
class traits_t>
2548 basic_string<char_t, traits_t> operator+(
2549 basic_string<char_t, traits_t>&& lhs,
2550 typename traits_t::const_pointer rhs) noexcept
2552 basic_string<char_t, traits_t> str(std::move(lhs));
2557 template<
class char_t,
class traits_t>
2558 basic_string<char_t, traits_t> operator+(
2559 typename traits_t::const_pointer lhs,
2560 const basic_string<char_t, traits_t>& rhs) noexcept
2562 basic_string<char_t, traits_t> str(lhs);
2567 template<
class char_t,
class traits_t>
2568 basic_string<char_t, traits_t> operator+(
2569 const basic_string<char_t, traits_t>& lhs,
2570 typename traits_t::value_type rhs) noexcept
2572 basic_string<char_t, traits_t> str(lhs);
2577 template<
class char_t,
class traits_t>
2578 basic_string<char_t, traits_t> operator+(
2579 basic_string<char_t, traits_t>&& lhs,
2580 typename traits_t::value_type rhs) noexcept
2582 basic_string<char_t, traits_t> str(std::move(lhs));
2587 template<
class char_t,
class traits_t>
2588 basic_string<char_t, traits_t> operator+(
2589 typename traits_t::value_type lhs,
2590 const basic_string<char_t, traits_t>& rhs) noexcept
2592 basic_string<char_t, traits_t> str(&lhs, 1);
2597 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2598 basic_string<char_t, traits_t> operator+(
const basic_string<char_t, traits_t>& lhs,
const string_t& rhs) noexcept
2600 basic_string<char_t, traits_t> str(lhs);
2605 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2606 basic_string<char_t, traits_t> operator+(basic_string<char_t, traits_t>&& lhs,
const string_t& rhs) noexcept
2608 basic_string<char_t, traits_t> str(std::move(lhs));
2613 template<
class char_t,
class traits_t, range_of_t_c<
char_t>
string_t>
2614 basic_string<char_t, traits_t> operator+(
const string_t& lhs,
const basic_string<char_t, traits_t>& rhs) noexcept
2616 basic_string<char_t, traits_t> str(lhs);
2625 template<
class char_t,
class traits_t>
2626 inline typename basic_string<char_t, traits_t>::size_type basic_string<char_t, traits_t>::size() const noexcept
2628 const size_type nSize = m_Data.size() /
sizeof(value_type);
2629 return nSize == 0 ? 0 : nSize - 1;
2636 template<
class char_t,
class traits_t>
2637 inline typename basic_string<char_t, traits_t>::pointer basic_string<char_t, traits_t>::data() noexcept
2639 return reinterpret_cast<pointer
>(m_Data.data());
2647 template<
class char_t,
class traits_t>
2648 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::at(size_type nIndex)
2653 return data()[nIndex];
2659 template<
class char_t,
class traits_t>
2660 inline void basic_string<char_t, traits_t>::clear() noexcept
2668 template<
class char_t,
class traits_t>
2669 struct std::hash<qx::basic_string<char_t, traits_t>>
2673 return traits_t::hash_function(str.data(), traits_t::hash_seed(), str.size());
2680 template<
class char_t,
class traits_t>
2688 template<
class char_t,
class traits_t>
2691 template<
class format_context_type>
2694 return QX_FMT_NS::format_to(
2697 qx::basic_string_view<char_t>(value.data(), value.size()));
2705 template<
class char_t,
class traits_t>
2706 qx::details::ostream<char_t>& operator<<(
2707 qx::details::ostream<char_t>& os,
2714 template<
class char_t,
class traits_t>
2717 typename qx::details::istream<traits_t>::iostate ret_bit = qx::details::istream<traits_t>::goodbit;
2719 auto try_push_back = [&str, &is, &ret_bit](char_t ch)
2721 typename traits_t::size_type nCurrentSize = str.size();
2722 if (str._resize(nCurrentSize + 1))
2724 str[nCurrentSize] = ch;
2730 ret_bit |= qx::details::istream<traits_t>::failbit;
2741 if (!traits_t::is_space(ch))
2751 if (!traits_t::is_space(ch))
2753 if (!try_push_back(ch))
2763 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.
void append(fwd_it_t itBegin, fwd_it_t itEnd) noexcept
Append string.
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.
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) noexcept
Append the formatted string to the current one.
size_type rfind(value_type chSymbol, size_type nBegin=npos, size_type nEnd=0) const noexcept
Find substring (reverse direction)
size_type length() const noexcept
Get string length.
void free() noexcept
Clear string and free allocated memory.
void from(const from_t &data)
Construct string from custom type.
size_type trim_right() noexcept
Trim the string to the right (whitespace characters)
requires format_acceptable_args_c< char_t, args_t... > void vformat(string_view svFormat, args_t &&... args)
Clear the string and format it with the format string and the args.
void assign(size_type nSymbols, value_type chSymbol) noexcept
Assign by filling.
size_type replace_all(const find_string_t &sFind, const replace_string_t &sReplace, size_type nBegin=0, size_type nEnd=npos) noexcept
Replace all occurrences of sFind with sReplace.
bool ends_with(value_type chSymbol) const noexcept
Check if current string ends with char.
void swap(basic_string &sOther) noexcept
Swap this str and other.
value_type pop_front() noexcept
Erase first char and return it.
void append(value_type chSymbol) noexcept
Append char.
bool contains(value_type chSymbol) const noexcept
Check if string contains char.
size_type trim() noexcept
Trim the string to the both sides (whitespace characters)
void to_upper() noexcept
Convert string to uppercase.
void shrink_to_fit() noexcept
Fit allocated size to string's actual size.
static basic_string static_from(const from_t &data)
Construct string from custom type and get it.
size_type find_last_not_of(value_type chSymbol, size_type nEnd=0) const noexcept
Finds the last character not equal to chSymbol.
size_type trim_left() noexcept
Trim the string to the left (whitespace characters)
size_type reserve(size_type nCapacity) noexcept
Reserve memory for the string.
requires format_acceptable_args_c< char_t, args_t... > void append_vformat(string_view svFormat, args_t &&... args)
Append the formatted string to the current one.
string_view substr(size_type nPos, size_type nSymbols=npos) const noexcept
Get substring.
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 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) noexcept
Create a string by formatting it with the format string and the args.
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.
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.
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) noexcept
Clear the string and format it with the format string and the args.
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.
#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.