11template < prototype_
character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
12inline ::std::strong_ordering _sz_compare(
const CHARACTER * pA,
const CHARACTER * pB, ORDERING ordering)
noexcept
18 auto order = ordering.order(*pA, *pB);
20 if (order != 0 || !*pA || !*pB)
36template < prototype_
character CHARACTER >
37constexpr ::std::strong_ordering _sz_compare(
const CHARACTER * pA,
const CHARACTER * pB)
noexcept
45template < prototype_
character CHARACTER >
46constexpr ::std::strong_ordering case_insensitive__sz_compare(
const CHARACTER * pA,
const CHARACTER * pB)
noexcept
49 return _sz_compare(pA, pB, ::comparison::case_insensitive < CHARACTER >());
54template < prototype_
character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
55inline ::std::strong_ordering _sz_count_compare(
const CHARACTER * pA,
const CHARACTER * pB, character_count sizeB, ORDERING ordering)
noexcept
58 auto pBEnd = pB + sizeB;
70 auto order = ordering.order(*pA, *pB);
72 if (order != 0 || !*pA)
88template < prototype_
character CHARACTER >
89constexpr ::std::strong_ordering _sz_count_compare(
const CHARACTER * pA,
const CHARACTER * pB, character_count sizeB)
noexcept
97template < prototype_
character CHARACTER >
98constexpr ::std::strong_ordering case_insensitive__sz_count_compare(
const CHARACTER * pA,
const CHARACTER * pB, character_count sizeB)
noexcept
101 return _sz_count_compare(pA, pB, sizeB, ::comparison::case_insensitive < CHARACTER >());
106template < prototype_
character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
107inline ::std::strong_ordering _count_sz_compare(
const CHARACTER * pA, character_count sizeA,
const CHARACTER * pB, ORDERING ordering)
noexcept
110 auto pAEnd = pA + sizeA;
118 return ordering.order({}, *pB);
122 auto order = ordering.order(*pA, *pB);
124 if (order != 0 || !*pB)
140template < prototype_
character CHARACTER >
141constexpr ::std::strong_ordering _count_sz_compare(
const CHARACTER * pA, character_count sizeA,
const CHARACTER * pB)
noexcept
149template < prototype_
character CHARACTER >
150constexpr ::std::strong_ordering case_insensitive__count_sz_compare(
const CHARACTER * pA, character_count sizeA,
const CHARACTER * pB)
noexcept
153 return _count_sz_compare(pA, sizeA, pB, ::comparison::case_insensitive < CHARACTER >());
179template <
typename ITERATOR_TYPE >
180inline ::std::strong_ordering _scopedstr_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB)
noexcept
183 character_count len = minimum(scopedstrA.size(), scopedstrB.size());
185 auto order = string_count_collate(scopedstrA.begin(), scopedstrB.begin(), len);
194 return scopedstrA.size() <=> scopedstrB.size();
199template <
typename ITERATOR_TYPE >
200inline ::std::strong_ordering _case_insensitive_scopedstr_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB)
noexcept
203 character_count len = minimum(scopedstrA.size(), scopedstrB.size());
205 auto order = case_insensitive_string_count_collate(scopedstrA.begin(), scopedstrB.begin(), len);
214 return scopedstrA.size() <=> scopedstrB.size();
255template <
typename ITERATOR_TYPE >
256inline ::std::strong_ordering range_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB)
noexcept
259 ::std::strong_ordering order(::std::strong_ordering::less);
261 if (scopedstrA._initialize_order(order, scopedstrA, scopedstrB))
268 return _string_collate(::string_base < ITERATOR_TYPE >(scopedstrA).c_str(), ::string_base < ITERATOR_TYPE >(scopedstrB).c_str());
273template <
typename ITERATOR_TYPE >
274inline ::std::strong_ordering case_insensitive_range_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB)
noexcept
277 ::std::strong_ordering order(::std::strong_ordering::less);
279 if (scopedstrA._initialize_order(order, scopedstrA, scopedstrB))
286 return _case_insensitive_string_collate(::string_base < ITERATOR_TYPE >(scopedstrA).c_str(), ::string_base < ITERATOR_TYPE >(scopedstrB).c_str());
291template < prototype_
character CHARACTER >
292inline ::std::strong_ordering _sz_count_collate(
const CHARACTER * pszA,
const CHARACTER * pszB, character_count sizeB)
noexcept
295 return range_collate<const CHARACTER>(scopedstrA, { pszB, sizeB });
300template < prototype_
character CHARACTER >
301inline ::std::strong_ordering _case_insensitive_sz_count_collate(
const CHARACTER * pszA,
const CHARACTER * pszB, character_count sizeB)
noexcept
304 return case_insensitive_range_collate<const CHARACTER>(scopedstrA, { pszB, sizeB });
309inline ::std::strong_ordering _count_sz_collate(const_char_pointer pszA, character_count sizeA, const_char_pointer pszB)
noexcept
312 return range_collate<const_char_pointer >({ pszA, sizeA }, pszB);
317inline ::std::strong_ordering _case_insensitive_count_sz_collate(const_char_pointer pszA, character_count sizeA, const_char_pointer pszB)
noexcept
320 return case_insensitive_range_collate<const_char_pointer >({ pszA, sizeA }, pszB);
325CLASS_DECL_ACME ::string string_formatf(const_char_pointer pszFormat, ...);
331CLASS_DECL_ACME
void foo123();
372template <
typename ITERATOR_TYPE >
373template < other_primitive_character < typename ::string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
377 auto oldlen = this->size();
379 character_count iaLen[t_size];
381 character_count* plen = iaLen;
383 auto dstlen = a.__utf_length(this->begin(), plen);
385 auto p = get_buffer(dstlen);
391 a.__utf_concatenate_to(p, plen);
400template <
typename ITERATOR_TYPE >
404 auto pmetadata = string_base::NATURAL_META_DATA::from_data(
range.m_begin);
406 pmetadata->natural_increment_reference_count();
412 this->m_erange =
range.m_erange;
637template <
typename ITERATOR_TYPE >
638inline character_count const_string_range < ITERATOR_TYPE >::unichar_count()
const
641 return ::unichar_count(this->begin());
1099template <
typename ITERATOR_TYPE >
1100template < prototype_
character CHARACTER2 >
1101inline ::string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(
const CHARACTER2 * start, character_count len)
1104 _assign(start, len);
1242template <
typename ITERATOR_TYPE >
1243template < prototype_
character CHARACTER2 >
1244inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::_assign(
const CHARACTER2 * pszSource, character_count len)
1247 auto dstlen = utf_to_utf_length(this->begin(), pszSource, len);
1258 auto pszTarget = this->get_buffer(dstlen);
1260 utf_to_utf(scopedstrTarget, pszSource, len);
1262 this->release_buffer(dstlen);
1334template <
typename ITERATOR_TYPE >
1335template < prototype_
character CHARACTER2 >
1336inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(CHARACTER2 chSrc, character_count repeat)
1342 auto lenUnit = utf_to_utf_length(this->begin(), &chSrc, 1);
1344 auto len = lenUnit * repeat;
1346 auto psz = get_buffer(len);
1350 utf_to_utf(sz, &chSrc, 1);
1359 for (::collection::index j = 0; j < lenUnit; j++)
1362 *pTarget++ = *pSource;
1370 release_buffer(len);
1550template <
typename ITERATOR_TYPE >
1551template < other_primitive_character < typename ::string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
1552inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::_append(
const OTHER_CHARACTER * pszSrc, character_count count)
1555 auto nOldLength = this->length();
1564 character_count nNewLength = nOldLength + utf_to_utf_length(this->begin(), pszSrc, count);
1566 auto pszBuffer = get_buffer(nNewLength,
true);
1568 utf_to_utf(scopedstrBuffer + nOldLength, pszSrc, count);
1570 release_buffer(nNewLength);
1629template <
typename ITERATOR_TYPE >
1630inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_character(::ansi_character ch)
1633 return append(&ch, 1);
1638template <
typename ITERATOR_TYPE >
1639inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_character(::wd16_character wch)
1642 return append(&wch, 1);
1647template <
typename ITERATOR_TYPE >
1648inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_character(::wd32_character wch)
1651 return append(&wch, 1);
1656template <
typename ITERATOR_TYPE >
1657inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(character_count len,
CHARACTER ch)
1663 character_count nOldLength = this->size();
1665 character_count nNewLength = nOldLength + len;
1667 CHARACTER * pszBuffer = this->get_buffer(nNewLength,
true);
1669 auto pch = pszBuffer + nOldLength;
1671 auto p = pch + len - 1;
1682 this->release_buffer(nNewLength);
1860template <
typename ITERATOR_TYPE >
1861template < prototype_
character CHARACTER2 >
1862string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::assign(
const CHARACTER2 * start,
const CHARACTER2 * end)
1865 return assign(start, end - start);
2098template <
typename ITERATOR_TYPE >
2099inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_left(character_count count)
const
2102 return { this->begin(), this->unichar_at(count) };
2108template <
typename ITERATOR_TYPE >
2109inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iFirst)
const
2112 return { this->unichar_at(iFirst), this->end() };
2117template <
typename ITERATOR_TYPE >
2118inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iStart, character_count iCount)
const
2121 return { this->unichar_at(iStart), this->unichar_at(iStart + iCount) };
2135template < prototype_
character CHARACTER >
2136inline bool operator>(
const CHARACTER * psz,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2139 return string_compare(scopedstr, string_safe_length(scopedstr), scopedstr.begin(), scopedstr.size()) > 0;
2144template < prototype_
character CHARACTER >
2145inline bool operator > (
CHARACTER ch,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2148 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) > 0;
2153template < prototype_
character CHARACTER >
2154inline bool operator > (::wide_character ch,
const typename ::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2157 return wide_string(ch) > scopedstr;
2162template < prototype_
character CHARACTER >
2163inline bool operator>(::i32 i,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2166 return ::string_base<CHARACTER>(i) > scopedstr;
2171template < prototype_
character CHARACTER >
2172inline bool operator<(
const CHARACTER * psz,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2175 return string_compare(scopedstr, string_save_length(scopedstr), scopedstr.begin(), scopedstr.size()) < 0;
2180template < prototype_
character CHARACTER >
2181inline bool operator<(
CHARACTER ch,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2184 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) < 0;
2189template < prototype_
character CHARACTER >
2190inline bool operator<(::i32 i,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2193 return ::string_base <CHARACTER>(i) < scopedstr;
2198template <
typename ITERATOR_TYPE >
2199inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::lower()
const
2202 return string_base < ITERATOR_TYPE >(*this).make_lower();
2207template <
typename ITERATOR_TYPE >
2208inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::upper()
const
2211 return string_base < ITERATOR_TYPE >(*this).make_upper();
2216template < prototype_
character CHARACTER >
2217inline const CHARACTER * FormatArgument(
const typename GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
noexcept
2220 return scopedstr.begin();
2285template <
typename ITERATOR_TYPE >
2286template < prototype_array A_STRING_ARRAY >
2287bool const_string_range < ITERATOR_TYPE >::contains_any(
const A_STRING_ARRAY & stra)
const
2290 for (
auto & scopedstr : stra)
2293 if (contains(scopedstr))
2307template <
typename ITERATOR_TYPE >
2308template < prototype_array A_STRING_ARRAY >
2309bool const_string_range < ITERATOR_TYPE >::contains_all(
const A_STRING_ARRAY & stra)
const
2312 for (
auto & scopedstr : stra)
2315 if (!contains(scopedstr))
2331template <
typename ITERATOR_TYPE >
2332template < prototype_array A_STRING_ARRAY >
2333bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_at_least_one_of(
const A_STRING_ARRAY & stra)
const
2336 for (
auto & scopedstr : stra)
2339 if (case_insensitive_contains(scopedstr))
2353template <
typename ITERATOR_TYPE >
2354template < prototype_array A_STRING_ARRAY >
2355bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_all(
const A_STRING_ARRAY & stra)
const
2358 for (
auto & scopedstr : stra)
2361 if (!case_insensitive_contains(scopedstr))
2375template <
typename ITERATOR_TYPE >
2376template < prototype_array A_STRING_ARRAY >
2377bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_at_least_one_of(
const A_STRING_ARRAY & stra)
const
2380 for (
auto & scopedstr : stra)
2383 if (unicode_case_insensitive_contains(scopedstr))
2397template <
typename ITERATOR_TYPE >
2398template < prototype_array A_STRING_ARRAY >
2399bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_all(
const A_STRING_ARRAY & stra)
const
2402 for (
auto & scopedstr : stra)
2405 if (!unicode_case_insensitive_contains(scopedstr))
2420template <
typename ITERATOR_TYPE >
2421string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::Tokenize(
const SCOPED_STRING & scopedstrTokens, character_count & start)
const
2426 throw_exception(error_bad_argument);
2428 if (scopedstrTokens.is_empty())
2432 return(string_base < ITERATOR_TYPE >(this->begin() + start));
2437 const CHARACTER * pszPlace = this->begin() + start;
2438 const CHARACTER * pszEnd = this->begin() + size();
2439 if (scopedstrPlace < pszEnd)
2441 character_count nIncluding = string_skip_any_character_in(scopedstrPlace,
2444 if ((scopedstrPlace + nIncluding) < pszEnd)
2446 pszPlace += nIncluding;
2447 character_count nExcluding = string_find_first_character_in(scopedstrPlace, scopedstrTokens);
2449 character_count iFrom = start + nIncluding;
2450 character_count nUntil = nExcluding;
2451 start = iFrom + nUntil + 1;
2453 return substr(iFrom, nUntil);
2461 return(string_base < ITERATOR_TYPE >());
2468template <
typename ITERATOR_TYPE >
2469string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::intersection(
const SCOPED_STRING & scopedstrFind)
const
2472 string_base < ITERATOR_TYPE > scopedstr;
2474 for (character_count i = 0; i < size(); i++)
2477 auto ch = this->operator[](i);
2479 if (scopedstrFind.contains(ch))
2494template <
typename ITERATOR_TYPE >
2495inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::concatenate_with_separator(
const SCOPED_STRING & scopedstrSeparator,
const SCOPED_STRING & scopedstr)
2498 if (this->has_character())
2501 if (scopedstr.has_character())
2504 this->append(scopedstrSeparator + scopedstr);
2509 else if (scopedstr.has_character())
2512 this->assign(scopedstr);
2522template <
typename ITERATOR_TYPE >
2523inline void string_base < ITERATOR_TYPE >::get_string(
CHARACTER * psz)
const noexcept
2526 string_count_copy(scopedstr, this->begin(), length());
2579template <
typename ITERATOR_TYPE >
2580string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::release_buffer(character_count characterCount)
2583 if (characterCount < 0)
2586 characterCount = string_safe_length(this->begin()) + characterCount + 1;
2590 this->NATURAL_POINTER::metadata()->set_character_count(characterCount);
2592 this->m_end = this->m_begin + characterCount;
2605template <
typename ITERATOR_TYPE >
2606inline memsize string_base < ITERATOR_TYPE >::character_count_in_bytes()
const {
return this->NATURAL_POINTER::metadata()->character_count_in_bytes(); }
2609template <
typename ITERATOR_TYPE >
2610inline memsize string_base < ITERATOR_TYPE >::null_terminated_character_count_in_bytes()
const {
return this->NATURAL_POINTER::metadata()->character_count_in_bytes() +
sizeof(
CHARACTER); }
2613template <
typename ITERATOR_TYPE >
2614void string_base < ITERATOR_TYPE >::resize(character_count n,
CHARACTER c)
2617 character_count nOldSize = length();
2628 auto psz = this->get_buffer(n);
2630 flood_characters(scopedstr + nOldSize, c, n - nOldSize);
2632 this->release_buffer(n);
2642template <
typename ITERATOR_TYPE >
2643inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::truncate(this_iterator p)
2646 if(p <= this->begin())
2652 else if(p < this->end())
2655 auto pmetadata = this->NATURAL_POINTER::metadata();
2657 if (pmetadata->natural_is_shared())
2660 *
this = (*this)(0, p);
2666 auto characterCount = p - this->begin();
2668 pmetadata->set_character_count(characterCount);
2670 this->m_end = this->m_begin + characterCount;
2683template <
typename ITERATOR_TYPE >
2684inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::erase_beginning(this_iterator p)
2689 assign(p, this->m_end - p);
2691 return this->m_begin;
2697template <
typename ITERATOR_TYPE >
2698inline void string_base < ITERATOR_TYPE >::set_at(character_count iChar,
CHARACTER ch)
2701 auto p = this->NATURAL_POINTER::metadata();
2703 if (iChar >= p->character_count())
2706 throw ::exception(error_index_out_of_bounds);
2710 if (p->natural_is_shared())
2713 fork_string(maximum(p->character_count(), iChar + 1),
true);
2717 ((
CHARACTER *)this->m_begin)[iChar] = ch;
2721template <
typename ITERATOR_TYPE >
2722bool const_string_range < ITERATOR_TYPE >::contains(
const SCOPED_STRING & scopedstr)
const
2725 return ::is_set(find(scopedstr));
2730template <
typename ITERATOR_TYPE >
2731bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(
const SCOPED_STRING & scopedstr)
const
2734 return ::is_set(case_insensitive_find(scopedstr));
2938template <
typename ITERATOR_TYPE >
2939bool const_string_range < ITERATOR_TYPE >::contains(
const SCOPED_STRING & scopedstr,
const CHARACTER ** ppszBeg,
const CHARACTER ** ppszEnd)
const
2942 auto pFind = this->find(scopedstr);
2944 if (::is_null(pFind))
2951 if (::is_set(ppszBeg))
2958 if (::is_set(ppszEnd))
2961 *ppszEnd = pFind + scopedstr.size();
2970template <
typename ITERATOR_TYPE >
2971bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(
const SCOPED_STRING & scopedstr,
const CHARACTER ** ppszBeg,
const CHARACTER ** ppszEnd)
const
2974 auto pFind = this->case_insensitive_find(scopedstr);
2976 if (::is_null(pFind))
2983 if (::is_set(ppszBeg))
2990 if (::is_set(ppszEnd))
2993 *ppszEnd = pFind + scopedstr.size();
3002template <
typename ITERATOR_TYPE >
3003bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(
const SCOPED_STRING & scopedstr,
const CHARACTER ** ppszBeg,
const CHARACTER ** ppszEnd)
const
3006 auto pFind = this->unicode_case_insensitive_find(scopedstr);
3008 if (::is_null(pFind))
3015 if (::is_set(ppszBeg))
3022 if (::is_set(ppszEnd))
3025 *ppszEnd = pFind + scopedstr.size();
3150template <
typename ITERATOR_TYPE >
3151bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(
const SCOPED_STRING & scopedstr)
const
3154 return ::is_set(unicode_case_insensitive_find(scopedstr));
3193template <
typename ITERATOR_TYPE >
3194string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::erase(character_count iIndex, character_count count)
3197 character_count nLength = size();
3213 if (count + iIndex > nLength)
3216 count = nLength - iIndex;
3227 if (count + iIndex > nLength)
3230 count = nLength - iIndex;
3237 character_count nNewLength = nLength - count;
3239 character_count nCopy = nLength - (iIndex + count) + 1;
3243 memory_transfer(scopedstrBuffer + iIndex, pszBuffer + iIndex + count, (
size_t)nCopy);
3245 release_buffer(nNewLength);
3254template <
typename ITERATOR_TYPE >
3255inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i,
CHARACTER ch)
3272 character_count nNewLength = size() + 1;
3274 CHARACTER * pszBuffer = get_buffer(nNewLength);
3276 memory_transfer(scopedstrBuffer + i + 1, pszBuffer + i, nNewLength - i);
3280 release_buffer(nNewLength);
3287template <
typename ITERATOR_TYPE >
3288inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i,
const string_base & str)
3305 character_count nInsertLength = str.size();
3307 character_count nNewLength = size();
3309 if (nInsertLength > 0)
3312 nNewLength += nInsertLength;
3314 CHARACTER * pszBuffer = get_buffer(nNewLength);
3316 memory_transfer(scopedstrBuffer + i + nInsertLength, pszBuffer + i, (nNewLength - i - nInsertLength + 1) *
sizeof(
CHARACTER));
3318 memory_copy(scopedstrBuffer + i, str.begin(), nInsertLength *
sizeof(
CHARACTER));
3320 release_buffer(nNewLength);
3329template <
typename ITERATOR_TYPE >
3330inline ::collection::count string_base < ITERATOR_TYPE >::replace_with(
CHARACTER charNew,
CHARACTER charOld, character_count start)
3333 character_count count = 0;
3336 if (charOld != charNew)
3339 bool bCopied =
false;
3342 character_count nLength = size();
3343 character_count iChar = 0;
3344 while (iChar < nLength)
3347 if (scopedstrBuffer[iChar] == charOld)
3352 pszBuffer = get_buffer(nLength);
3354 pszBuffer[iChar] = charNew;
3357 iChar = character_count((scopedstrBuffer + iChar + 1) - pszBuffer);
3361 release_buffer(nLength);
3464template <
typename ITERATOR_TYPE >
3466::collection::count string_base < ITERATOR_TYPE >::replace_with_count(
const SCOPED_STRING & scopedstrNew,
const SCOPED_STRING & scopedstrOld, character_count start)
3471 ::collection::count c = 0;
3474 character_count nSourceLen = scopedstrOld.size();
3475 if (nSourceLen == 0)
3478 character_count nReplacementLen = scopedstrNew.size();
3481 character_count count = 0;
3485 const CHARACTER * pszStart = this->begin() + start;
3489 while ((scopedstrTarget = string_find_string(pszStart, scopedstrOld)) !=
nullptr)
3494 pszStart = pszTarget + nSourceLen;
3507 character_count nOldLength = size();
3508 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
3510 CHARACTER * pszBuffer = get_buffer(maximum(nNewLength, nOldLength));
3512 const CHARACTER * pszStart = pszBuffer + start;
3513 const CHARACTER * pszEnd = pszBuffer + nOldLength;
3516 while (pszStart < pszEnd)
3521 while ((scopedstrTarget = (
CHARACTER *)string_find_string(pszStart, scopedstrOld)) !=
nullptr)
3524 character_count nBalance = nOldLength - character_count(scopedstrTarget - pszBuffer + nSourceLen);
3526 memory_transfer((
void *)(scopedstrTarget + nReplacementLen), pszTarget + nSourceLen, nBalance *
sizeof(
CHARACTER));
3528 ::memory_copy((
void *)pszTarget, scopedstrNew, nReplacementLen *
sizeof(
CHARACTER));
3530 pszStart = pszTarget + nReplacementLen;
3532 pszTarget[nReplacementLen + nBalance] = 0;
3534 nOldLength += (nReplacementLen - nSourceLen);
3538 pszStart += string_safe_length(pszStart) + 1;
3542 ASSERT(scopedstrBuffer[nNewLength] == 0);
3544 release_buffer(nNewLength);
3553template <
typename ITERATOR_TYPE >
3555::collection::count string_base < ITERATOR_TYPE >::replace_with_ci_count(
const SCOPED_STRING & scopedstrNew,
const SCOPED_STRING & scopedstrOld, character_count start)
3560 ::collection::count c = 0;
3563 character_count nSourceLen = scopedstrOld.size();
3564 if (nSourceLen == 0)
3567 character_count nReplacementLen = scopedstrOld.size();
3570 character_count count = 0;
3572 const CHARACTER * pszStart = this->begin() + start;
3575 while ((scopedstrTarget = case_insensitive_string_find_string(pszStart, scopedstrOld)) !=
nullptr)
3578 pszStart = pszTarget + nSourceLen;
3588 character_count nOldLength = size();
3589 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
3591 CHARACTER * pszBuffer = get_buffer(maximum(nNewLength, nOldLength));
3593 CHARACTER * pszStart = pszBuffer + start;
3594 CHARACTER * pszEnd = pszBuffer + nOldLength;
3597 while (pszStart < pszEnd)
3602 while ((scopedstrTarget = (
CHARACTER *)case_insensitive_string_find_string(pszStart, scopedstrOld)) !=
nullptr)
3605 character_count nBalance = nOldLength - character_count(scopedstrTarget - pszBuffer + nSourceLen);
3607 memory_transfer(scopedstrTarget + nReplacementLen, pszTarget + nSourceLen, nBalance *
sizeof(
CHARACTER));
3609 ::memory_copy(scopedstrTarget, scopedstrNew, nReplacementLen *
sizeof(
CHARACTER));
3611 pszStart = pszTarget + nReplacementLen;
3613 pszTarget[nReplacementLen + nBalance] = 0;
3615 nOldLength += (nReplacementLen - nSourceLen);
3619 pszStart += string_safe_length(pszStart) + 1;
3623 ASSERT(scopedstrBuffer[nNewLength] == 0);
3625 release_buffer(nNewLength);
3678template <
typename ITERATOR_TYPE >
3679string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::replace(const_iterator start, const_iterator end,
const SCOPED_STRING & scopedstr)
3682 auto finalLen = this->size() + scopedstr.size() - (end - start);
3686 auto psz = str.get_buffer(finalLen);
3688 memory_copy(scopedstr, this->begin(), start - this->begin());
3690 memory_copy(scopedstr + (start - this->begin()), scopedstr.begin(), scopedstr.size());
3692 memory_copy(scopedstr + (start - this->begin()) + scopedstr.size(), end, this->end() - end);
3694 str.release_buffer(finalLen);
3696 *
this = ::transfer(str);
3703template <
typename ITERATOR_TYPE >
3704inline ::collection::count string_base < ITERATOR_TYPE >::erase_character(
CHARACTER chRemove)
3707 character_count nLength = size();
3709 CHARACTER * pszBuffer = get_buffer(nLength);
3715 CHARACTER * pszEnd = pszBuffer + nLength;
3717 while (scopedstrSource < pszEnd)
3719 CHARACTER * pszNewSource = pszSource + 1;
3720 if (*pszSource != chRemove)
3724 size_t NewSourceGap = (scopedstrNewSource - pszSource);
3725 CHARACTER * pszNewDest = pszDest + NewSourceGap;
3727 for (i = 0; pszDest != pszNewDest && i < NewSourceGap; i++)
3729 *pszDest = *pszSource;
3734 pszSource = pszNewSource;
3737 character_count count = character_count(scopedstrSource - pszDest);
3738 release_buffer(nLength - count);
3745template <
typename ITERATOR_TYPE >
3746inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::find(
CHARACTER ch)
const RELEASENOTHROW
3749 return this->find_first(ch);
3816template <
typename ITERATOR_TYPE >
3817inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::case_insensitive_find(
CHARACTER ch)
const RELEASENOTHROW
3845 auto psz = this->begin();
3847 while(scopedstr < this->end())
3850 if (character_tolower(*psz) == character_tolower(ch))
3884template <
typename ITERATOR_TYPE >
3888 return ::string_find_character(this->begin() + start, this->end(), ch);
4050template <
typename ITERATOR_TYPE >
4056 auto rangeScope = *
this;
4058 if (this->_initialize_find(p, scopedstr, rangeScope))
4067 auto pszBlock = (
const CHARACTER * ) scopedstr.begin();
4069 auto pszBlockEnd = (
const CHARACTER *)scopedstr.end();
4071 for (; psz < rangeScope.m_end; psz++)
4076 auto pszBlock2 = pszBlock;
4085 if (unicode_index_length(scopedstr2, len1) != unicode_index_length(scopedstrBlock2, len2))
4097 while (scopedstrBlock2 < pszBlockEnd);
4099 if (scopedstrBlock2 >= pszBlockEnd)
4113 ::unicode_increment(psz);
4123template <
typename ITERATOR_TYPE >
4124inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_find(
const SCOPED_STRING & scopedstr)
const RELEASENOTHROW
4129 auto rangeScope = *
this;
4131 if (this->_initialize_find(p, scopedstr, rangeScope))
4144 for (; psz < rangeScope.m_end; psz++)
4157 while (*psz2 !=
'\0' && *pszSub2 !=
'\0')
4160 if (unicode_to_lower_case(unicode_index_length(scopedstr2, len1)) !=
4161 unicode_to_lower_case(unicode_index_length(scopedstrSub2, len2)))
4179 if (*pszSub2 ==
'\0')
4219template <
typename ITERATOR_TYPE >
4220inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_rear_find(
const SCOPED_STRING & scopedstr)
const RELEASENOTHROW
4223 auto psz = (
const CHARACTER *)this->begin();
4225 auto pszEnd = (
const CHARACTER *)this->end();
4227 unicode_decrement(pszEnd, psz);
4229 auto pszBlock = (
const CHARACTER *)scopedstr.begin();
4231 auto pszBlockEnd = (
const CHARACTER *)scopedstr.end();
4233 unicode_decrement(scopedstrBlockEnd, pszBlock);
4235 if (::is_null(scopedstrBlockEnd))
4242 while(::is_set(pszEnd))
4247 const CHARACTER * pszSub2 = pszBlockEnd;
4254 if (unicode_index(scopedstrBlockEnd) != unicode_index(scopedstr2))
4261 pszSub2 = (
const CHARACTER *)unicode_decrement(scopedstrSub2, pszBlock);
4263 if (::is_null(scopedstrSub2))
4274 psz2 = (
const CHARACTER *)unicode_decrement(scopedstr2, psz);
4276 if (is_null(scopedstr2))
4289 pszEnd = (
const CHARACTER *)unicode_decrement(pszEnd, psz);
4302template <
typename ITERATOR_TYPE >
4303inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_rear_find(
const SCOPED_STRING & scopedstr)
const RELEASENOTHROW
4306 auto psz = (
const CHARACTER *)this->begin();
4308 auto pszEnd = (
const CHARACTER *)this->end();
4310 unicode_decrement(pszEnd, psz);
4312 auto pszBlock = (
const CHARACTER *)scopedstr.begin();
4314 auto pszBlockEnd = (
const CHARACTER *)scopedstr.end();
4316 unicode_decrement(scopedstrBlockEnd, pszBlock);
4318 if (::is_null(scopedstrBlockEnd))
4325 while (::is_set(pszEnd))
4330 const CHARACTER * pszSub2 = pszBlockEnd;
4337 if (unicode_to_lower_case(unicode_index(scopedstrBlockEnd)) != unicode_to_lower_case(unicode_index(scopedstr2)))
4344 pszSub2 = (
const CHARACTER *)unicode_decrement(scopedstrSub2, pszBlock);
4346 if (::is_null(scopedstrSub2))
4357 psz2 = (
const CHARACTER *)unicode_decrement(scopedstr2, psz);
4359 if (is_null(scopedstr2))
4372 pszEnd = (
const CHARACTER *)unicode_decrement(pszEnd, psz);
4647template <
typename ITERATOR_TYPE >
4648typename const_string_range < ITERATOR_TYPE >::CHARACTER const_string_range < ITERATOR_TYPE >::last_char(character_count count)
const
4651 return *(this->end() + count);
4679template <
typename ITERATOR_TYPE >
4680string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_upper()
4682 character_count nLength = size();
4683 CHARACTER * pszBuffer = get_buffer(nLength);
4684 string_uppercase(scopedstrBuffer, nLength + 1);
4685 release_buffer(nLength);
4691template <
typename ITERATOR_TYPE >
4692string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_lower()
4694 character_count nLength = size();
4695 CHARACTER * pszBuffer = get_buffer(nLength);
4696 string_lowercase(scopedstrBuffer, nLength + 1);
4697 release_buffer(nLength);
4703template <
typename ITERATOR_TYPE >
4704string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::MakeReverse()
4706 character_count nLength = size();
4707 CHARACTER * pszBuffer = get_buffer(nLength);
4708 string_reverse(scopedstrBuffer);
4709 release_buffer(nLength);
4717template <
typename ITERATOR_TYPE >
4718string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right()
4721 return trim_right(
" \t\r\n");
4772template <
typename ITERATOR_TYPE >
4773string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left()
4777 return trim_left(
" \t\r\n");
4844template <
typename ITERATOR_TYPE >
4845string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim()
4847 return(trim_right().trim_left());
4851template <
typename ITERATOR_TYPE >
4852string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(
CHARACTER chTarget)
4854 return(trim_right(chTarget).trim_left(chTarget));
4858template <
typename ITERATOR_TYPE >
4859string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(
const SCOPED_STRING & scopedstrTargets)
4861 return trim_right(scopedstrTargets).trim_left(scopedstrTargets);
4867template <
typename ITERATOR_TYPE >
4868string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(
CHARACTER chTarget)
4871 auto iterator = this->rear_skip(chTarget);
4919template <
typename ITERATOR_TYPE >
4920string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(
const SCOPED_STRING & scopedstrCharacters)
4925 auto p = this->rear_skip_any_character_in(scopedstrCharacters);
4927 if (p < this->end())
4982template <
typename ITERATOR_TYPE >
4983string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(
CHARACTER chTarget)
4986 auto p = this->skip(chTarget);
4988 if (::is_set(p) && p > this->begin())
5022template <
typename ITERATOR_TYPE >
5023string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(
const SCOPED_STRING & scopedstrCharacters)
5028 auto p = this->skip_any_character_in(scopedstrCharacters).begin();
5030 if (p > this->begin())
5033 this->erase_beginning(p);
5069template <
typename ITERATOR_TYPE >
5070string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed()
const
5073 string_base < ITERATOR_TYPE > scopedstr(*
this);
5075 scopedstr.trim_right();
5083template <
typename ITERATOR_TYPE >
5084string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed()
const
5087 string_base < ITERATOR_TYPE > scopedstr(*
this);
5089 scopedstr.trim_left();
5097template <
typename ITERATOR_TYPE >
5098string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed()
const
5101 string_base < ITERATOR_TYPE > scopedstr(*
this);
5111template <
typename ITERATOR_TYPE >
5112string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(
CHARACTER chTarget)
const
5115 string_base < ITERATOR_TYPE > scopedstr(*
this);
5117 scopedstr.trim(chTarget);
5125template <
typename ITERATOR_TYPE >
5126string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(
const SCOPED_STRING & scopedstrCharacters)
const
5129 auto scopedstr(*
this);
5131 scopedstr.trim(scopedstrCharacters);
5133 return ::transfer(scopedstr);
5141template <
typename ITERATOR_TYPE >
5142string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(
CHARACTER chTarget)
const
5145 auto scopedstr(*
this);
5147 scopedstr.trim_right(chTarget);
5149 return ::transfer(scopedstr);
5155template <
typename ITERATOR_TYPE >
5156string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(
const SCOPED_STRING & scopedstrCharacters)
const
5159 auto scopedstr(*
this);
5161 scopedstr.trim_right(scopedstrCharacters);
5163 return ::transfer(scopedstr);
5169template <
typename ITERATOR_TYPE >
5170string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(
CHARACTER chTarget)
const
5173 string_base < ITERATOR_TYPE > scopedstr(*
this);
5175 scopedstr.trim_left(chTarget);
5183template <
typename ITERATOR_TYPE >
5184string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(
const SCOPED_STRING & scopedstrCharacters)
const
5187 auto scopedstr(*
this);
5189 scopedstr.trim_left(scopedstrCharacters);
5191 return ::transfer(scopedstr);
5196template <
typename ITERATOR_TYPE >
5197const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(character_count start)
const
5200 return subrange(start, -1);
5205template <
typename ITERATOR_TYPE >
5206template < prototype_
integral START, prototype_
integral COUNT >
5207const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(START start, COUNT count)
const
5210 character_count length = this->size();
5218 else if ((::character_count)start >= length)
5225 character_count end;
5230 end = length + count + 1;
5236 end = start + count;
5247 if (end <= (::character_count)start)
5254 return { this->begin() + start, (::character_count)(end - start) };
5259template <
typename ITERATOR_TYPE >
5260string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::substr(character_count start)
const
5263 return substr(start, -1);
5268template <
typename ITERATOR_TYPE >
5269template < prototype_
integral START, prototype_
integral COUNT >
5270string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::substr(START start, COUNT count)
const
5273 character_count length = this->size();
5281 else if ((::character_count)start >= length)
5288 character_count end;
5293 end = length + count + 1;
5299 end = start + count;
5310 if (end <= (::character_count) start)
5317 return { this->begin() + start, (::character_count) (end - start) };
5322template <
typename ITERATOR_TYPE >
5323void string_base < ITERATOR_TYPE >::clear()
5331template <
typename ITERATOR_TYPE >
5332string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right(character_count count)
const
5342 character_count nLength = size();
5344 if (count >= nLength)
5351 return(string_base < ITERATOR_TYPE >(this->begin() + nLength - count, count));
5357template <
typename ITERATOR_TYPE >
5358string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left(character_count count)
const
5369 character_count nLength = size();
5371 if (count >= nLength)
5378 return(string_base < ITERATOR_TYPE >(this->begin(), count));
5384template <
typename ITERATOR_TYPE >
5385string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_including_any_character_in(
const SCOPED_STRING & scopedstrCharacters)
const
5388 auto p = this->skip_any_character_in(scopedstrCharacters);
5399 return { p.begin(), this->end() - p.begin()};
5407template <
typename ITERATOR_TYPE >
5408string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_skipping_any_character_in(
const SCOPED_STRING & scopedstrCharacters)
const
5411 auto p = this->skip_any_character_in(scopedstrCharacters);
5422 return { p.begin(), this->end() - p.begin()};
5429template <
typename ITERATOR_TYPE >
5430string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf_arguments(
const CHARACTER * pszFormat, va_list args)
5433 ASSERT(is_string_ok(scopedstrFormat));
5435 character_count nCurrentLength = this->size();
5437 va_list argsForCount;
5439 va_copy(argsForCount, args);
5441 character_count nAppendLength = get_formatted_length(scopedstrFormat, argsForCount);
5443 va_end(argsForCount);
5445 CHARACTER * pszBuffer = get_buffer(nCurrentLength + nAppendLength,
true);
5447 _string_format(scopedstrBuffer + nCurrentLength, nAppendLength + 1, pszFormat, args);
5449 release_buffer(nCurrentLength + nAppendLength);
5456template <
typename ITERATOR_TYPE >
5457string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf_arguments(
const CHARACTER * pszFormat, va_list args)
5460 ASSERT(is_string_ok(scopedstrFormat));
5462 if (scopedstrFormat ==
nullptr)
5465 throw_exception(error_bad_argument);
5471 va_copy(ptr1, args);
5473 character_count nLength = get_formatted_length(scopedstrFormat, ptr1);
5477 CHARACTER * pszBuffer = get_buffer(nLength);
5481 va_copy(ptr2, args);
5483 _string_format(scopedstrBuffer, nLength + 1, pszFormat, ptr2);
5487 release_buffer(nLength);
5537template <
typename ITERATOR_TYPE >
5538string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf(
const CHARACTER * pszFormat, ...)
5541 ASSERT(is_string_ok(scopedstrFormat));
5545 va_start(argList, pszFormat);
5547 formatf_arguments(scopedstrFormat, argList);
5557template <
typename ITERATOR_TYPE >
5558string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf(
const CHARACTER * pszFormat, ...)
5561 ASSERT(is_string_ok(scopedstrFormat));
5565 va_start(argList, pszFormat);
5567 append_formatf_arguments(scopedstrFormat, argList);
5576template <
typename ITERATOR_TYPE >
5577void string_base < ITERATOR_TYPE >::reserve(character_count res_arg)
5579 get_buffer(res_arg + 1);
5585template <
typename ITERATOR_TYPE >
5586string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::uppered()
const
5589 return string_base < ITERATOR_TYPE >(*this).make_upper();
5595template <
typename ITERATOR_TYPE >
5596string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::reversed()
const
5599 return string_base < ITERATOR_TYPE >(*this).MakeReverse();
5604template <
typename ITERATOR_TYPE >
5605string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst)
const
5608 return unichar_substr(iFirst, -1);
5613template <
typename ITERATOR_TYPE >
5614string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst, character_count count)
const
5619 if (pchStart ==
nullptr)
5622 ::collection::count iUtf8Len = this->unichar_count();
5625 iFirst = iUtf8Len + iFirst;
5628 count = iUtf8Len - iFirst + count + 1;
5630 if (iFirst + count > iUtf8Len)
5631 count = iUtf8Len - iFirst;
5636 ::collection::count ca = 0;
5638 while (ca < iFirst && *pchStart !=
'\0')
5641 pchStart = unicode_increment(pchStart);
5647 if (*pchStart ==
'\0')
5654 while (ca < count && *pchEnd !=
'\0')
5657 pchEnd = unicode_increment(pchEnd);
5663 return string_base < ITERATOR_TYPE >(pchStart, pchEnd - pchStart);
5693template <
typename ITERATOR_TYPE >
5694inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unichar_at(character_count iUnicharIndex)
const
5697 auto p = this->begin();
5699 while (p < this->end() && iUnicharIndex > 0)
5702 auto iLen = unicode_len(p);
5714template <
typename ITERATOR_TYPE >
5715bool string_base < ITERATOR_TYPE >::eat_before(string_base < ITERATOR_TYPE > & strBefore,
const SCOPED_STRING & scopedstrSeparator,
bool bEatEverythingIfNotFound)
5718 ASSERT(
this != &strBefore);
5720 if (
this == &strBefore)
5727 auto pFind = this->find(scopedstrSeparator);
5729 if (::is_null(pFind))
5732 if (bEatEverythingIfNotFound)
5745 strBefore = (*this)(0, pFind);
5747 *
this = (*this)(pFind + scopedstrSeparator.size());
5755template <
typename ITERATOR_TYPE >
5756bool string_base < ITERATOR_TYPE >::eat_before_let_separator(string_base < ITERATOR_TYPE > & strBefore,
const SCOPED_STRING & scopedstrSeparator,
bool bEatEverythingIfNotFound)
5759 ASSERT(
this != &strBefore);
5761 if (
this == &strBefore)
5768 auto pFind = this->find(scopedstrSeparator);
5770 if (::is_null(pFind))
5773 if (bEatEverythingIfNotFound)
5778 *
this = scopedstrSeparator;
5786 strBefore = (*this)(0, pFind);
5788 *
this = (*this)(pFind);
5795template <
typename ITERATOR_TYPE >
5796void string_base < ITERATOR_TYPE >::add(
CHARACTER ch)
5865template <
typename ITERATOR_TYPE >
5866inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_begins(
const SCOPED_STRING & scopedstr)
const
5869 return this->begins(scopedstr, ::comparison::case_insensitive < CHARACTER >());
5875template <
typename ITERATOR_TYPE >
5876inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_ends(
const SCOPED_STRING & scopedstr)
const
5879 return this->ends(scopedstr, ::comparison::case_insensitive < CHARACTER >());
5884template <
typename ITERATOR_TYPE >
5885inline bool string_base < ITERATOR_TYPE > ::begins_eat(
const SCOPED_STRING & scopedstrPrefix)
5888 if (!this->begins(scopedstrPrefix))
5895 assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
5902template <
typename ITERATOR_TYPE >
5903inline bool string_base < ITERATOR_TYPE > ::ends_eat(
const SCOPED_STRING & scopedstrSuffix)
5906 if (!this->ends(scopedstrSuffix))
5913 assign(this->begin(), size() - scopedstrSuffix.size());
5920template <
typename ITERATOR_TYPE >
5921inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eat(
const SCOPED_STRING & scopedstrPrefix)
5924 if (!this->case_insensitive_begins(scopedstrPrefix))
5931 assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
5938template <
typename ITERATOR_TYPE >
5939inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eat(
const SCOPED_STRING & scopedstrSuffix)
5942 if (!this->case_insensitive_ends(scopedstrSuffix))
5949 assign(this->begin(), size() - scopedstrSuffix.size());
5956template <
typename ITERATOR_TYPE >
5957inline bool string_base < ITERATOR_TYPE > ::begins_replace(
const SCOPED_STRING & scopedstrNewPrefix,
const SCOPED_STRING & scopedstrPrefix)
5960 if(!begins_eat(scopedstrPrefix))
5967 *
this = scopedstrNewPrefix + *
this;
5974template <
typename ITERATOR_TYPE >
5975inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_replace(
const SCOPED_STRING & scopedstrNewPrefix,
const SCOPED_STRING & scopedstrPrefix)
5978 if(!this->case_insensitive_begins_eat(scopedstrPrefix))
5985 *
this = scopedstrNewPrefix + *
this;
5992template <
typename ITERATOR_TYPE >
5993inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_prefix(
const SCOPED_STRING & scopedstrPrefix)
5996 if (!this->begins(scopedstrPrefix))
5999 operator =(scopedstrPrefix + *
this);
6008template <
typename ITERATOR_TYPE >
6009inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_prefix(
const SCOPED_STRING & scopedstrPrefix)
6012 if (!this->case_insensitive_begins(scopedstrPrefix))
6015 operator =(scopedstrPrefix + *
this);
6024template <
typename ITERATOR_TYPE >
6025inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_suffix(
const SCOPED_STRING & scopedstrSuffix)
6028 if (!this->ends(scopedstrSuffix))
6031 operator =(*
this + scopedstrSuffix);
6040template <
typename ITERATOR_TYPE >
6041inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_suffix(
const SCOPED_STRING & scopedstrSuffix)
6044 if (!this->case_insensitive_ends(scopedstrSuffix))
6047 operator =(*
this + scopedstrSuffix);
6057template <
typename ITERATOR_TYPE >
6058inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_prefixed(
const SCOPED_STRING & scopedstrPrefix)
const
6061 if (!this->begins(scopedstrPrefix))
6064 return scopedstrPrefix + *
this;
6073template <
typename ITERATOR_TYPE >
6074inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_prefixed(
const SCOPED_STRING & scopedstrPrefix)
const
6077 if (!this->case_insensitive_begins(scopedstrPrefix))
6080 return scopedstrPrefix + *
this;
6089template <
typename ITERATOR_TYPE >
6090inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_suffixed(
const SCOPED_STRING & scopedstrSuffix)
const
6093 if (!this->ends(scopedstrSuffix))
6096 return *
this + scopedstrSuffix;
6105template <
typename ITERATOR_TYPE >
6106inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_suffixed(
const SCOPED_STRING & scopedstrSuffix)
const
6109 if (!this->case_insensitive_ends(scopedstrSuffix))
6112 return *
this + scopedstrSuffix;
6307template <
typename ITERATOR_TYPE >
6308inline bool string_base < ITERATOR_TYPE > ::begins_bitten(
string_base & strBitten,
const SCOPED_STRING & scopedstrPrefix)
const
6311 if (!this->begins(scopedstrPrefix))
6318 strBitten.assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
6325template <
typename ITERATOR_TYPE >
6326inline bool string_base < ITERATOR_TYPE > ::ends_bitten(
string_base & strBitten,
const SCOPED_STRING & scopedstrSuffix)
const
6329 if (!this->ends(scopedstrSuffix))
6336 strBitten.assign(this->begin(), size() - scopedstrSuffix.size());
6343template <
typename ITERATOR_TYPE >
6344inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_bitten(
string_base & strBitten,
const SCOPED_STRING & scopedstrPrefix)
const
6347 if (!this->case_insensitive_begins(scopedstrPrefix))
6354 strBitten.assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
6361template <
typename ITERATOR_TYPE >
6362inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_bitten(
string_base & strBitten,
const SCOPED_STRING & scopedstrSuffix)
const
6365 if (!this->case_insensitive_ends(scopedstrSuffix))
6372 strBitten.assign(this->begin(), size() - scopedstrSuffix.size());
6379template <
typename ITERATOR_TYPE >
6380inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::begins_bitten(
const SCOPED_STRING & scopedstrPrefix)
const
6383 if (!this->begins(scopedstrPrefix))
6390 return { this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size() };
6395template <
typename ITERATOR_TYPE >
6396inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::ends_bitten(
const SCOPED_STRING & scopedstrSuffix)
const
6399 if (!this->ends(scopedstrSuffix))
6406 return { this->begin(), size() - scopedstrSuffix.size()};
6411template <
typename ITERATOR_TYPE >
6412inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_bitten(
const SCOPED_STRING & scopedstrPrefix)
const
6415 if (!this->case_insensitive_begins(scopedstrPrefix))
6422 return { this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size()};
6427template <
typename ITERATOR_TYPE >
6428inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_bitten(
const SCOPED_STRING & scopedstrSuffix)
const
6431 if (!this->case_insensitive_ends(scopedstrSuffix))
6438 return { this->begin(), size() - scopedstrSuffix.size()};
6444template <
typename ITERATOR_TYPE >
6445inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eaten(
string_base & strEaten,
const SCOPED_STRING & scopedstrPrefix)
const
6448 if (!this->case_insensitive_begins(scopedstrPrefix))
6455 strEaten.assign(this->begin(), scopedstrPrefix.size());
6462template <
typename ITERATOR_TYPE >
6463inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eaten(
string_base & strEaten,
const SCOPED_STRING & scopedstrSuffix)
const
6466 if (!this->case_insensitive_ends(scopedstrSuffix))
6473 strEaten.assign(this->begin() + length() - scopedstrSuffix.size(), scopedstrSuffix.size());
6480template <
typename ITERATOR_TYPE >
6481inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_eaten(
const SCOPED_STRING & scopedstrPrefix)
const
6484 if (!this->case_insensitive_begins(scopedstrPrefix))
6491 return { this->begin(), scopedstrPrefix.size() };
6496template <
typename ITERATOR_TYPE >
6497inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_eaten(
const SCOPED_STRING & scopedstrSuffix)
const
6500 if (!this->case_insensitive_ends(scopedstrSuffix))
6507 return { this->begin() + length() - scopedstrSuffix.size(), scopedstrSuffix.size() };
6512template <
typename ITERATOR_TYPE >
6514template <
typename EQUALITY >
6515inline ::collection::count string_base < ITERATOR_TYPE > ::_replace_with(
const SCOPED_STRING & scopedstrNew,
const SCOPED_STRING & scopedstrOld, character_count start, EQUALITY equality)
6519 character_count nReplacedLen = scopedstrOld.size();
6521 if (nReplacedLen == 0)
6529 character_count nReplacementLen = scopedstrNew.size();
6532 auto count = (*this)(start)._occurrence_count_of(scopedstrOld, equality);
6545 character_count nNewLength = this->size() + (nReplacementLen - nReplacedLen) * count;
6547 string_base < ITERATOR_TYPE > str;
6549 CHARACTER * pszBuffer = str.get_buffer(nNewLength);
6553 RANGE rangeOld = *
this;
6555 memory_copy(pLastNewEnd, rangeOld.begin(), start *
sizeof(
CHARACTER));
6557 rangeOld.begin() += start;
6559 pLastNewEnd += start;
6563 while ((scopedstrTarget = (
CHARACTER *)rangeOld.find(scopedstrOld, equality)) !=
nullptr)
6566 auto offset = pszTarget - rangeOld.begin();
6568 memory_copy(pLastNewEnd,rangeOld.begin(), offset *
sizeof(
CHARACTER));
6570 pLastNewEnd += offset;
6572 memory_copy(pLastNewEnd, scopedstrNew.begin(), nReplacementLen *
sizeof(
CHARACTER));
6574 rangeOld.m_begin = pszTarget + nReplacedLen;
6576 pLastNewEnd += nReplacementLen;
6580 memory_copy(pLastNewEnd,rangeOld.begin(), (rangeOld.end() - rangeOld.begin()) *
sizeof(
CHARACTER));
6582 str.release_buffer(nNewLength);
6584 *
this = ::transfer(str);
6674template < prototype_
character CHARACTER >
6675void CopyCharsOverlapped(
CHARACTER * pchDest,
const CHARACTER * pchSrc, character_count nChars)
noexcept
6678 memory_transfer(pchDest, pchSrc, nChars *
sizeof(
CHARACTER));
6683template < prototype_
character CHARACTER >
6684void CopyCharsOverlapped(
CHARACTER * pchDest,
size_t nDestLen,
const CHARACTER * pchSrc, character_count nChars)
noexcept
6687 memory_transfer(pchDest, pchSrc, nChars *
sizeof(
CHARACTER));
6693template <
typename STRING >
6694inline STRING & string_concatenate(STRING & scopedstr,
const typename STRING::CHARACTER * psz1, character_count nLength1,
const typename STRING::CHARACTER * psz2, character_count nLength2)
6697 character_count nNewLength = nLength1 + nLength2;
6699 typename STRING::CHARACTER * pszBuffer = scopedstr.get_buffer(nNewLength);
6701 string_count_copy(scopedstrBuffer, psz1, nLength1);
6703 string_count_copy(scopedstrBuffer + nLength1, psz2, nLength2);
6705 scopedstr.release_buffer(nNewLength);
6712template <
typename STRING >
6713inline bool string_ends_eat(STRING & ansistr,
const STRING & scopedstrSuffix)
6716 auto lenSuffix = scopedstrSuffix.length();
6718 if (lenSuffix > ansistr.length())
6725 if (STRING::string_count_compare(ansistr.reverse_ptr_at(lenSuffix), scopedstrSuffix, lenSuffix) != 0)
6732 ansistr.reverse_truncate(lenSuffix);
6799::i32 get_mem_free_available_kb();
6802template < prototype_
character CHARACTER >
6803::wd32_character unicode_iterator < CHARACTER > ::operator *() {
return unicode_index(m_psz); }
6806template < prototype_
character CHARACTER >
6807unicode_iterator < CHARACTER > & unicode_iterator < CHARACTER > ::operator ++()
6810 unicode_increment(m_psz);
6817template < prototype_
character CHARACTER >
6818unicode_iterator < CHARACTER > unicode_iterator < CHARACTER > ::operator ++(::i32)
6823 unicode_increment(m_psz);
6831template <
typename ITERATOR_TYPE >
6832inline string_base < ITERATOR_TYPE > operator +(
const scoped_string_base < ITERATOR_TYPE > & scopedstr,
const inline_number_string & inlinenumberstring)
6835 string_base < ITERATOR_TYPE > str(scopedstr);
6837 string_base < ITERATOR_TYPE > strNumber(inlinenumberstring);
6839 str.append(strNumber);
6841 return ::transfer(scopedstr);
6845template <
character_count n >
6846inline const_string_range_static_array < const_char_pointer ,2 > operator +(const ::i8 (&s)[n],
const inline_number_string& inlinenumberstring)
6849 return { ::as_string_literal<::i8, n>(s), inlinenumberstring };
6904template <
typename ITERATOR_TYPE >
6905inline string_base < ITERATOR_TYPE >::string_base(const ::atom&
atom) :
6913template <
typename ITERATOR_TYPE >
6914string_base < ITERATOR_TYPE >::string_base(const ::payload &
payload) :
6922template <
typename ITERATOR_TYPE >
6923inline string_base < ITERATOR_TYPE >::string_base(
const property &
property) :
6936template <
typename ITERATOR_TYPE >
6937inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (
const scoped_ansi_string & ansistr) { assign_range(ansistr);
return *
this; }
6939template <
typename ITERATOR_TYPE >
6940inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (
const scoped_wd16_string & wd16str) { assign_range(wd16str);
return *
this; }
6942template <
typename ITERATOR_TYPE >
6943inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (
const scoped_wd32_string & wd32str) { assign_range(wd32str);
return *
this; }
Definition _template_after_initial_concepts.h:15
const_iterator find_first(CHARACTER chSeparator, ::character_count start=0) const RELEASENOTHROW
character_count _find_first_character_in(const CHARACTER * blockCharacters, character_count iStart = ...
Definition _impl_string_base.h:2856
const_iterator unicode_find(const SCOPED_STRING &scopedstr) const RELEASENOTHROW
Find the first occurrence of scopedstr, starting at start position and up to count characters from st...
Definition _impl_string_base.h:2867
Definition string_base.h:90
void construct2(const ::character_range< const CHARACTER * > &range)
Definition _impl_string_base.h:438
Definition std_iterator.h:49