681template <
typename ITERATOR_TYPE >
682inline character_count const_string_range < ITERATOR_TYPE >::unichar_count()
const
685 return ::unichar_count(this->begin());
1279template <
typename ITERATOR_TYPE >
1280inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_left(character_count count)
const
1283 return { this->begin(), this->unichar_at(count) };
1289template <
typename ITERATOR_TYPE >
1290inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iFirst)
const
1293 return { this->unichar_at(iFirst), this->end() };
1298template <
typename ITERATOR_TYPE >
1299inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iStart, character_count iCount)
const
1302 return { this->unichar_at(iStart), this->unichar_at(iStart + iCount) };
1307template < prototype_
character CHARACTER >
1308inline bool operator>(
const CHARACTER * psz,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1311 return string_compare(scopedstr, string_safe_length(scopedstr), scopedstr.begin(), scopedstr.size()) > 0;
1316template < prototype_
character CHARACTER >
1317inline bool operator > (
CHARACTER ch,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1320 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) > 0;
1325template < prototype_
character CHARACTER >
1326inline bool operator > (::wide_character ch,
const typename ::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1329 return wide_string(ch) > scopedstr;
1334template < prototype_
character CHARACTER >
1335inline bool operator>(::i32 i,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1338 return ::string_base<CHARACTER>(i) > scopedstr;
1343template < prototype_
character CHARACTER >
1344inline bool operator<(
const CHARACTER * psz,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1347 return string_compare(scopedstr, string_save_length(scopedstr), scopedstr.begin(), scopedstr.size()) < 0;
1352template < prototype_
character CHARACTER >
1353inline bool operator<(
CHARACTER ch,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1356 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) < 0;
1361template < prototype_
character CHARACTER >
1362inline bool operator<(::i32 i,
const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1365 return ::string_base <CHARACTER>(i) < scopedstr;
1370template <
typename ITERATOR_TYPE >
1371inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::lower()
const
1374 return string_base < ITERATOR_TYPE >(*this).make_lower();
1379template <
typename ITERATOR_TYPE >
1380inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::upper()
const
1383 return string_base < ITERATOR_TYPE >(*this).make_upper();
1388template < prototype_
character CHARACTER >
1389inline const CHARACTER * FormatArgument(
const typename GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
noexcept
1392 return scopedstr.begin();
1457template <
typename ITERATOR_TYPE >
1458template < prototype_array A_STRING_ARRAY >
1459bool const_string_range < ITERATOR_TYPE >::contains_any(
const A_STRING_ARRAY & stra)
const
1462 for (
auto & scopedstr : stra)
1465 if (contains(scopedstr))
1479template <
typename ITERATOR_TYPE >
1480template < prototype_array A_STRING_ARRAY >
1481bool const_string_range < ITERATOR_TYPE >::contains_all(
const A_STRING_ARRAY & stra)
const
1484 for (
auto & scopedstr : stra)
1487 if (!contains(scopedstr))
1503template <
typename ITERATOR_TYPE >
1504template < prototype_array A_STRING_ARRAY >
1505bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_at_least_one_of(
const A_STRING_ARRAY & stra)
const
1508 for (
auto & scopedstr : stra)
1511 if (case_insensitive_contains(scopedstr))
1525template <
typename ITERATOR_TYPE >
1526template < prototype_array A_STRING_ARRAY >
1527bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_all(
const A_STRING_ARRAY & stra)
const
1530 for (
auto & scopedstr : stra)
1533 if (!case_insensitive_contains(scopedstr))
1547template <
typename ITERATOR_TYPE >
1548template < prototype_array A_STRING_ARRAY >
1549bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_at_least_one_of(
const A_STRING_ARRAY & stra)
const
1552 for (
auto & scopedstr : stra)
1555 if (unicode_case_insensitive_contains(scopedstr))
1569template <
typename ITERATOR_TYPE >
1570template < prototype_array A_STRING_ARRAY >
1571bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_all(
const A_STRING_ARRAY & stra)
const
1574 for (
auto & scopedstr : stra)
1577 if (!unicode_case_insensitive_contains(scopedstr))
1592template <
typename ITERATOR_TYPE >
1593string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::Tokenize(
const SCOPED_STRING & scopedstrTokens, character_count & start)
const
1598 throw_exception(error_bad_argument);
1600 if (scopedstrTokens.is_empty())
1602 if (start < this->size())
1604 return(string_base < ITERATOR_TYPE >(this->begin() + start));
1609 const CHARACTER * pszPlace = this->begin() + start;
1610 const CHARACTER * pszEnd = this->begin() + this->size();
1611 if (pszPlace < pszEnd)
1613 character_count nIncluding = string_skip_any_character_in(pszPlace,
1616 if ((pszPlace + nIncluding) < pszEnd)
1618 pszPlace += nIncluding;
1619 character_count nExcluding = string_find_first_character_in(pszPlace, scopedstrTokens);
1621 character_count iFrom = start + nIncluding;
1622 character_count nUntil = nExcluding;
1623 start = iFrom + nUntil + 1;
1625 return this->substr(iFrom, nUntil);
1636 return(string_base < ITERATOR_TYPE >());
1643template <
typename ITERATOR_TYPE >
1644string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::intersection(
const SCOPED_STRING & scopedstrFind)
const
1647 string_base < ITERATOR_TYPE > scopedstr;
1649 for (character_count i = 0; i < this->size(); i++)
1652 auto ch = this->operator[](i);
1654 if (scopedstrFind.contains(ch))
1669template <
typename ITERATOR_TYPE >
1670inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::concatenate_with_separator(
const SCOPED_STRING & scopedstrSeparator,
const SCOPED_STRING & scopedstr)
1673 if (this->has_character())
1676 if (scopedstr.has_character())
1679 this->append(scopedstrSeparator + scopedstr);
1684 else if (scopedstr.has_character())
1687 this->assign(scopedstr);
1697template <
typename ITERATOR_TYPE >
1698inline void string_base < ITERATOR_TYPE >::get_string(
CHARACTER * psz)
const noexcept
1701 string_count_copy(psz, this->begin(), this->length());
1706template <
typename ITERATOR_TYPE >
1707string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::release_buffer(character_count characterCount)
1710 if (characterCount < 0)
1713 characterCount = string_safe_length(this->begin()) + characterCount + 1;
1719 this->m_end = this->m_begin + characterCount;
1740template <
typename ITERATOR_TYPE >
1741void string_base < ITERATOR_TYPE >::resize(character_count n,
CHARACTER c)
1744 character_count nOldSize = this->length();
1755 auto psz = this->get_buffer<true>(n);
1757 flood_characters(psz + nOldSize, c, n - nOldSize);
1759 this->release_buffer(n);
1766template <
typename ITERATOR_TYPE >
1767inline typename string_base < ITERATOR_TYPE >::this_iterator string_base < ITERATOR_TYPE >::truncate_on_find_character(
CHARACTER ch)
1770 auto p = this->find_first_character(ch);
1784template <
typename ITERATOR_TYPE >
1785inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::truncate(this_iterator p)
1788 if(p <= this->begin())
1794 else if(p < this->end())
1797 auto pbasedata = this->m_pbasedata;
1799 if (pbasedata->base_data_is_shared())
1802 this->assign(this->m_begin, p);
1808 auto characterCount = p - this->begin();
1812 this->m_end = this->m_begin + characterCount;
1825template <
typename ITERATOR_TYPE >
1826inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::erase_beginning(this_iterator p)
1831 assign(p, this->m_end - p);
1833 return this->m_begin;
1839template <
typename ITERATOR_TYPE >
1840inline void string_base < ITERATOR_TYPE >::set_at(character_count iChar,
CHARACTER ch)
1843 defer_set_size<true>(maximum(this->size(), iChar + 1));
1861 ((
CHARACTER *)this->m_begin)[iChar] = ch;
1865template <
typename ITERATOR_TYPE >
1866bool const_string_range < ITERATOR_TYPE >::contains(
const SCOPED_STRING & scopedstr)
const
1869 return ::is_set(find(scopedstr));
1874template <
typename ITERATOR_TYPE >
1875bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(
const SCOPED_STRING & scopedstr)
const
1878 return ::is_set(case_insensitive_find(scopedstr));
2082template <
typename ITERATOR_TYPE >
2083bool const_string_range < ITERATOR_TYPE >::contains(
const SCOPED_STRING & scopedstr,
const CHARACTER ** ppszBeg,
const CHARACTER ** ppszEnd)
const
2086 auto pFind = this->find(scopedstr);
2088 if (::is_null(pFind))
2095 if (::is_set(ppszBeg))
2102 if (::is_set(ppszEnd))
2105 *ppszEnd = pFind + scopedstr.size();
2114template <
typename ITERATOR_TYPE >
2115bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(
const SCOPED_STRING & scopedstr,
const CHARACTER ** ppszBeg,
const CHARACTER ** ppszEnd)
const
2118 auto pFind = this->case_insensitive_find(scopedstr);
2120 if (::is_null(pFind))
2127 if (::is_set(ppszBeg))
2134 if (::is_set(ppszEnd))
2137 *ppszEnd = pFind + scopedstr.size();
2146template <
typename ITERATOR_TYPE >
2147bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(
const SCOPED_STRING & scopedstr,
const CHARACTER ** ppszBeg,
const CHARACTER ** ppszEnd)
const
2150 auto pFind = this->unicode_case_insensitive_find(scopedstr);
2152 if (::is_null(pFind))
2159 if (::is_set(ppszBeg))
2166 if (::is_set(ppszEnd))
2169 *ppszEnd = pFind + scopedstr.size();
2294template <
typename ITERATOR_TYPE >
2295bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(
const SCOPED_STRING & scopedstr)
const
2298 return ::is_set(unicode_case_insensitive_find(scopedstr));
2337template <
typename ITERATOR_TYPE >
2338string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::index_erase(character_count iIndex, character_count count)
2341 character_count nLength = this->size();
2357 if (count + iIndex > nLength)
2360 count = nLength - iIndex;
2371 if (count + iIndex > nLength)
2374 count = nLength - iIndex;
2381 character_count nNewLength = nLength - count;
2383 character_count nCopy = nLength - (iIndex + count) + 1;
2385 CHARACTER * pszBuffer = get_buffer<true>();
2387 memory_transfer(pszBuffer + iIndex, pszBuffer + iIndex + count, (
size_t)nCopy);
2389 release_buffer(nNewLength);
2398template <
typename ITERATOR_TYPE >
2399inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i,
CHARACTER ch)
2409 if (i > this->size())
2416 character_count nNewLength = this->size() + 1;
2418 CHARACTER * pszBuffer = get_buffer<true>(nNewLength);
2420 memory_transfer(pszBuffer + i + 1, pszBuffer + i, nNewLength - i);
2424 release_buffer(nNewLength);
2431template <
typename ITERATOR_TYPE >
2432inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i,
const string_base & str)
2442 if (i > this->size())
2449 character_count nInsertLength = str.size();
2451 character_count nNewLength = this->size();
2453 if (nInsertLength > 0)
2456 nNewLength += nInsertLength;
2458 CHARACTER * pszBuffer = get_buffer<true>(nNewLength);
2460 memory_transfer(pszBuffer + i + nInsertLength, pszBuffer + i, (nNewLength - i - nInsertLength + 1) *
sizeof(
CHARACTER));
2462 memory_copy(pszBuffer + i, str.begin(), nInsertLength *
sizeof(
CHARACTER));
2464 release_buffer(nNewLength);
2473template <
typename ITERATOR_TYPE >
2474inline ::collection::count string_base < ITERATOR_TYPE >::replace_with(
CHARACTER charNew,
CHARACTER charOld, character_count start)
2477 character_count count = 0;
2480 if (charOld != charNew)
2483 bool bCopied =
false;
2486 character_count nLength = this->size();
2487 character_count iChar = 0;
2488 while (iChar < nLength)
2491 if (pszBuffer[iChar] == charOld)
2496 pszBuffer = get_buffer<true>(nLength);
2498 pszBuffer[iChar] = charNew;
2501 iChar = character_count((pszBuffer + iChar + 1) - pszBuffer);
2505 release_buffer(nLength);
2514template <
typename ITERATOR_TYPE >
2516::collection::count string_base < ITERATOR_TYPE >::replace_with_count(
const SCOPED_STRING & scopedstrNew,
const SCOPED_STRING & scopedstrOld, character_count start)
2521 ::collection::count c = 0;
2524 character_count nSourceLen = scopedstrOld.size();
2525 if (nSourceLen == 0)
2528 character_count nReplacementLen = scopedstrNew.size();
2531 character_count count = 0;
2535 const CHARACTER * pszStart = this->begin() + start;
2539 while ((pszTarget = string_find_string(pszStart, scopedstrOld)) !=
nullptr)
2544 pszStart = pszTarget + nSourceLen;
2557 character_count nOldLength = this->size();
2558 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
2560 CHARACTER * pszBuffer = get_buffer<true>(maximum(nNewLength, nOldLength));
2562 const CHARACTER * pszStart = pszBuffer + start;
2563 const CHARACTER * pszEnd = pszBuffer + nOldLength;
2566 while (pszStart < pszEnd)
2571 while ((pszTarget = (
CHARACTER *)string_find_string(pszStart, scopedstrOld)) !=
nullptr)
2574 character_count nBalance = nOldLength - character_count(pszTarget - pszBuffer + nSourceLen);
2576 memory_transfer((
void *)(pszTarget + nReplacementLen), pszTarget + nSourceLen, nBalance *
sizeof(
CHARACTER));
2578 ::memory_copy((
void *)pszTarget, scopedstrNew, nReplacementLen *
sizeof(
CHARACTER));
2580 pszStart = pszTarget + nReplacementLen;
2582 pszTarget[nReplacementLen + nBalance] = 0;
2584 nOldLength += (nReplacementLen - nSourceLen);
2588 pszStart += string_safe_length(pszStart) + 1;
2592 ASSERT(pszBuffer[nNewLength] == 0);
2594 release_buffer(nNewLength);
2603template <
typename ITERATOR_TYPE >
2605::collection::count string_base < ITERATOR_TYPE >::replace_with_ci_count(
const SCOPED_STRING & scopedstrNew,
const SCOPED_STRING & scopedstrOld, character_count start)
2610 ::collection::count c = 0;
2613 character_count nSourceLen = scopedstrOld.size();
2614 if (nSourceLen == 0)
2617 character_count nReplacementLen = scopedstrOld.size();
2620 character_count count = 0;
2622 const CHARACTER * pszStart = this->begin() + start;
2625 while ((pszTarget = case_insensitive_string_find_string(pszStart, scopedstrOld)) !=
nullptr)
2628 pszStart = pszTarget + nSourceLen;
2638 character_count nOldLength = this->size();
2639 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
2641 CHARACTER * pszBuffer = get_buffer<true>(maximum(nNewLength, nOldLength));
2643 CHARACTER * pszStart = pszBuffer + start;
2644 CHARACTER * pszEnd = pszBuffer + nOldLength;
2647 while (pszStart < pszEnd)
2652 while ((pszTarget = (
CHARACTER *)case_insensitive_string_find_string(pszStart, scopedstrOld)) !=
nullptr)
2655 character_count nBalance = nOldLength - character_count(pszTarget - pszBuffer + nSourceLen);
2657 memory_transfer(pszTarget + nReplacementLen, pszTarget + nSourceLen, nBalance *
sizeof(
CHARACTER));
2659 ::memory_copy(pszTarget, scopedstrNew, nReplacementLen *
sizeof(
CHARACTER));
2661 pszStart = pszTarget + nReplacementLen;
2663 pszTarget[nReplacementLen + nBalance] = 0;
2665 nOldLength += (nReplacementLen - nSourceLen);
2669 pszStart += string_safe_length(pszStart) + 1;
2673 ASSERT(pszBuffer[nNewLength] == 0);
2675 release_buffer(nNewLength);
2684template <
typename ITERATOR_TYPE >
2685string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::replace(const_iterator pszStart, const_iterator pszEnd,
const SCOPED_STRING & scopedstr)
2688 auto finalLen = this->size() + scopedstr.size() - (pszEnd - pszStart);
2692 auto psz = str.get_buffer(finalLen);
2694 memory_copy(psz, this->begin(), pszStart - this->begin());
2696 memory_copy(psz + (pszStart - this->begin()), scopedstr.begin(), scopedstr.size());
2698 memory_copy(psz + (pszStart - this->begin()) + scopedstr.size(), pszEnd, this->end() - pszEnd);
2700 str.release_buffer(finalLen);
2702 *
this = ::transfer(str);
2709template <
typename ITERATOR_TYPE >
2710inline ::collection::count string_base < ITERATOR_TYPE >::erase_character(
CHARACTER chRemove)
2713 character_count nLength = this->size();
2715 CHARACTER * pszBuffer = get_buffer<true>(nLength);
2721 CHARACTER * pszEnd = pszBuffer + nLength;
2723 while (pszSource < pszEnd)
2725 CHARACTER * pszNewSource = pszSource + 1;
2726 if (*pszSource != chRemove)
2730 size_t NewSourceGap = (pszNewSource - pszSource);
2731 CHARACTER * pszNewDest = pszDest + NewSourceGap;
2733 for (i = 0; pszDest != pszNewDest && i < NewSourceGap; i++)
2735 *pszDest = *pszSource;
2740 pszSource = pszNewSource;
2743 character_count count = character_count(pszSource - pszDest);
2744 release_buffer(nLength - count);
2751template <
typename ITERATOR_TYPE >
2752inline ::collection::count string_base < ITERATOR_TYPE >::erase_any_character_in(
const SCOPED_STRING & scopedstrCharacters)
2755 character_count nLength = this->size();
2757 CHARACTER * pszBuffer = get_buffer<true>(nLength);
2763 CHARACTER * pszEnd = pszBuffer + nLength;
2765 while (pszSource < pszEnd)
2767 CHARACTER * pszNewSource = pszSource + 1;
2768 if (!scopedstrCharacters.contains(*pszSource))
2772 size_t NewSourceGap = (pszNewSource - pszSource);
2773 CHARACTER * pszNewDest = pszDest + NewSourceGap;
2775 for (i = 0; pszDest != pszNewDest && i < NewSourceGap; i++)
2777 *pszDest = *pszSource;
2782 pszSource = pszNewSource;
2785 character_count count = character_count(pszSource - pszDest);
2786 release_buffer(nLength - count);
2794template <
typename ITERATOR_TYPE >
2795inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::find(
CHARACTER ch)
const RELEASENOTHROW
2798 return this->find_first(ch);
2804template <
typename ITERATOR_TYPE >
2805inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::case_insensitive_find(
CHARACTER ch)
const RELEASENOTHROW
2833 auto psz = this->begin();
2835 while(psz < this->end())
2838 if (character_tolower(*psz) == character_tolower(ch))
2855template <
typename ITERATOR_TYPE >
2859 return ::string_find_character(this->begin() + start, this->end(), ch);
2866template <
typename ITERATOR_TYPE >
2872 auto rangeScope = *
this;
2874 if (this->_initialize_find(p, scopedstr, rangeScope))
2881 auto psz = (
const CHARACTER * ) p;
2883 auto pszBlock = (
const CHARACTER * ) scopedstr.begin();
2885 auto pszBlockEnd = (
const CHARACTER *)scopedstr.end();
2887 for (; psz < rangeScope.m_end; psz++)
2892 auto pszBlock2 = pszBlock;
2901 if (unicode_index_length(psz2, len1) != unicode_index_length(pszBlock2, len2))
2913 while (pszBlock2 < pszBlockEnd);
2915 if (pszBlock2 >= pszBlockEnd)
2929 psz = ::unicode_next(psz);
2939template <
typename ITERATOR_TYPE >
2940inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_find(
const SCOPED_STRING & scopedstr)
const RELEASENOTHROW
2945 auto rangeScope = *
this;
2947 if (this->_initialize_find(p, scopedstr, rangeScope))
2960 for (; psz < rangeScope.m_end; psz++)
2973 while (*psz2 !=
'\0' && *pszSub2 !=
'\0')
2976 if (unicode_to_lower_case(unicode_index_length(psz2, len1)) !=
2977 unicode_to_lower_case(unicode_index_length(pszSub2, len2)))
2995 if (*pszSub2 ==
'\0')
3035template <
typename ITERATOR_TYPE >
3036string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator += (
const SCOPED_STRING & scopedstr)
3046inline string & operator <<(
string & str, const_char_pointer psz)
3056template < prototype_
integral INTEGRAL >
3057inline string & operator <<(
string & str, INTEGRAL i)
3060 str += ::as_string(i);
3067template <
typename ITERATOR_TYPE >
3068inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_rear_find(
const SCOPED_STRING & scopedstr)
const RELEASENOTHROW
3071 auto psz = (
const CHARACTER *)this->begin();
3073 auto pszEnd = (
const CHARACTER *)this->end();
3075 pszEnd = unicode_prior(pszEnd, psz);
3077 auto pszBlock = (
const CHARACTER *)scopedstr.begin();
3079 auto pszBlockEnd = (
const CHARACTER *)scopedstr.end();
3081 pszBlockEnd = unicode_prior(pszBlockEnd, pszBlock);
3083 if (::is_null(pszBlockEnd))
3090 while(::is_set(pszEnd))
3095 const CHARACTER * pszSub2 = pszBlockEnd;
3102 if (unicode_index(pszBlockEnd) != unicode_index(psz2))
3109 pszSub2 = (
const CHARACTER *)unicode_prior(pszSub2, pszBlock);
3111 if (::is_null(pszSub2))
3122 psz2 = (
const CHARACTER *)unicode_prior(psz2, psz);
3137 pszEnd = (
const CHARACTER *)unicode_prior(pszEnd, psz);
3150template <
typename ITERATOR_TYPE >
3151inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_rear_find(
const SCOPED_STRING & scopedstr)
const RELEASENOTHROW
3154 auto psz = (
const CHARACTER *)this->begin();
3156 auto pszEnd = (
const CHARACTER *)this->end();
3158 pszEnd = unicode_prior(pszEnd, psz);
3160 auto pszBlock = (
const CHARACTER *)scopedstr.begin();
3162 auto pszBlockEnd = (
const CHARACTER *)scopedstr.end();
3164 pszBlockEnd = unicode_prior(pszBlockEnd, pszBlock);
3166 if (::is_null(pszBlockEnd))
3173 while (::is_set(pszEnd))
3178 const CHARACTER * pszSub2 = pszBlockEnd;
3185 if (unicode_to_lower_case(unicode_index(pszBlockEnd)) != unicode_to_lower_case(unicode_index(psz2)))
3192 pszSub2 = (
const CHARACTER *)unicode_prior(pszSub2, pszBlock);
3194 if (::is_null(pszSub2))
3205 psz2 = (
const CHARACTER *)unicode_prior(psz2, psz);
3220 pszEnd = (
const CHARACTER *)unicode_prior(pszEnd, psz);
3233template <
typename ITERATOR_TYPE >
3234typename const_string_range < ITERATOR_TYPE >::CHARACTER const_string_range < ITERATOR_TYPE >::last_char(character_count count)
const
3237 return *(this->end() + count);
3243template <
typename ITERATOR_TYPE >
3244string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_upper()
3246 character_count nLength = this->size();
3247 CHARACTER * pszBuffer = get_buffer<true>(nLength);
3248 string_uppercase(pszBuffer, nLength + 1);
3249 release_buffer(nLength);
3255template <
typename ITERATOR_TYPE >
3256string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_lower()
3258 character_count nLength = this->size();
3259 CHARACTER * pszBuffer = get_buffer<true>(nLength);
3260 string_lowercase(pszBuffer, nLength + 1);
3261 release_buffer(nLength);
3267template <
typename ITERATOR_TYPE >
3268string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::MakeReverse()
3270 character_count nLength = this->size();
3271 CHARACTER * pszBuffer = get_buffer<true>(nLength);
3272 string_reverse(pszBuffer);
3273 release_buffer(nLength);
3281template <
typename ITERATOR_TYPE >
3282string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right()
3285 return trim_right(
" \t\r\n");
3336template <
typename ITERATOR_TYPE >
3337string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left()
3341 return trim_left(
" \t\r\n");
3408template <
typename ITERATOR_TYPE >
3409string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim()
3411 return(trim_right().trim_left());
3415template <
typename ITERATOR_TYPE >
3416string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(
CHARACTER chTarget)
3418 return(trim_right(chTarget).trim_left(chTarget));
3422template <
typename ITERATOR_TYPE >
3423string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(
const SCOPED_STRING & scopedstrTargets)
3425 return trim_right(scopedstrTargets).trim_left(scopedstrTargets);
3431template <
typename ITERATOR_TYPE >
3432string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(
CHARACTER chTarget)
3435 auto iterator = this->rear_skip(chTarget);
3483template <
typename ITERATOR_TYPE >
3484string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(
const SCOPED_STRING & scopedstrCharacters)
3489 auto p = this->rear_skip_any_character_in(scopedstrCharacters);
3491 if (p < this->end())
3546template <
typename ITERATOR_TYPE >
3547string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(
CHARACTER chTarget)
3550 auto p = this->skip(chTarget);
3552 if (::is_set(p) && p > this->begin())
3586template <
typename ITERATOR_TYPE >
3587string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(
const SCOPED_STRING & scopedstrCharacters)
3592 auto p = this->skip_any_character_in(scopedstrCharacters);
3594 if (p > this->begin())
3597 this->erase_beginning(p);
3633template <
typename ITERATOR_TYPE >
3634string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed()
const
3637 string_base < ITERATOR_TYPE > scopedstr(*
this);
3639 scopedstr.trim_right();
3647template <
typename ITERATOR_TYPE >
3648string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed()
const
3651 string_base < ITERATOR_TYPE > scopedstr(*
this);
3653 scopedstr.trim_left();
3661template <
typename ITERATOR_TYPE >
3662string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed()
const
3665 string_base < ITERATOR_TYPE > scopedstr(*
this);
3675template <
typename ITERATOR_TYPE >
3676string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(
CHARACTER chTarget)
const
3679 string_base < ITERATOR_TYPE > scopedstr(*
this);
3681 scopedstr.trim(chTarget);
3689template <
typename ITERATOR_TYPE >
3690string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(
const SCOPED_STRING & scopedstrCharacters)
const
3693 auto scopedstr(*
this);
3695 scopedstr.trim(scopedstrCharacters);
3697 return ::transfer(scopedstr);
3705template <
typename ITERATOR_TYPE >
3706string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(
CHARACTER chTarget)
const
3709 auto scopedstr(*
this);
3711 scopedstr.trim_right(chTarget);
3713 return ::transfer(scopedstr);
3719template <
typename ITERATOR_TYPE >
3720string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(
const SCOPED_STRING & scopedstrCharacters)
const
3723 auto scopedstr(*
this);
3725 scopedstr.trim_right(scopedstrCharacters);
3727 return ::transfer(scopedstr);
3733template <
typename ITERATOR_TYPE >
3734string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(
CHARACTER chTarget)
const
3737 string_base < ITERATOR_TYPE > scopedstr(*
this);
3739 scopedstr.trim_left(chTarget);
3747template <
typename ITERATOR_TYPE >
3748string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(
const SCOPED_STRING & scopedstrCharacters)
const
3751 auto scopedstr(*
this);
3753 scopedstr.trim_left(scopedstrCharacters);
3755 return ::transfer(scopedstr);
3760template <
typename ITERATOR_TYPE >
3761const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(character_count start)
const
3764 return subrange(start, -1);
3769template <
typename ITERATOR_TYPE >
3770template < prototype_
integral START, prototype_
integral COUNT >
3771const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(START start, COUNT count)
const
3774 character_count length = this->size();
3782 else if ((::character_count)start >= length)
3789 character_count end;
3794 end = length + count + 1;
3800 end = start + count;
3811 if (end <= (::character_count)start)
3818 return { this->begin() + start, (::character_count)(end - start) };
3894template <
typename ITERATOR_TYPE >
3895void string_base < ITERATOR_TYPE >::clear()
3904template <
typename ITERATOR_TYPE >
3905string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf_arguments(
const CHARACTER * pszFormat, va_list args)
3908 ASSERT(is_string_ok(pszFormat));
3910 character_count nCurrentLength = this->size();
3912 va_list argsForCount;
3914 va_copy(argsForCount, args);
3916 character_count nAppendLength = get_formatted_length(pszFormat, argsForCount);
3918 va_end(argsForCount);
3920 auto p = get_buffer<true>(nCurrentLength + nAppendLength);
3922 _string_format(p + nCurrentLength, nAppendLength + 1, pszFormat, args);
3924 release_buffer(nCurrentLength + nAppendLength);
3931template <
typename ITERATOR_TYPE >
3932string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf_arguments(
const CHARACTER * pszFormat, va_list args)
3935 ASSERT(is_string_ok(pszFormat));
3937 if (pszFormat ==
nullptr)
3940 throw_exception(error_bad_argument);
3946 va_copy(ptr1, args);
3948 character_count nLength = get_formatted_length(pszFormat, ptr1);
3953 throw ::exception(error_failed);
3959 CHARACTER * pszBuffer = get_buffer(nLength);
3963 va_copy(ptr2, args);
3965 _string_format(pszBuffer, nLength + 1, pszFormat, ptr2);
3969 release_buffer(nLength);
3976template <
typename ITERATOR_TYPE >
3977string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::format_arguments(
const scoped_string & scopedstrFormat, std::format_args args)
3978 requires(::is_same<CHARACTER, ansi_character>)
3980 return this->operator=(::format_arguments(scopedstrFormat, args));
3984template <
typename ITERATOR_TYPE >
3985string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::format_arguments(
const scoped_wstring & scopedstrFormat, std::wformat_args args)
3987requires(::is_same<CHARACTER, wide_character>)
3989 return this->operator=(::wformat_arguments(scopedstrFormat, args));
3993template <
typename ITERATOR_TYPE >
3994template<
typename... Args>
3995string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::runtime_format(
const scoped_string & scopedstrFormat, Args&&... args)
3996requires(::is_same<CHARACTER, ansi_character>)
3999 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
4001 auto str = std::apply([&](
auto&... unpacked) {
4002 return ::format_arguments(scopedstrFormat, std::make_format_args(unpacked...));
4005 return this->operator=(::transfer(str));
4013template <
typename ITERATOR_TYPE >
4014template<
typename... Args>
4015string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::runtime_format(
const scoped_wstring & scopedstrFormat, Args&&... args)
4016requires(::is_same<CHARACTER, wide_character>)
4019 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
4021 auto wstr = std::apply([&](
auto&... unpacked) {
4022 return ::wformat_arguments(scopedstrFormat, std::make_format_args(unpacked...));
4025 return this->operator=(::transfer(wstr));
4032template <
typename ITERATOR_TYPE >
4033string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf(
const CHARACTER * pszFormat, ...)
4036 ASSERT(is_string_ok(pszFormat));
4040 va_start(argList, pszFormat);
4042 formatf_arguments(pszFormat, argList);
4052template <
typename ITERATOR_TYPE >
4053string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf(
const CHARACTER * pszFormat, ...)
4056 ASSERT(is_string_ok(pszFormat));
4060 va_start(argList, pszFormat);
4062 append_formatf_arguments(pszFormat, argList);
4071template <
typename ITERATOR_TYPE >
4072void string_base < ITERATOR_TYPE >::reserve(character_count res_arg)
4074 get_buffer<true>(res_arg + 1);
4080template <
typename ITERATOR_TYPE >
4081string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::uppered()
const
4084 return string_base < ITERATOR_TYPE >(*this).make_upper();
4090template <
typename ITERATOR_TYPE >
4091string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::reversed()
const
4094 return string_base < ITERATOR_TYPE >(*this).MakeReverse();
4099template <
typename ITERATOR_TYPE >
4100string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst)
const
4103 return unichar_substr(iFirst, -1);
4108template <
typename ITERATOR_TYPE >
4109string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst, character_count count)
const
4114 if (pchStart ==
nullptr)
4117 ::collection::count iUtf8Len = this->unichar_count();
4120 iFirst = iUtf8Len + iFirst;
4123 count = iUtf8Len - iFirst + count + 1;
4125 if (iFirst + count > iUtf8Len)
4126 count = iUtf8Len - iFirst;
4131 ::collection::count ca = 0;
4133 while (ca < iFirst && *pchStart !=
'\0')
4136 pchStart = unicode_next(pchStart);
4142 if (*pchStart ==
'\0')
4149 while (ca < count && *pchEnd !=
'\0')
4152 pchEnd = unicode_next(pchEnd);
4158 return string_base < ITERATOR_TYPE >(pchStart, pchEnd - pchStart);
4188template <
typename ITERATOR_TYPE >
4189inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unichar_at(character_count iUnicharIndex)
const
4192 auto p = this->begin();
4194 while (p < this->end() && iUnicharIndex > 0)
4197 auto iLen = unicode_len(p);
4209template <
typename ITERATOR_TYPE >
4210bool string_base < ITERATOR_TYPE >::eat_before(string_base < ITERATOR_TYPE > & strBefore,
const SCOPED_STRING & scopedstrSeparator,
bool bEatEverythingIfNotFound)
4213 ASSERT(
this != &strBefore);
4215 if (
this == &strBefore)
4222 auto pFind = this->find(scopedstrSeparator);
4224 if (::is_null(pFind))
4227 if (bEatEverythingIfNotFound)
4240 strBefore = (*this)(0, pFind);
4242 *
this = (*this)(pFind + scopedstrSeparator.size());
4250template <
typename ITERATOR_TYPE >
4251bool string_base < ITERATOR_TYPE >::eat_before_let_separator(string_base < ITERATOR_TYPE > & strBefore,
const SCOPED_STRING & scopedstrSeparator,
bool bEatEverythingIfNotFound)
4254 ASSERT(
this != &strBefore);
4256 if (
this == &strBefore)
4263 auto pFind = this->find(scopedstrSeparator);
4265 if (::is_null(pFind))
4268 if (bEatEverythingIfNotFound)
4273 *
this = scopedstrSeparator;
4281 strBefore = (*this)(0, pFind);
4283 *
this = (*this)(pFind);
4290template <
typename ITERATOR_TYPE >
4291void string_base < ITERATOR_TYPE >::add(
CHARACTER ch)
4360template <
typename ITERATOR_TYPE >
4361inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_begins(
const SCOPED_STRING & scopedstr)
const
4364 return this->begins(scopedstr, ::comparison::case_insensitive < CHARACTER >());
4370template <
typename ITERATOR_TYPE >
4371inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_ends(
const SCOPED_STRING & scopedstr)
const
4374 return this->ends(scopedstr, ::comparison::case_insensitive < CHARACTER >());
4379template <
typename ITERATOR_TYPE >
4380inline bool string_base < ITERATOR_TYPE > ::begins_eat(
const SCOPED_STRING & scopedstrPrefix)
4383 if (!this->begins(scopedstrPrefix))
4390 assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4397template <
typename ITERATOR_TYPE >
4398inline bool string_base < ITERATOR_TYPE > ::ends_eat(
const SCOPED_STRING & scopedstrSuffix)
4401 if (!this->ends(scopedstrSuffix))
4408 assign(this->begin(), this->size() - scopedstrSuffix.size());
4415template <
typename ITERATOR_TYPE >
4416inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eat(
const SCOPED_STRING & scopedstrPrefix)
4419 if (!this->case_insensitive_begins(scopedstrPrefix))
4426 assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4433template <
typename ITERATOR_TYPE >
4434inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eat(
const SCOPED_STRING & scopedstrSuffix)
4437 if (!this->case_insensitive_ends(scopedstrSuffix))
4444 assign(this->begin(), this->size() - scopedstrSuffix.size());
4451template <
typename ITERATOR_TYPE >
4452inline bool string_base < ITERATOR_TYPE > ::begins_replace(
const SCOPED_STRING & scopedstrNewPrefix,
const SCOPED_STRING & scopedstrPrefix)
4455 if(!begins_eat(scopedstrPrefix))
4462 *
this = scopedstrNewPrefix + *
this;
4469template <
typename ITERATOR_TYPE >
4470inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_replace(
const SCOPED_STRING & scopedstrNewPrefix,
const SCOPED_STRING & scopedstrPrefix)
4473 if(!this->case_insensitive_begins_eat(scopedstrPrefix))
4480 *
this = scopedstrNewPrefix + *
this;
4487template <
typename ITERATOR_TYPE >
4488inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_prefix(
const SCOPED_STRING & scopedstrPrefix)
4491 if (!this->begins(scopedstrPrefix))
4494 operator =(scopedstrPrefix + *
this);
4503template <
typename ITERATOR_TYPE >
4504inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_prefix(
const SCOPED_STRING & scopedstrPrefix)
4507 if (!this->case_insensitive_begins(scopedstrPrefix))
4510 operator =(scopedstrPrefix + *
this);
4519template <
typename ITERATOR_TYPE >
4520inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_suffix(
const SCOPED_STRING & scopedstrSuffix)
4523 if (!this->ends(scopedstrSuffix))
4526 operator =(*
this + scopedstrSuffix);
4535template <
typename ITERATOR_TYPE >
4536inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_suffix(
const SCOPED_STRING & scopedstrSuffix)
4539 if (!this->case_insensitive_ends(scopedstrSuffix))
4542 operator =(*
this + scopedstrSuffix);
4552template <
typename ITERATOR_TYPE >
4553inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_prefixed(
const SCOPED_STRING & scopedstrPrefix)
const
4556 if (!this->begins(scopedstrPrefix))
4559 return scopedstrPrefix + *
this;
4568template <
typename ITERATOR_TYPE >
4569inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_prefixed(
const SCOPED_STRING & scopedstrPrefix)
const
4572 if (!this->case_insensitive_begins(scopedstrPrefix))
4575 return scopedstrPrefix + *
this;
4584template <
typename ITERATOR_TYPE >
4585inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_suffixed(
const SCOPED_STRING & scopedstrSuffix)
const
4588 if (!this->ends(scopedstrSuffix))
4591 return *
this + scopedstrSuffix;
4600template <
typename ITERATOR_TYPE >
4601inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_suffixed(
const SCOPED_STRING & scopedstrSuffix)
const
4604 if (!this->case_insensitive_ends(scopedstrSuffix))
4607 return *
this + scopedstrSuffix;
4802template <
typename ITERATOR_TYPE >
4803inline bool string_base < ITERATOR_TYPE > ::begins_get_remainder(
string_base & strRemainder,
const SCOPED_STRING & scopedstrPrefix)
const
4806 if (!this->begins(scopedstrPrefix))
4813 strRemainder.assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4820template <
typename ITERATOR_TYPE >
4821inline bool string_base < ITERATOR_TYPE > ::ends_get_remainder(
string_base & strRemainder,
const SCOPED_STRING & scopedstrSuffix)
const
4824 if (!this->ends(scopedstrSuffix))
4831 strRemainder.assign(this->begin(), this->size() - scopedstrSuffix.size());
4838template <
typename ITERATOR_TYPE >
4839inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_get_remainder(
string_base & strRemainder,
const SCOPED_STRING & scopedstrPrefix)
const
4842 if (!this->case_insensitive_begins(scopedstrPrefix))
4849 strRemainder.assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4856template <
typename ITERATOR_TYPE >
4857inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_get_remainder(
string_base & strRemainder,
const SCOPED_STRING & scopedstrSuffix)
const
4860 if (!this->case_insensitive_ends(scopedstrSuffix))
4867 strRemainder.assign(this->begin(), this->size() - scopedstrSuffix.size());
4874template <
typename ITERATOR_TYPE >
4875inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::begins_bitten(
const SCOPED_STRING & scopedstrPrefix)
const
4878 if (!this->begins(scopedstrPrefix))
4885 return { this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size() };
4890template <
typename ITERATOR_TYPE >
4891inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::ends_bitten(
const SCOPED_STRING & scopedstrSuffix)
const
4894 if (!this->ends(scopedstrSuffix))
4901 return { this->begin(), this->size() - scopedstrSuffix.size()};
4906template <
typename ITERATOR_TYPE >
4907inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_bitten(
const SCOPED_STRING & scopedstrPrefix)
const
4910 if (!this->case_insensitive_begins(scopedstrPrefix))
4917 return { this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size()};
4922template <
typename ITERATOR_TYPE >
4923inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_bitten(
const SCOPED_STRING & scopedstrSuffix)
const
4926 if (!this->case_insensitive_ends(scopedstrSuffix))
4933 return { this->begin(), this->size() - scopedstrSuffix.size()};
4939template <
typename ITERATOR_TYPE >
4940inline bool string_base < ITERATOR_TYPE > ::begins_erase_get_erased(
string_base & strErased,
const SCOPED_STRING & scopedstrPrefix)
4943 if (!this->case_insensitive_begins(scopedstrPrefix))
4950 strErased.assign(this->begin(), scopedstrPrefix.size());
4952 assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4959template <
typename ITERATOR_TYPE >
4960inline bool string_base < ITERATOR_TYPE > ::ends_erase_get_erased(
string_base & strErased,
const SCOPED_STRING & scopedstrSuffix)
4963 if (!this->case_insensitive_ends(scopedstrSuffix))
4970 strErased.assign(this->begin() + this->length() - scopedstrSuffix.size(), scopedstrSuffix.size());
4972 assign(this->begin(), this->size() - scopedstrSuffix.size());
4979template <
typename ITERATOR_TYPE >
4980inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_eaten(
const SCOPED_STRING & scopedstrPrefix)
const
4983 if (!this->case_insensitive_begins(scopedstrPrefix))
4990 return { this->begin(), scopedstrPrefix.size() };
4995template <
typename ITERATOR_TYPE >
4996inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_eaten(
const SCOPED_STRING & scopedstrSuffix)
const
4999 if (!this->case_insensitive_ends(scopedstrSuffix))
5006 return { this->begin() + this->length() - scopedstrSuffix.size(), scopedstrSuffix.size() };
5011template <
typename ITERATOR_TYPE >
5013template <
typename EQUALITY >
5014inline ::collection::count string_base < ITERATOR_TYPE > ::_replace_with(
const SCOPED_STRING & scopedstrNew,
const SCOPED_STRING & scopedstrOld, character_count start, EQUALITY equality)
5018 character_count nReplacedLen = scopedstrOld.size();
5020 if (nReplacedLen == 0)
5028 character_count nReplacementLen = scopedstrNew.size();
5031 auto count = (*this)(start)._occurrence_count_of(scopedstrOld, equality);
5044 character_count nNewLength = this->size() + (nReplacementLen - nReplacedLen) * count;
5046 string_base < ITERATOR_TYPE > str;
5048 CHARACTER * pszBuffer = str.get_buffer(nNewLength);
5052 BASE_RANGE rangeOld = *
this;
5054 memory_copy(pLastNewEnd, rangeOld.begin(), start *
sizeof(
CHARACTER));
5056 rangeOld.begin() += start;
5058 pLastNewEnd += start;
5062 while ((pszTarget = (
CHARACTER *)rangeOld.find(scopedstrOld, equality)) !=
nullptr)
5065 auto offset = pszTarget - rangeOld.begin();
5067 memory_copy(pLastNewEnd,rangeOld.begin(), offset *
sizeof(
CHARACTER));
5069 pLastNewEnd += offset;
5071 memory_copy(pLastNewEnd, scopedstrNew.begin(), nReplacementLen *
sizeof(
CHARACTER));
5073 rangeOld.m_begin = pszTarget + nReplacedLen;
5075 pLastNewEnd += nReplacementLen;
5079 memory_copy(pLastNewEnd,rangeOld.begin(), (rangeOld.end() - rangeOld.begin()) *
sizeof(
CHARACTER));
5081 str.release_buffer(nNewLength);
5083 *
this = ::transfer(str);
5093template < prototype_
character CHARACTER >
5094void CopyCharsOverlapped(
CHARACTER * pchDest,
const CHARACTER * pchSrc, character_count nChars)
noexcept
5097 memory_transfer(pchDest, pchSrc, nChars *
sizeof(
CHARACTER));
5102template < prototype_
character CHARACTER >
5103void CopyCharsOverlapped(
CHARACTER * pchDest,
size_t nDestLen,
const CHARACTER * pchSrc, character_count nChars)
noexcept
5106 memory_transfer(pchDest, pchSrc, nChars *
sizeof(
CHARACTER));
5112template <
typename STRING >
5113inline STRING & string_concatenate(STRING & scopedstr,
const typename STRING::CHARACTER * psz1, character_count nLength1,
const typename STRING::CHARACTER * psz2, character_count nLength2)
5116 character_count nNewLength = nLength1 + nLength2;
5118 typename STRING::CHARACTER * pszBuffer = scopedstr.get_buffer(nNewLength);
5120 string_count_copy(pszBuffer, psz1, nLength1);
5122 string_count_copy(pszBuffer + nLength1, psz2, nLength2);
5124 scopedstr.release_buffer(nNewLength);
5131template <
typename STRING >
5132inline bool string_ends_eat(STRING & ansistr,
const STRING & scopedstrSuffix)
5135 auto lenSuffix = scopedstrSuffix.length();
5137 if (lenSuffix > ansistr.length())
5144 if (STRING::string_count_compare(ansistr.reverse_ptr_at(lenSuffix), scopedstrSuffix, lenSuffix) != 0)
5151 ansistr.reverse_truncate(lenSuffix);
5159::i32 get_mem_free_available_kb();
5162template < prototype_
character CHARACTER >
5163::wd32_character unicode_iterator < CHARACTER > ::operator *() {
return unicode_index(m_psz); }
5166template < prototype_
character CHARACTER >
5167unicode_iterator < CHARACTER > & unicode_iterator < CHARACTER > ::operator ++()
5170 unicode_increment(m_psz);
5177template < prototype_
character CHARACTER >
5178unicode_iterator < CHARACTER > unicode_iterator < CHARACTER > ::operator ++(::i32)
5183 unicode_increment(m_psz);
5191template <
typename ITERATOR_TYPE >
5192inline string_base < ITERATOR_TYPE > operator +(
const scoped_string_base < ITERATOR_TYPE > & scopedstr,
const inline_number_string & inlinenumberstring)
5195 string_base < ITERATOR_TYPE > str(scopedstr);
5197 string_base < ITERATOR_TYPE > strNumber(inlinenumberstring);
5199 str.append(strNumber);
5201 return ::transfer(scopedstr);
5206template <
character_count n >
5207inline ::string_base < const_char_pointer >operator +(const ::i8 (&s)[n],
const inline_number_string& inlinenumberstring)
5210 return { ::as_string_literal<::i8, n>(s), inlinenumberstring };
5265template <
typename ITERATOR_TYPE >
5266inline string_base < ITERATOR_TYPE >::string_base(const ::atom&
atom) :
5274template <
typename ITERATOR_TYPE >
5275string_base < ITERATOR_TYPE >::string_base(const ::payload &
payload) :
5283template <
typename ITERATOR_TYPE >
5284inline string_base < ITERATOR_TYPE >::string_base(
const property &
property) :
5308template <
typename ITERATOR_TYPE >
5309inline typename scoped_string_base < ITERATOR_TYPE >::STRING scoped_string_base < ITERATOR_TYPE > ::as_string()
const
5317template <
typename ITERATOR_TYPE >
5318inline typename scoped_string_base < ITERATOR_TYPE >::BASE_RANGE scoped_string_base < ITERATOR_TYPE > ::rear_word(
CHARACTER ch)
const
5321 auto p = this->rear_find(ch);
5330 return {::unicode_next(p), this->m_end};
5335template <
typename ITERATOR_TYPE >
5336inline typename scoped_string_base < ITERATOR_TYPE >::BASE_RANGE scoped_string_base < ITERATOR_TYPE > ::rear_prefix(
CHARACTER ch)
const
5339 auto p = this->rear_find(ch);
5348 return {this->m_begin, p};
5353#include "acme/prototype/string/c_string.h"
5356template <
typename ITERATOR_TYPE >
5357string_base<ITERATOR_TYPE>::string_base(const ::c::string & cstring) :
5368template<
typename ITERATOR_TYPE>
5369inline const ::block string_base<ITERATOR_TYPE>::block_with_null_terminator()
const
5372 return {(
const void *) this->data(), this->size_in_bytes_with_null_terminator()};