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>
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>
212 const bool bRet = m_Data.resize((nSymbols > 0 ? nSymbols + 1 : 0) *
sizeof(value_type));
214 (*this)[nSymbols] =
QX_CHAR_PREFIX(
typename traits_t::value_type,
'\0');
219 template<
class char_t,
class traits_t>
222 m_Data.shrink_to_fit();
225 template<
class char_t,
class traits_t>
232 template<
class char_t,
class traits_t>
235 size_type nSymbols)
const noexcept
237 return string_view(data() + nPos, nSymbols != npos ? nSymbols : size() - nPos);
240 template<
class char_t,
class traits_t>
243 for (value_type& ch : *
this)
244 ch = traits_t::to_lower(ch);
247 template<
class char_t,
class traits_t>
250 for (value_type& ch : *
this)
251 ch = traits_t::to_upper(ch);
254 template<
class char_t,
class traits_t>
260 template<
class char_t,
class traits_t>
263 return at(size() - 1);
266 template<
class char_t,
class traits_t>
272 template<
class char_t,
class traits_t>
278 template<
class char_t,
class traits_t>
281 return m_Data.capacity() /
sizeof(value_type) - 1;
284 template<
class char_t,
class traits_t>
287 return std::numeric_limits<size_type>::max() - 1
291 template<
class char_t,
class traits_t>
295 std::optional<to_t> optResult = std::nullopt;
298 std::is_trivial_v<to_t> && std::is_standard_layout_v<to_t> || std::is_pointer_v<to_t>
299 || std::is_same_v<to_t, std::nullptr_t>)
301 if constexpr (std::is_same_v<to_t, std::nullptr_t>)
308 else if constexpr (std::is_same_v<to_t, bool>)
310 if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"true")) == 0)
314 else if (compare(
QX_STR_PREFIX(
typename traits_t::value_type,
"false")) == 0)
319 else if (
const auto pszSelectedFormat = pszFormat ? pszFormat : get_format_specifier<value_type, to_t>())
322 constexpr
size_t nBufferSize = 256;
324 const size_t nFormatSpecifierLength = traits_t::length(pszSelectedFormat);
325 if (nFormatSpecifierLength <= nBufferSize - svNSpecifier.size() - 1)
327 value_type formatBuffer[nBufferSize];
328 std::memcpy(formatBuffer, pszSelectedFormat, nFormatSpecifierLength *
sizeof(value_type));
330 formatBuffer + nFormatSpecifierLength,
332 svNSpecifier.size() *
sizeof(value_type));
333 formatBuffer[nFormatSpecifierLength + svNSpecifier.size()] =
QX_CHAR_PREFIX(value_type,
'\0');
337 const int nConvertedArgs = traits_t::sscanf(data(), formatBuffer, &result, &nSymbolsRead);
339 if (
static_cast<size_type
>(nSymbolsRead) == size() && nConvertedArgs == 1)
347 sstream_type ss(data());
355 template<
class char_t,
class traits_t>
359 size_type nPos)
const noexcept
361 size_type nCharsToCopy = 0;
363 if (pDest && nCount > 0 && nPos < size())
365 nCharsToCopy = std::min(nPos + nCount, size()) - nPos;
366 std::memcpy(pDest, data() + nPos, nCharsToCopy *
sizeof(value_type));
372 template<
class char_t,
class traits_t>
373 template<
class from_t>
377 std::is_trivial_v<from_t> && std::is_standard_layout_v<from_t> || std::is_pointer_v<from_t>
378 || std::is_same_v<from_t, std::nullptr_t>)
380 if constexpr (std::is_same_v<from_t, std::nullptr_t>)
382 assign(
QX_STR_PREFIX(
typename traits_t::value_type,
"nullptr"));
384 else if constexpr (std::is_same_v<from_t, bool>)
403 template<
class char_t,
class traits_t>
404 template<
class from_t>
409 return std::move(sTemp);
412 template<
class char_t,
class traits_t>
418 template<
class char_t,
class traits_t>
423 const size_type nSize = size();
424 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszStr) : nSymbols;
426 if (resize(nSize + nSizeSource))
427 std::memcpy(data() + nSize, pszStr, nSizeSource *
sizeof(value_type));
431 template<
class char_t,
class traits_t>
434 append(sStr.data(), sStr.size());
437 template<
class char_t,
class traits_t>
438 template<
class fwd_it_t>
441 for (
auto it = itBegin; it != itEnd; ++it)
445 template<
class char_t,
class traits_t>
446 template<range_of_t_c<
char_t>
string_t>
449 if constexpr (std::ranges::contiguous_range<string_t> && std::ranges::sized_range<string_t>)
451 append(sStr.data(), sStr.size());
455 append(sStr.begin(), sStr.end());
459 template<
class char_t,
class traits_t>
462 value_type chSymbol) noexcept
467 template<
class char_t,
class traits_t>
470 const_pointer pszWhat,
471 size_type nSymbols) noexcept
475 const size_type nSize = size();
476 const size_type nSizeSource = nSymbols == npos ? traits_t::length(pszWhat) : nSymbols;
478 if (nSizeSource > 0 && resize(nSize + nSizeSource))
480 std::memmove(data() + nPos + nSizeSource, data() + nPos, (nSize - nPos) *
sizeof(value_type));
481 std::memcpy(data() + nPos, pszWhat, nSizeSource *
sizeof(value_type));
482 return nPos + nSizeSource;
489 template<
class char_t,
class traits_t>
490 template<
class fwd_it_t>
493 fwd_it_t itWhatBegin,
494 fwd_it_t itWhatEnd) noexcept
496 if constexpr (is_random_access_iterator<fwd_it_t>)
498 return insert(nPos, itWhatBegin.operator->(),
static_cast<size_type
>(itWhatEnd - itWhatBegin));
502 size_type nWhatSize = 0;
503 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
506 size_type nStartSymbols = size();
507 if (nWhatSize > 0 && resize(nStartSymbols + nWhatSize))
509 std::memmove(data() + nPos + nWhatSize, data() + nPos, (nStartSymbols - nPos) *
sizeof(value_type));
511 size_type nWhatPos = 0;
512 for (
auto it = itWhatBegin; it != itWhatEnd; ++it)
514 at(nPos + nWhatPos) = *it;
518 return nPos + nWhatSize;
527 template<
class char_t,
class traits_t>
532 return insert(nPos, sWhat.data(), sWhat.size());
535 template<
class char_t,
class traits_t>
536 template<range_of_t_c<
char_t>
string_t>
539 string_t sWhat) noexcept
541 return insert(
static_cast<size_type
>(nPos), sWhat.begin(), sWhat.end());
544 template<
class char_t,
class traits_t>
547 value_type chSymbol) noexcept
549 return insert(
static_cast<size_type
>(itPos - cbegin()), chSymbol);
552 template<
class char_t,
class traits_t>
555 const_pointer pszWhat,
556 size_type nSymbols) noexcept
558 return insert(
static_cast<size_type
>(itPos - cbegin()), pszWhat, nSymbols);
561 template<
class char_t,
class traits_t>
566 return insert(
static_cast<size_type
>(itPos - cbegin()), sWhat.data(), sWhat.size());
569 template<
class char_t,
class traits_t>
570 template<
class fwd_it_t>
573 fwd_it_t itWhatBegin,
574 fwd_it_t itWhatEnd) noexcept
576 return insert(
static_cast<size_type
>(itPos - begin()), itWhatBegin, itWhatEnd);
579 template<
class char_t,
class traits_t>
580 template<range_of_t_c<
char_t>
string_t>
583 string_t sWhat) noexcept
585 return insert(
static_cast<size_type
>(itPos - begin()), sWhat.begin(), sWhat.end());
588 template<
class char_t,
class traits_t>
591 const size_t nStartSize = size();
592 resize(nStartSize + 1);
593 (*this)[nStartSize] = chSymbol;
596 template<
class char_t,
class traits_t>
599 insert(0, &chSymbol, 1);
602 template<
class char_t,
class traits_t>
605 if (
const typename iterator::difference_type nCharsToErase = itLast - itFirst; nCharsToErase > 0)
607 const size_type nStartSize = size();
608 const size_type nSymbolsToCopy = itLast != end() ? traits_t::length(itLast.operator->()) : 0;
610 if (nSymbolsToCopy > 0)
612 std::memmove(itFirst.operator->(), itLast.operator->(), nSymbolsToCopy *
sizeof(value_type));
615 if (
static_cast<typename iterator::difference_type
>(nStartSize) >= nCharsToErase)
617 resize(nStartSize - nCharsToErase);
622 template<
class char_t,
class traits_t>
625 erase(itPos, itPos + 1);
628 template<
class char_t,
class traits_t>
634 template<
class char_t,
class traits_t>
640 template<
class char_t,
class traits_t>
643 value_type chRet = back();
648 template<
class char_t,
class traits_t>
651 value_type chRet = front();
656 template<
class char_t,
class traits_t>
662 return traits_t::is_space(ch);
666 template<
class char_t,
class traits_t>
668 value_type chSymbol) noexcept
671 [chSymbol](value_type ch)
673 return ch == chSymbol;
677 template<
class char_t,
class traits_t>
679 const_pointer pszStr) noexcept
684 [pszStr](value_type ch)
686 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
701 template<
class char_t,
class traits_t>
703 const_pointer pszStr,
704 size_type nStrSize) noexcept
709 [pszStr, nStrSize](value_type ch)
711 for (size_type j = 0; j < nStrSize; ++j)
724 template<
class char_t,
class traits_t>
728 return trim_left(sStr.data(), sStr.size());
731 template<
class char_t,
class traits_t>
732 template<
class fwd_it_t>
735 fwd_it_t itEnd) noexcept
738 [itBegin, itEnd](
auto ch)
740 for (
auto it = itBegin; it != itEnd; ++it)
748 template<
class char_t,
class traits_t>
749 template<range_of_t_c<
char_t>
string_t>
751 const string_t& sStr) noexcept
753 return trim_left(sStr.begin(), sStr.end());
756 template<
class char_t,
class traits_t>
762 return traits_t::is_space(ch);
766 template<
class char_t,
class traits_t>
768 value_type chSymbol) noexcept
771 [chSymbol](value_type ch)
773 return ch == chSymbol;
777 template<
class char_t,
class traits_t>
779 const_pointer pszStr) noexcept
784 [pszStr](value_type ch)
786 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
801 template<
class char_t,
class traits_t>
803 const_pointer pszStr,
804 size_type nStrSize) noexcept
809 [pszStr, nStrSize](value_type ch)
811 for (size_type j = 0; j < nStrSize; ++j)
824 template<
class char_t,
class traits_t>
828 return trim_right(sStr.data(), sStr.size());
831 template<
class char_t,
class traits_t>
832 template<
class fwd_it_t>
835 fwd_it_t itEnd) noexcept
838 [itBegin, itEnd](
auto ch)
840 for (
auto it = itBegin; it != itEnd; ++it)
848 template<
class char_t,
class traits_t>
849 template<range_of_t_c<
char_t>
string_t>
851 const string_t& sStr) noexcept
853 return trim_right(sStr.begin(), sStr.end());
856 template<
class char_t,
class traits_t>
862 return traits_t::is_space(ch);
866 template<
class char_t,
class traits_t>
868 value_type chSymbol) noexcept
871 [chSymbol](value_type ch)
873 return ch == chSymbol;
877 template<
class char_t,
class traits_t>
879 const_pointer pszStr) noexcept
884 [pszStr](value_type ch)
886 for (size_type j = 0; pszStr[j] !=
QX_CHAR_PREFIX(value_type,
'\0'); ++j)
901 template<
class char_t,
class traits_t>
903 const_pointer pszStr,
904 size_type nStrSize) noexcept
909 [pszStr, nStrSize](value_type ch)
911 for (size_type j = 0; j < nStrSize; ++j)
924 template<
class char_t,
class traits_t>
928 return trim(sStr.data(), sStr.size());
931 template<
class char_t,
class traits_t>
932 template<
class fwd_it_t>
935 fwd_it_t itEnd) noexcept
938 [itBegin, itEnd](
auto ch)
940 for (
auto it = itBegin; it != itEnd; ++it)
948 template<
class char_t,
class traits_t>
949 template<range_of_t_c<
char_t>
string_t>
951 const string_t& sStr) noexcept
953 return trim(sStr.begin(), sStr.end());
956 template<
class char_t,
class traits_t>
960 size_type nEnd) noexcept
962 size_type nPos = find(chSymbol, nBegin, nEnd);
970 template<
class char_t,
class traits_t>
972 const_pointer pszStr,
975 size_type nStrSize) noexcept
979 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
980 const size_type nPos = find(pszStr, nBegin, nLocalStrSize, nEnd);
983 erase(nPos, nLocalStrSize);
993 template<
class char_t,
class traits_t>
997 size_type nEnd) noexcept
999 const size_type nPos = find(sStr, nBegin, nEnd);
1002 erase(nPos, sStr.size());
1007 template<
class char_t,
class traits_t>
1008 template<
class fwd_it_t>
1013 size_type nEnd) noexcept
1015 const size_type nPos = find(itBegin, itEnd, nBegin, nEnd);
1018 erase(nPos,
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>
1026 const string_t& sStr,
1028 size_type nEnd) noexcept
1030 return remove(sStr.begin(), sStr.end(), nBegin, nEnd);
1033 template<
class char_t,
class traits_t>
1036 return remove(chSymbol,
static_cast<size_type
>(0),
static_cast<size_type
>(1)) != npos;
1039 template<
class char_t,
class traits_t>
1042 return remove(pszStr,
static_cast<size_type
>(0), nStrSize, nStrSize) != npos;
1045 template<
class char_t,
class traits_t>
1048 return remove(sStr,
static_cast<size_type
>(0), sStr.size()) != npos;
1051 template<
class char_t,
class traits_t>
1052 template<
class fwd_it_t>
1055 return remove(itBegin, itEnd,
static_cast<size_type
>(0),
static_cast<size_type
>(std::distance(itBegin, itEnd)))
1059 template<
class char_t,
class traits_t>
1060 template<range_of_t_c<
char_t>
string_t>
1063 return remove_prefix(sStr.begin(), sStr.end());
1066 template<
class char_t,
class traits_t>
1069 const size_type nSize = size();
1070 return remove(chSymbol, nSize - 1, nSize) != npos;
1073 template<
class char_t,
class traits_t>
1078 const size_type nSize = size();
1079 const size_type nLocalStrSize = nStrSize != npos ? nStrSize : traits_t::length(pszStr);
1081 return remove(pszStr, nSize - nLocalStrSize, nSize, nLocalStrSize) != npos;
1089 template<
class char_t,
class traits_t>
1092 return remove_suffix(sStr.data(), sStr.size());
1095 template<
class char_t,
class traits_t>
1096 template<
class fwd_it_t>
1099 const size_type nSize = size();
1100 return remove(itBegin, itEnd, nSize -
static_cast<size_type
>(std::distance(itBegin, itEnd)), nSize) != npos;
1103 template<
class char_t,
class traits_t>
1104 template<range_of_t_c<
char_t>
string_t>
1107 return remove_suffix(sStr.begin(), sStr.end());
1110 template<
class char_t,
class traits_t>
1112 value_type chSymbol,
1114 size_type nEnd) noexcept
1116 size_type nOccurrences = 0;
1117 size_type nLastOccurrencePos = nBegin;
1122 nLastOccurrencePos = remove(chSymbol, nLastOccurrencePos, nEnd);
1123 }
while (nLastOccurrencePos != npos);
1125 return nOccurrences - 1;
1128 template<
class char_t,
class traits_t>
1130 const_pointer pszStr,
1133 size_type nStrSize) noexcept
1137 size_type nOccurrences = 0;
1138 size_type nLastOccurrencePos = nBegin;
1143 nLastOccurrencePos = remove(pszStr, nLastOccurrencePos, nEnd, nStrSize);
1144 }
while (nLastOccurrencePos != npos);
1146 return nOccurrences - 1;
1154 template<
class char_t,
class traits_t>
1158 size_type nEnd) noexcept
1160 return remove_all(sStr.data(), nBegin, nEnd, sStr.size());
1163 template<
class char_t,
class traits_t>
1164 template<
class fwd_it_t>
1169 size_type nEnd) noexcept
1171 size_type nOccurrences = 0;
1172 size_type nLastOccurrencePos = nBegin;
1177 nLastOccurrencePos = remove(itFirst, itLast, nLastOccurrencePos, nEnd);
1178 }
while (nLastOccurrencePos != npos);
1180 return nOccurrences - 1;
1183 template<
class char_t,
class traits_t>
1184 template<range_of_t_c<
char_t>
string_t>
1186 const string_t& sStr,
1188 size_type nEnd) noexcept
1190 return remove_all(sStr.begin(), sStr.end(), nBegin, nEnd);
1193 template<
class char_t,
class traits_t>
1197 const_pointer pszReplace,
1198 size_t nReplaceSize) noexcept
1200 const size_type nStartSize = size();
1201 const size_type nNewSize = nStartSize - nSize + nReplaceSize;
1206 data() + nBegin + nReplaceSize,
1207 data() + nBegin + nSize,
1208 (nStartSize - nBegin - nSize) *
sizeof(value_type));
1210 std::memcpy(data() + nBegin, pszReplace, nReplaceSize *
sizeof(value_type));
1214 return nBegin + nReplaceSize;
1217 template<
class char_t,
class traits_t>
1218 template<
class replace_
string_t>
1222 const replace_string_t& sReplace) noexcept
1224 return replace(nBegin, nSize, _get_string_view_like_data(sReplace), _get_string_view_like_size(sReplace));
1227 template<
class char_t,
class traits_t>
1228 template<
class find_
string_t,
class replace_
string_t>
1230 const find_string_t& sFind,
1231 const replace_string_t& sReplace,
1233 size_type nEnd) noexcept
1235 if (size_type nPos = find(sFind, nBegin, nEnd); nPos != npos)
1239 _get_string_view_like_size(sFind),
1240 _get_string_view_like_data(sReplace),
1241 _get_string_view_like_size(sReplace));
1249 template<
class char_t,
class traits_t>
1250 template<
class find_
string_t,
class replace_
string_t>
1252 const find_string_t& sFind,
1253 const replace_string_t& sReplace,
1255 size_type nEnd) noexcept
1257 size_type nOccurrences = 0;
1258 size_type nPos = nBegin;
1262 nPos = replace(sFind, sReplace, nPos, nEnd);
1265 }
while (nPos != npos);
1267 return nOccurrences;
1270 template<
class char_t,
class traits_t>
1273 return compare(&chSymbol, 1);
1276 template<
class char_t,
class traits_t>
1279 return traits_t::compare(data(), pszStr);
1282 template<
class char_t,
class traits_t>
1285 return traits_t::compare_n(data(), pStr, nSymbols);
1288 template<
class char_t,
class traits_t>
1291 return compare(sStr.data(), sStr.size());
1294 template<
class char_t,
class traits_t>
1295 template<
class fwd_it_t>
1298 return iter_strcmp(cbegin(), cend(), itBegin, itEnd);
1301 template<
class char_t,
class traits_t>
1302 template<range_of_t_c<
char_t>
string_t>
1305 return compare(sStr.begin(), sStr.end());
1308 template<
class char_t,
class traits_t>
1310 value_type chSymbol,
1312 size_type nEnd)
const noexcept
1317 [chSymbol](const_pointer pCurrentChar)
1319 return *pCurrentChar == chSymbol;
1323 template<
class char_t,
class traits_t>
1325 const_pointer pszWhat,
1327 size_type nWhatSize,
1328 size_type nEnd)
const noexcept
1332 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1337 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1339 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1348 template<
class char_t,
class traits_t>
1352 size_type nEnd)
const noexcept
1354 return find(sWhat.data(), nBegin, sWhat.size(), nEnd);
1357 template<
class char_t,
class traits_t>
1358 template<
class fwd_it_t>
1360 fwd_it_t itWhatBegin,
1363 size_type nEnd)
const noexcept
1365 const size_t nWhatSize = itWhatEnd - itWhatBegin;
1369 [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
1371 const size_t nStart =
static_cast<size_type
>(pCurrentChar - data());
1380 template<
class char_t,
class traits_t>
1381 template<range_of_t_c<
char_t>
string_t>
1385 size_type nEnd)
const noexcept
1387 return find(sWhat.begin(), sWhat.end(), nBegin, nEnd);
1390 template<
class char_t,
class traits_t>
1392 value_type chSymbol,
1394 size_type nEnd)
const noexcept
1399 [chSymbol](const_pointer pCurrentChar)
1401 return *pCurrentChar == chSymbol;
1405 template<
class char_t,
class traits_t>
1407 const_pointer pszWhat,
1409 size_type nWhatSize,
1410 size_type nEnd)
const noexcept
1414 const size_type nLocalWhatSize = nWhatSize != npos ? nWhatSize : traits_t::length(pszWhat);
1419 [pszWhat, nLocalWhatSize](const_pointer pCurrentChar)
1421 return !traits_t::compare_n(pszWhat, pCurrentChar, nLocalWhatSize);
1430 template<
class char_t,
class traits_t>
1434 size_type nEnd)
const noexcept
1436 return rfind(sWhat.data(), nBegin, sWhat.size(), nEnd);
1439 template<
class char_t,
class traits_t>
1440 template<
class fwd_it_t>
1442 fwd_it_t itWhatBegin,
1445 size_type nEnd)
const noexcept
1447 const size_t nWhatSize = itWhatEnd - itWhatBegin;
1451 [
this, itWhatBegin, itWhatEnd, nWhatSize](const_pointer pCurrentChar)
1453 const size_t nStart =
static_cast<size_type
>(pCurrentChar - data());
1462 template<
class char_t,
class traits_t>
1463 template<range_of_t_c<
char_t>
string_t>
1467 size_type nEnd)
const noexcept
1469 return rfind(sWhat.begin(), sWhat.end(), nBegin, nEnd);
1472 template<
class char_t,
class traits_t>
1474 value_type chSymbol,
1475 size_type nBegin)
const noexcept
1477 return find(chSymbol, nBegin);
1480 template<
class char_t,
class traits_t>
1482 const_pointer pszWhat,
1484 size_type nWhatSize)
const noexcept
1488 return _find_first_of(
1490 pszWhat + nWhatSize,
1492 [](const_pointer pChar)
1503 template<
class char_t,
class traits_t>
1505 const_pointer pszWhat,
1506 size_type nBegin)
const noexcept
1510 return _find_first_of(
1512 static_cast<const_pointer
>(
nullptr),
1514 [](const_pointer pChar)
1516 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1525 template<
class char_t,
class traits_t>
1528 size_type nBegin)
const noexcept
1530 return find_first_of(sWhat.data(), nBegin, sWhat.size());
1533 template<
class char_t,
class traits_t>
1534 template<
class fwd_it_t>
1536 fwd_it_t itWhatBegin,
1538 size_type nBegin)
const noexcept
1540 return _find_first_of(
1550 template<
class char_t,
class traits_t>
1551 template<range_of_t_c<
char_t>
string_t>
1554 size_type nBegin)
const noexcept
1556 return find_first_of(sWhat.begin(), sWhat.end(), nBegin);
1559 template<
class char_t,
class traits_t>
1561 value_type chSymbol,
1562 size_type nEnd)
const noexcept
1564 return rfind(chSymbol, npos, nEnd);
1567 template<
class char_t,
class traits_t>
1569 const_pointer pszWhat,
1571 size_type nWhatSize)
const noexcept
1575 return _find_last_of(
1577 pszWhat + nWhatSize,
1579 [](const_pointer pChar)
1590 template<
class char_t,
class traits_t>
1592 const_pointer pszWhat,
1593 size_type nEnd)
const noexcept
1597 return _find_last_of(
1599 static_cast<const_pointer
>(
nullptr),
1601 [](const_pointer pChar)
1603 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1612 template<
class char_t,
class traits_t>
1615 size_type nEnd)
const noexcept
1617 return find_last_of(sWhat.data(), nEnd, sWhat.size());
1620 template<
class char_t,
class traits_t>
1621 template<
class fwd_it_t>
1623 fwd_it_t itWhatBegin,
1625 size_type nEnd)
const noexcept
1627 return _find_last_of(
1637 template<
class char_t,
class traits_t>
1638 template<range_of_t_c<
char_t>
string_t>
1641 size_type nEnd)
const noexcept
1643 return find_last_of(sWhat.begin(), sWhat.end(), nEnd);
1646 template<
class char_t,
class traits_t>
1648 value_type chSymbol,
1649 size_type nBegin)
const noexcept
1654 [chSymbol](const_pointer pCurrentChar)
1656 return *pCurrentChar != chSymbol;
1660 template<
class char_t,
class traits_t>
1662 const_pointer pszWhat,
1664 size_type nWhatSize)
const noexcept
1668 return _find_first_not_of(
1670 pszWhat + nWhatSize,
1672 [](const_pointer pChar)
1683 template<
class char_t,
class traits_t>
1685 const_pointer pszWhat,
1686 size_type nBegin)
const noexcept
1690 return _find_first_not_of(
1692 static_cast<const_pointer
>(
nullptr),
1694 [](const_pointer pChar)
1696 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1705 template<
class char_t,
class traits_t>
1708 size_type nBegin)
const noexcept
1710 return find_first_not_of(sWhat.data(), nBegin, sWhat.size());
1713 template<
class char_t,
class traits_t>
1714 template<
class fwd_it_t>
1716 fwd_it_t itWhatBegin,
1718 size_type nBegin)
const noexcept
1720 return _find_first_not_of(
1730 template<
class char_t,
class traits_t>
1731 template<range_of_t_c<
char_t>
string_t>
1734 size_type nBegin)
const noexcept
1736 return find_first_not_of(sWhat.begin(), sWhat.end(), nBegin);
1739 template<
class char_t,
class traits_t>
1741 value_type chSymbol,
1742 size_type nEnd)
const noexcept
1747 [chSymbol](const_pointer pCurrentChar)
1749 return *pCurrentChar != chSymbol;
1753 template<
class char_t,
class traits_t>
1755 const_pointer pszWhat,
1757 size_type nWhatSize)
const noexcept
1761 return _find_last_not_of(
1763 pszWhat + nWhatSize,
1765 [](const_pointer pChar)
1776 template<
class char_t,
class traits_t>
1778 const_pointer pszWhat,
1779 size_type nEnd)
const noexcept
1783 return _find_last_not_of(
1785 static_cast<const_pointer
>(
nullptr),
1787 [](const_pointer pChar)
1789 return *(pChar + 1) !=
QX_CHAR_PREFIX(value_type,
'\0') ? pChar + 1 :
nullptr;
1798 template<
class char_t,
class traits_t>
1801 size_type nEnd)
const noexcept
1803 return find_last_not_of(sWhat.data(), nEnd, sWhat.size());
1806 template<
class char_t,
class traits_t>
1807 template<
class fwd_it_t>
1809 fwd_it_t itWhatBegin,
1811 size_type nEnd)
const noexcept
1813 return _find_last_not_of(
1823 template<
class char_t,
class traits_t>
1824 template<range_of_t_c<
char_t>
string_t>
1827 size_type nEnd)
const noexcept
1829 return find_last_not_of(sWhat.begin(), sWhat.end(), nEnd);
1832 template<
class char_t,
class traits_t>
1834 const value_type chSeparator)
const noexcept
1838 size_type nStart = 0;
1840 while ((nEnd = find(chSeparator, nStart)) != npos)
1842 tokens.emplace_back(substr(nStart, nEnd - nStart));
1844 while (traits_t::compare_n(data() + nStart, &chSeparator, 1) == 0)
1848 if (nStart != size())
1849 tokens.emplace_back(substr(nStart));
1851 return std::move(tokens);
1854 template<
class char_t,
class traits_t>
1856 const_pointer pszSeparator,
1857 size_type nSepLen)
const noexcept
1864 if (nSepLen == npos)
1865 nSepLen = traits_t::length(pszSeparator);
1867 size_type nStart = 0;
1869 while ((nEnd = find(pszSeparator, nStart, nSepLen, npos)) != npos)
1871 tokens.emplace_back(substr(nStart, nEnd - nStart));
1873 while (traits_t::compare_n(data() + nStart, pszSeparator, nSepLen) == 0)
1877 if (nStart != size())
1878 tokens.emplace_back(substr(nStart));
1883 template<
class char_t,
class traits_t>
1887 return split(sSeparator.data(), sSeparator.size());
1890 template<
class char_t,
class traits_t>
1891 template<
class fwd_it_t>
1893 fwd_it_t itSepFirst,
1894 fwd_it_t itSepLast)
const noexcept
1898 const size_type nSepLen =
static_cast<size_type
>(std::distance(itSepFirst, itSepLast));
1900 size_type nStart = 0;
1902 while ((nEnd = find(itSepFirst, itSepLast, nStart)) != npos)
1904 tokens.emplace_back(substr(nStart, nEnd - nStart));
1905 nStart = nEnd + nSepLen;
1907 tokens.emplace_back(substr(nStart));
1912 template<
class char_t,
class traits_t>
1913 template<range_of_t_c<
char_t>
string_t>
1915 const string_t& sSeparator)
const noexcept
1917 return split(sSeparator.begin(), sSeparator.end());
1920 template<
class char_t,
class traits_t>
1924 return at(0) == chSymbol;
1929 template<
class char_t,
class traits_t>
1934 if (size_type nThisSize = size(); nThisSize > 0)
1936 if (nStrSize == npos)
1937 nStrSize = traits_t::length(pszStr);
1939 if (nStrSize <= nThisSize)
1940 return traits_t::compare_n(data(), pszStr, nStrSize) == 0;
1947 template<
class char_t,
class traits_t>
1950 return starts_with(sStr.data(), sStr.size());
1953 template<
class char_t,
class traits_t>
1954 template<
class fwd_it_t>
1957 auto nStrSize = std::distance(itBegin, itEnd);
1958 return iter_strcmp(cbegin(), cbegin() +
static_cast<size_type
>(nStrSize), itBegin, itEnd) == 0;
1961 template<
class char_t,
class traits_t>
1962 template<range_of_t_c<
char_t>
string_t>
1965 return starts_with(sStr.begin(), sStr.end());
1968 template<
class char_t,
class traits_t>
1971 const size_type nSize = size();
1973 return at(nSize - 1) == chSymbol;
1978 template<
class char_t,
class traits_t>
1984 if (nStrSize == npos)
1985 nStrSize = traits_t::length(pszStr);
1987 return ends_with(pszStr, pszStr + nStrSize);
1990 template<
class char_t,
class traits_t>
1993 return ends_with(sStr.data(), sStr.size());
1996 template<
class char_t,
class traits_t>
1997 template<
class fwd_it_t>
2000 const size_t nOtherSize =
static_cast<size_type
>(std::distance(itBegin, itEnd));
2001 if (nOtherSize > size())
2004 return iter_strcmp(cend() - nOtherSize, cend(), itBegin, itEnd) == 0;
2007 template<
class char_t,
class traits_t>
2008 template<range_of_t_c<
char_t>
string_t>
2011 return ends_with(sStr.begin(), sStr.end());
2014 template<
class char_t,
class traits_t>
2017 return find(chSymbol) != npos;
2020 template<
class char_t,
class traits_t>
2023 return find(pszStr, 0, nStrSize) != npos;
2026 template<
class char_t,
class traits_t>
2029 return find(sStr) != npos;
2032 template<
class char_t,
class traits_t>
2033 template<
class fwd_it_t>
2036 return find(itBegin, itEnd) != npos;
2039 template<
class char_t,
class traits_t>
2040 template<range_of_t_c<
char_t>
string_t>
2043 return find(sStr) != npos;
2046 template<
class char_t,
class traits_t>
2053 template<
class char_t,
class traits_t>
2054 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(basic_string&& sStr) noexcept
2056 assign(std::move(sStr));
2060 template<
class char_t,
class traits_t>
2061 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const basic_string& sStr) noexcept
2067 template<
class char_t,
class traits_t>
2068 template<range_of_t_c<
char_t>
string_t>
2069 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator=(
const string_t& sStr) noexcept
2075 template<
class char_t,
class traits_t>
2076 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(value_type chSymbol) noexcept
2082 template<
class char_t,
class traits_t>
2083 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(const_pointer pszSource) noexcept
2086 append(pszSource, traits_t::length(pszSource));
2091 template<
class char_t,
class traits_t>
2092 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const basic_string& sStr) noexcept
2094 append(sStr.data(), sStr.size());
2098 template<
class char_t,
class traits_t>
2099 template<range_of_t_c<
char_t>
string_t>
2100 inline basic_string<char_t, traits_t>& basic_string<char_t, traits_t>::operator+=(
const string_t& sStr) noexcept
2102 append(sStr.begin(), sStr.end());
2106 template<
class char_t,
class traits_t>
2107 inline bool basic_string<char_t, traits_t>::operator==(value_type chSymbol)
const noexcept
2109 return size() == 1 && at(0) == chSymbol;
2112 template<
class char_t,
class traits_t>
2113 inline bool basic_string<char_t, traits_t>::operator==(const_pointer pszSource)
const noexcept
2115 return compare(pszSource) == 0;
2118 template<
class char_t,
class traits_t>
2119 inline bool basic_string<char_t, traits_t>::operator==(
const basic_string& sStr)
const noexcept
2121 return size() == sStr.size() && compare(sStr.data(), sStr.size()) == 0;
2124 template<
class char_t,
class traits_t>
2125 template<range_of_t_c<
char_t>
string_t>
2126 inline bool basic_string<char_t, traits_t>::operator==(
const string_t& sStr)
const noexcept
2128 return iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) == 0;
2131 template<
class char_t,
class traits_t>
2132 inline bool basic_string<char_t, traits_t>::operator!=(value_type chSymbol)
const noexcept
2134 return !operator==(chSymbol);
2137 template<
class char_t,
class traits_t>
2138 inline bool basic_string<char_t, traits_t>::operator!=(const_pointer pszSource)
const noexcept
2140 return !operator==(pszSource);
2143 template<
class char_t,
class traits_t>
2144 inline bool basic_string<char_t, traits_t>::operator!=(
const basic_string& sStr)
const noexcept
2146 return !operator==(sStr);
2149 template<
class char_t,
class traits_t>
2150 template<range_of_t_c<
char_t>
string_t>
2151 inline bool basic_string<char_t, traits_t>::operator!=(
const string_t& sStr)
const noexcept
2153 return !operator==(sStr);
2156 template<
class char_t,
class traits_t>
2157 inline bool basic_string<char_t, traits_t>::operator<(value_type chSymbol)
const noexcept
2159 return compare(&chSymbol, 1) < 0;
2162 template<
class char_t,
class traits_t>
2163 inline bool basic_string<char_t, traits_t>::operator<(const_pointer pszSource)
const noexcept
2165 return compare(pszSource) < 0;
2168 template<
class char_t,
class traits_t>
2169 inline bool basic_string<char_t, traits_t>::operator<(
const basic_string& sStr)
const noexcept
2171 return compare(sStr.data(), sStr.size()) < 0;
2174 template<
class char_t,
class traits_t>
2175 template<range_of_t_c<
char_t>
string_t>
2176 inline bool basic_string<char_t, traits_t>::operator<(
const string_t& sStr)
const noexcept
2178 return iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) < 0;
2181 template<
class char_t,
class traits_t>
2182 inline bool basic_string<char_t, traits_t>::operator<=(value_type chSymbol)
const noexcept
2184 return compare(&chSymbol, 1) <= 0;
2187 template<
class char_t,
class traits_t>
2188 inline bool basic_string<char_t, traits_t>::operator<=(const_pointer pszSource)
const noexcept
2190 return compare(pszSource) <= 0;
2193 template<
class char_t,
class traits_t>
2194 inline bool basic_string<char_t, traits_t>::operator<=(
const basic_string& sStr)
const noexcept
2196 return compare(sStr.data(), sStr.size()) <= 0;
2199 template<
class char_t,
class traits_t>
2200 template<range_of_t_c<
char_t>
string_t>
2201 inline bool basic_string<char_t, traits_t>::operator<=(
const string_t& sStr)
const noexcept
2203 return iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) <= 0;
2206 template<
class char_t,
class traits_t>
2207 inline bool basic_string<char_t, traits_t>::operator>(value_type chSymbol)
const noexcept
2209 return compare(&chSymbol, 1) > 0;
2212 template<
class char_t,
class traits_t>
2213 inline bool basic_string<char_t, traits_t>::operator>(const_pointer pszSource)
const noexcept
2215 return compare(pszSource) > 0;
2218 template<
class char_t,
class traits_t>
2219 inline bool basic_string<char_t, traits_t>::operator>(
const basic_string& sStr)
const noexcept
2221 return compare(sStr.data(), sStr.size()) > 0;
2224 template<
class char_t,
class traits_t>
2225 template<range_of_t_c<
char_t>
string_t>
2226 inline bool basic_string<char_t, traits_t>::operator>(
const string_t& sStr)
const noexcept
2228 return iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) > 0;
2231 template<
class char_t,
class traits_t>
2232 inline bool basic_string<char_t, traits_t>::operator>=(value_type chSymbol)
const noexcept
2234 return compare(&chSymbol, 1) >= 0;
2237 template<
class char_t,
class traits_t>
2238 inline bool basic_string<char_t, traits_t>::operator>=(const_pointer pszSource)
const noexcept
2240 return compare(pszSource) >= 0;
2243 template<
class char_t,
class traits_t>
2244 inline bool basic_string<char_t, traits_t>::operator>=(
const basic_string& sStr)
const noexcept
2246 return compare(sStr.data(), sStr.size()) >= 0;
2249 template<
class char_t,
class traits_t>
2250 template<range_of_t_c<
char_t>
string_t>
2251 inline bool basic_string<char_t, traits_t>::operator>=(
const string_t& sStr)
const noexcept
2253 return iter_strcmp(cbegin(), cend(), sStr.begin(), sStr.end()) >= 0;
2256 template<
class char_t,
class traits_t>
2257 inline typename basic_string<char_t, traits_t>::reference basic_string<char_t, traits_t>::operator[](
2258 size_type nSymbol) noexcept
2260 return data()[nSymbol];
2263 template<
class char_t,
class traits_t>
2264 inline typename basic_string<char_t, traits_t>::const_reference basic_string<char_t, traits_t>::operator[](
2265 size_type nSymbol)
const noexcept
2267 return data()[nSymbol];
2270 template<
class char_t,
class traits_t>
2271 inline basic_string<char_t, traits_t>::operator std::basic_string_view<
2272 typename basic_string<char_t, traits_t>::value_type>()
const noexcept
2274 return string_view(data(), size());
2277 template<
class char_t,
class traits_t>
2278 inline basic_string<char_t, traits_t>::operator bool() const noexcept
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.
size_type insert(size_type nPos, const basic_string &sWhat) noexcept
Insert substring.
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.
bool resize(size_type nSymbols) noexcept
Resize string.
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.