79class const_string_range :
82 public ::character_range<ITERATOR_TYPE> {
85 using BASE_RANGE = ::character_range<ITERATOR_TYPE>;
86 using RAW_CHARACTER_RANGE =
typename BASE_RANGE::RAW_CHARACTER_RANGE;
90 using THIS_RANGE = ::const_string_range<ITERATOR_TYPE>;
95 using ITEM_POINTER = get_type_item_pointer<ITERATOR_TYPE>;
96 using ITEM = non_const<dereference<ITEM_POINTER> >;
97 using CHARACTER = ITEM;
99 using BASE_DATA = BASE_RANGE::BASE_DATA;
102 using this_iterator =
typename BASE_RANGE::this_iterator;
103 using iterator =
typename BASE_RANGE::iterator;
104 using const_iterator =
typename BASE_RANGE::const_iterator;
106 using THIS_RAW_RANGE =
typename BASE_RANGE::THIS_RAW_RANGE;
107 using RAW_RANGE =
typename BASE_RANGE::RAW_RANGE;
108 using CONST_RAW_RANGE =
typename BASE_RANGE::CONST_RAW_RANGE;
117 using ARG_ITEM =
typename BASE_RANGE::ARG_ITEM;
119 using STRING = string_base < ITERATOR_TYPE >;
121 using STRING_ARRAY = ::string_base_array < STRING, STRING, e_type_string_array >;
126 const_string_range(nullptr_t) : BASE_RANGE(
nullptr) {}
128 const_string_range() {}
160 template<prototype_
integral INTEGRAL>
161 constexpr const_string_range(const_iterator begin, INTEGRAL count) : BASE_RANGE((this_iterator)begin,
162 (this_iterator)(begin + count)) {
165 template < typed_range < iterator > TYPED_RANGE >
166 constexpr const_string_range(
const TYPED_RANGE & range)
167 requires(!::std::is_same_v < TYPED_RANGE, THIS_RANGE >) :
168 BASE_RANGE(range.m_begin, range.m_end, range.m_erange) { }
170 constexpr const_string_range(
const const_string_range & range) :
171 BASE_RANGE(range.m_begin, range.m_end, range.m_erange) { }
173 constexpr const_string_range(const_string_range && range) :
174 BASE_RANGE(::transfer(range)) { }
176 constexpr const_string_range(this_iterator begin, this_iterator end, enum_range erange = e_range_none, BASE_DATA * pbasedata =
nullptr) :
177 BASE_RANGE(begin, end, erange, pbasedata) { }
181 const_string_range(const ::block& block);
183 const_string_range(ITERATOR_TYPE psz) :
184 const_string_range(psz, string_safe_length(psz)) {}
187 const_string_range start_count(character_count start, character_count count = -1)
190 if (start > this->size())
202 end = this->size() + count + 1;
212 if (end >= this->size())
219 auto erange = this->m_erange;
227 erange = e_range_none;
241 erange = e_range_none;
246 this->m_begin + start,
253 ::collection::count length()
const {
return this->size();}
256 const_string_range & assign_bounded(ITERATOR_TYPE psz, character_count start, character_count count)
259 *
this = ::_start_count_string_range(psz, start, count);
265 const_string_range subrange(character_count iFirst)
const;
267 const_string_range subrange(const_iterator p)
const { return ::transfer(subrange(p, -1)); }
268 const_string_range subrange(const_iterator p, character_count count)
const { return ::transfer(subrange(p - this->begin(), count)); }
272 template < prototype_
integral START, prototype_
integral COUNT >
273 const_string_range subrange(START start, COUNT count)
const;
274 template < prototype_
integral START >
275 const_string_range subrange(START start, const_iterator p)
const {
return subrange(start, (p - this->m_begin) - start); }
281 template<::i32 cCount, ::i32 wCount, ::i32 u16Count, ::i32 u32Count>
282 static consteval auto typed_str_literal(const ::i8(&c)[cCount],
const wchar_t(&w)[wCount],
const char16_t(&u16)[u16Count],
const char32_t(&u32)[u32Count])
284 if constexpr (std::is_same_v<CHARACTER, ::i8>)
286 else if constexpr (std::is_same_v<CHARACTER, wchar_t>)
288 else if constexpr (std::is_same_v<CHARACTER, char16_t>)
290 else if constexpr (std::is_same_v<CHARACTER, char32_t>)
293 static_assert(
sizeof(CHARACTER) == 0,
"Unsupported character type");
298 auto& last()
const {
return (
const CHARACTER&) ::get(this->end() - 1); }
300 auto& last(::collection::index i)
const {
return (
const CHARACTER&) ::get(this->end() - 1 - i); }
302 auto last_index()
const {
return this->size() - 1; }
304 auto last_index(::collection::index i)
const {
return this->size() - 1 - i; }
306 bool is_trimmed_empty()
const;
316 constexpr THIS_RANGE _begin_set(ITERATOR_TYPE pbegin)
const
322 (enum_range)this->m_erange,
329 constexpr THIS_RANGE begin_set(ITERATOR_TYPE pbegin)
const
332 if (pbegin < this->m_begin)
335 throw "pbegin < this->m_begin";
338 else if (pbegin > this->m_end)
341 throw "pbegin > this->m_end";
345 return _begin_set(pbegin);
350 constexpr THIS_RANGE _end_set(ITERATOR_TYPE pend)
const
353 return pend == this->m_end ?
365 constexpr THIS_RANGE end_set(ITERATOR_TYPE pend)
const
368 if (pend < this->m_begin)
371 throw "pend < this->m_begin";
374 else if (pend > this->m_end)
377 throw "pend > this->m_end";
381 return _end_set(pend);
386 template < prototype_
integral START, prototype_
integral COUNT>
387 STRING_RANGE operator()(START start, COUNT count)
const;
388 template < prototype_integral START, typed_character_pointer < const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
389 STRING_RANGE operator()(START start, CHARACTER_POINTER end)
const
391 return ::_start_end_range(STRING_RANGE(*
this), start, end);
393 template < typed_character_pointer < typename const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
394 STRING_RANGE operator()(CHARACTER_POINTER start)
const
396 return STRING_RANGE(start, this->end());
398 template < prototype_
integral START >
399 STRING_RANGE operator()(START start)
const;
400 STRING_RANGE operator()()
const;
402 template < prototype_
integral START, prototype_
integral COUNT>
403 auto substr(START start, COUNT count)
const {
return this->operator()(start, count); }
404 template < prototype_integral START, typed_character_pointer < typename const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
405 auto substr(START start, CHARACTER_POINTER end)
const {
return this->operator()(start, end); }
406 template < typed_character_pointer < typename const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
407 auto substr(CHARACTER_POINTER start)
const {
return this->operator()(start); }
408 template < prototype_
integral START >
409 auto substr(START start)
const {
return this->operator()(start); }
412 ::end_of_line_and_next_line < const CHARACTER* > end_of_line_and_next_line()
const
415 ::end_of_line_and_next_line < const CHARACTER* >
pair;
417 pair.end_of_line = this->find_first_character_in(
"\r\n\0");
421 if (!*
pair.next_line)
424 pair.next_line =
nullptr;
427 else if (*
pair.next_line ==
'\r')
432 if (*
pair.next_line ==
'\n')
440 else if (*
pair.next_line ==
'\n')
449 throw_exception(error_failed);
458 constexpr bool has_character()
const {
return !this->is_empty(); }
460 inline bool is_empty()
const noexcept { return ::is_null(this->m_begin) || ::is_null(this->m_end) || this->m_end <= this->m_begin || *this->m_begin ==
'\0'; }
461 inline memsize length_in_bytes()
const {
return this->size() *
sizeof(CHARACTER); }
464 inline character_count get_upper_bound(character_count i = -1)
const noexcept {
return this->size() + i; }
466 operator ::block()
const {
return { (::u8*)this->m_begin, this->length_in_bytes() }; }
468 inline CHARACTER _character_at(character_count i)
const {
return this->data()[i]; }
469 inline CHARACTER character_at(character_count i)
const
471 return i < 0 || i >= this->size() ? CHARACTER{} : this->_character_at(i);
480 inline const CHARACTER* data()
const {
return this->begin(); }
482 inline operator const CHARACTER* ()
const {
return this->data(); }
488 inline const CHARACTER* address_at(::collection::index i)
const {
return this->data() + i; }
492 inline const CHARACTER* rear_address(::collection::index i)
const {
return this->end() + i; }
494 inline const CHARACTER& operator[](::collection::index i)
const {
return this->data()[i]; }
496 character_count index_of(
const CHARACTER* p)
const { return ::index_of(p, data()); }
499 const_string_range trimmed_left()
const
502 return _begin_set(skip_any_character_in(typed_whitespace<CHARACTER>()));
507 const_string_range trimmed_left(
const SCOPED_STRING& scopedstr)
const
510 return _begin_set(skip_any_character_in(scopedstr));
515 const_string_range trimmed_right()
const
518 return _end_set(rear_skip_any_character_in(typed_whitespace<CHARACTER>()));
523 const_string_range trimmed_right(
const SCOPED_STRING & scopedstr)
const
526 return _end_set(rear_skip_any_character_in(scopedstr));
531 const_string_range trimmed()
const
534 return trimmed_right().trimmed_left();
539 constexpr bool _is_p_in_range(ITERATOR_TYPE p)
const
542 return p >= this->m_begin && p <= this->m_begin;
547 const_string_range & trim_left(
const SCOPED_STRING& scopedstrAnyPrefixCharacterToTrim)
550 ASSERT(this->is_working_string_range());
552 auto pszBegin = this->skip_any_character_in(scopedstrAnyPrefixCharacterToTrim);
555 && pszBegin != this->m_begin
556 && this->_is_p_in_range(pszBegin))
559 this->m_begin = pszBegin;
568 const_string_range& trim_left()
571 return this->trim_left(::typed_whitespace < CHARACTER >());
576 const_string_range & trim_right(
const SCOPED_STRING& scopedstrAnySuffixCharacterToTrim)
579 ASSERT(this->is_working_string_range());
581 auto pszEnd = this->rear_skip_any_character_in(scopedstrAnySuffixCharacterToTrim);
584 && pszEnd != this->m_end
585 && this->_is_p_in_range(pszEnd))
588 this->m_end = pszEnd;
597 const_string_range& trim_right()
600 return this->trim_right(::typed_whitespace < CHARACTER >());
605 const_string_range & trim(
606 const SCOPED_STRING& scopedstrAnyPrefixCharacterToTrim,
607 const SCOPED_STRING& scopedstrAnySuffixCharacterToTrim)
610 return trim_right(scopedstrAnySuffixCharacterToTrim).
611 trim_left(scopedstrAnyPrefixCharacterToTrim);
616 const_string_range& trim()
619 return trim_right().trim_left();
624 bool defer_trim(
const SCOPED_STRING& scopedstrAnyPrefixCharacterToTrim,
const SCOPED_STRING& scopedstrAnySuffixCharacterToTrim)
627 ASSERT(this->is_working_string_range());
629 auto pszCandidateBegin = this->skip_any_character_in(scopedstrAnyPrefixCharacterToTrim);
631 auto pszCandidateEnd = this->rear_skip_any_character_in(scopedstrAnySuffixCharacterToTrim);
633 if (pszCandidateBegin <= this->m_begin
634 || pszCandidateEnd >= this->m_end)
641 this->m_begin = pszCandidateBegin;
643 this->m_end = pszCandidateEnd;
651 const_string_range trimmed(
const SCOPED_STRING& scopedstr)
const
654 return trimmed_right(scopedstr).trimmed_left(scopedstr);
675 THIS_RANGE get_utf8_char()
const;
684 ::std::strong_ordering collate(
const SCOPED_STRING& range)
const noexcept;
686 ::std::strong_ordering case_insensitive_collate(
const SCOPED_STRING& range)
const noexcept;
735 inline bool operator==(
const THIS_RANGE& range)
const {
return this->equals(range); }
741 using BASE_RANGE::_order;
743 constexpr ::std::strong_ordering _order(
const SCOPED_STRING& range)
const
751 using BASE_RANGE::order;
756 constexpr ::std::strong_ordering operator<=>(
const SCOPED_STRING& range)
const {
758 return this->order(range);
763 template < typed_
character_range < CHARACTER > CHARACTER_RANGE >
764 constexpr bool equals(
const CHARACTER_RANGE& range)
const
767 auto sizeRange = this->size();
769 if (this->is_this_range(range))
776 return sizeRange != range.size() ? false :
779 _string_count_compare(this->m_begin, range.m_begin, sizeRange) == 0
785 template < typed_
character_po
inter < CHARACTER > CHARACTER_POINTER >
786 constexpr bool equals(CHARACTER_POINTER psz)
const
789 auto sizeThis = this->size();
791 if (psz == this->m_begin)
794 return sizeThis == string_safe_length(psz);
798 return _string_count_compare(this->m_begin, psz, sizeThis) == 0
799 && psz[sizeThis] == CHARACTER{};
804 constexpr bool has_file_extension_without_dot(
const SCOPED_STRING& scopedstrFileExtensionWithoutDot)
const
807 if (this->character_at(this->size() - scopedstrFileExtensionWithoutDot.size() - 1) !=
'.')
814 if (!this->case_insensitive_ends(scopedstrFileExtensionWithoutDot))
826 constexpr bool equals(
const SCOPED_STRING& scopedstr)
const
829 auto sizeRange = this->size();
831 return sizeRange != scopedstr.size() ? false :
834 _string_count_compare(this->m_begin, scopedstr.m_begin, sizeRange) == 0
840 template < typed_
character_range < CHARACTER > CHARACTER_RANGE >
841 constexpr bool case_insensitive_equals(
const CHARACTER_RANGE& range)
const
844 auto sizeRange = this->size();
846 return sizeRange != range.size() ? false :
849 _case_insensitive_string_count_compare(this->m_begin, range.m_begin, sizeRange) == 0
855 template < typed_
character_po
inter < CHARACTER > CHARACTER_POINTER >
856 constexpr bool case_insensitive_equals(CHARACTER_POINTER psz)
const
859 auto sizeThis = this->size();
861 if (this->is_empty())
878 else if (::is_empty(psz))
884 else if (0 != _case_insensitive_string_count_compare(this->m_begin, psz, sizeThis))
890 else if (psz[sizeThis] != CHARACTER{})
906 constexpr bool case_insensitive_equals(
const SCOPED_STRING& scopedstr)
const
909 auto sizeRange = this->size();
911 return sizeRange != scopedstr.size() ? false :
914 _case_insensitive_string_count_compare(this->m_begin, scopedstr.m_begin, sizeRange) == 0
921 template < typed_
character_range < CHARACTER > CHARACTER_RANGE >
922 constexpr ::i32 compare(
const CHARACTER_RANGE& range)
const
925 auto sizeThis = this->size();
929 return this->is_empty() ?
930 (range.is_empty() ? 0 :
932 (range.is_empty() ? 1 :
933 ((iOrdering = _string_count_compare(this->m_begin, range.begin(), sizeThis)) == 0 ?
934 ::compare(sizeThis, range.size()) : iOrdering));
939 template < typed_
character_po
inter < CHARACTER > CHARACTER_POINTER >
940 constexpr ::i32 compare(CHARACTER_POINTER psz)
const
943 auto sizeThis = this->size();
947 return this->is_empty() ?
948 (::is_empty(psz) ? 0 :
950 (::is_empty(psz) ? 1 :
951 ((iOrdering = _string_count_compare(this->m_begin, psz, sizeThis)) == 0 ?
952 (psz[sizeThis] == CHARACTER{} ?
959 constexpr ::i32 compare(
const SCOPED_STRING& scopedstr)
const
962 auto sizeThis = this->size();
966 return this->is_empty() ?
967 (scopedstr.is_empty() ? 0 :
969 (scopedstr.is_empty() ? 1 :
970 ((iOrdering = _string_count_compare(this->m_begin, scopedstr.m_begin, sizeThis)) == 0
972 ::compare(sizeThis, scopedstr.size()) : iOrdering));
977 template < typed_
character_range < CHARACTER > CHARACTER_RANGE >
978 constexpr ::i32 case_insensitive_compare(
const CHARACTER_RANGE& range)
const
981 auto sizeThis = this->size();
985 return this->is_empty() ?
986 (range.is_empty() ? 0 :
988 (range.is_empty() ? 1 : ((iOrdering = _case_insensitive_string_count_compare(
989 this->m_begin, range.begin(), sizeThis)) == 0
990 ? ::compare(sizeThis, range.size())
996 template < typed_
character_po
inter < CHARACTER > CHARACTER_POINTER >
997 constexpr ::i32 case_insensitive_compare(CHARACTER_POINTER psz)
const
1000 auto sizeThis = this->size();
1002 ::i32 iOrdering = 0;
1004 return this->is_empty() ?
1005 (::is_empty(psz) ? 0 :
1007 (::is_empty(psz) ? 1 : ((iOrdering = _case_insensitive_string_count_compare(this->m_begin, psz, sizeThis)) == 0
1009 (psz[sizeThis] == CHARACTER{}?
1017 constexpr ::i32 case_insensitive_compare(
const SCOPED_STRING& scopedstr)
const
1020 auto sizeThis = this->size();
1022 ::i32 iOrdering = 0;
1024 return this->is_empty() ?
1025 (scopedstr.is_empty() ? 0 :
1027 (scopedstr.is_empty() ? 1 : ((iOrdering = _case_insensitive_string_count_compare(
1028 this->m_begin, scopedstr.m_begin, sizeThis)) == 0
1029 ? ::compare(sizeThis, scopedstr.size())
1100 template < typed_
character_range < CHARACTER > CHARACTER_RANGE >
1101 constexpr ::std::strong_ordering order(
const CHARACTER_RANGE& range)
const
1104 return this->compare(range) <=> 0;
1120 template < typed_
character_po
inter < CHARACTER > CHARACTER_POINTER >
1121 constexpr ::std::strong_ordering order(CHARACTER_POINTER psz)
const
1124 return this->compare(psz) <=> 0;
1142 constexpr ::std::strong_ordering order(
const SCOPED_STRING& scopedstr)
const
1145 return this->compare(scopedstr) <=> 0;
1161 template < typed_
character_range < CHARACTER > CHARACTER_RANGE >
1162 constexpr ::std::strong_ordering case_insensitive_order(
const CHARACTER_RANGE& range)
const
1165 return this->case_insensitive_compare(range) <=> 0;
1180 template < typed_
character_po
inter < CHARACTER > CHARACTER_POINTER >
1181 constexpr ::std::strong_ordering case_insensitive_order(CHARACTER_POINTER psz)
const
1184 return this->case_insensitive_compare(psz) <=> 0;
1202 constexpr ::std::strong_ordering case_insensitive_order(
const SCOPED_STRING& scopedstr)
const
1205 return this->case_insensitive_compare(scopedstr) <=> 0;
1335 using BASE_RANGE::_find;
1337 constexpr const_iterator _find(
const SCOPED_STRING& range)
const {
1344 using BASE_RANGE::find;
1346 constexpr const_iterator find(
const SCOPED_STRING& range)
const {
1351 constexpr character_count find_index(
const SCOPED_STRING& range, character_count start = 0)
const
1354 return this->index_of(start <= 0 ? this->find(range) : (*
this)(start).find(range));
1357 constexpr character_count find_index(CHARACTER ch, character_count start = 0)
const
1360 return this->index_of(start <= 0 ? this->find(ch) : (*
this)(start).find(ch));
1405 using BASE_RANGE::_rear_find;
1407 constexpr const_iterator _rear_find(
const SCOPED_STRING& range, const_iterator end =
nullptr)
const
1415 using BASE_RANGE::rear_find;
1417 constexpr const_iterator rear_find(
const SCOPED_STRING& range, const_iterator end =
nullptr)
const
1424 constexpr character_count _rear_find_index(
const SCOPED_STRING& range, character_count end = -1)
const
1427 return this->index_of((*
this)(0, end >= 0 ? end : this->size() + end + 1)._rear_find(range));
1432 constexpr character_count rear_find_index(
const SCOPED_STRING& range, character_count end = -1)
const
1435 return this->index_of((*
this)(0, end >= 0 ? end : this->size() + end + 1).rear_find(range));
1440 constexpr const_iterator _rear_find(CHARACTER
character, const_iterator end =
nullptr)
const
1448 constexpr const_iterator rear_find(CHARACTER
character, const_iterator end =
nullptr)
const
1456 constexpr character_count _rear_find_index(CHARACTER
character, character_count end = -1)
const
1459 return this->index_of((*
this)(0, end >= 0 ? end : this->size() + end + 1)._rear_find(
character));
1464 constexpr character_count rear_find_index(CHARACTER
character, character_count end = -1)
const
1467 return this->index_of((*
this)(0, end >= 0 ? end : this->size() + end + 1).rear_find(
character));
1472 const_iterator case_insensitive_find(
const SCOPED_STRING& scopedstr)
const RELEASENOTHROW
1480 character_count case_insensitive_find_index(
const SCOPED_STRING& scopedstr)
const RELEASENOTHROW
1483 return this->index_of(case_insensitive_find(scopedstr));
1488 character_count case_insensitive_find_index(
const SCOPED_STRING& scopedstr, character_count start)
const RELEASENOTHROW {
return this->index_of((*
this)(start).case_insensitive_find(scopedstr)); }
1491 constexpr const_iterator _case_insensitive_rear_find(
const SCOPED_STRING& scopedstr)
const
1499 character_count _case_insensitive_rear_find_index(
const SCOPED_STRING& scopedstr, character_count end = -1)
const RELEASENOTHROW
1502 return this->index_of((*
this)(0, end >= 0 ? end : this->size() + end + 1)._case_insensitive_rear_find(scopedstr));
1507 constexpr const_iterator case_insensitive_rear_find(
const SCOPED_STRING& scopedstr)
const
1515 character_count case_insensitive_rear_find_index(
const SCOPED_STRING& scopedstr, character_count end = -1)
const RELEASENOTHROW
1519 return this->index_of((*
this)(0, end >= 0 ? end : this->size() + end + 1).case_insensitive_rear_find(scopedstr));
1564 using BASE_RANGE::_find_first_character;
1566 constexpr const_iterator _find_first_character(CHARACTER ch)
const {
1572 constexpr character_count _find_first_character_index(CHARACTER ch)
const {
1573 return this->index_of(_find_first_character(ch));
1576 using BASE_RANGE::find_first_character;
1578 constexpr const_iterator find_first_character(CHARACTER ch)
const {
1584 using BASE_RANGE::_find_first_character_in;
1586 constexpr const_iterator _find_first_character_in(
const SCOPED_STRING& range)
const {
1592 constexpr character_count _find_first_character_in_index(
const SCOPED_STRING& range)
const {
1593 return this->index_of(_find_first_character_in(range));
1596 using BASE_RANGE::find_first_character_in;
1598 constexpr const_iterator find_first_character_in(
const SCOPED_STRING& range)
const {
1604 constexpr character_count find_first_character_in_index(
const SCOPED_STRING& range, ::character_count start = 0)
const {
1605 return this->index_of((*
this)(start).find_first_character_in(range));
1608 constexpr bool contains_any_character_in(
const SCOPED_STRING& range)
const {
1610 return ::found(this->find_first_character_in(range));
1617 string_base < ITERATOR_TYPE > lowered()
const;
1618 string_base < ITERATOR_TYPE > uppered()
const;
1690 template<::comparison::equality<ITEM> EQUALITY>
1691 static constexpr ITERATOR_TYPE
1692 _static_skip_any_character_in(THIS_RANGE range,
const THIS_RANGE& rangeBlock, EQUALITY equality)
noexcept
1695 ITERATOR_TYPE pbegin = range.m_begin;
1700 auto pBlockScan = rangeBlock.begin();
1705 if (equality.equals(*pbegin, *pBlockScan))
1717 if (rangeBlock.is_end(pBlockScan))
1733 }
while (!range.is_end(pbegin));
1744 template<::comparison::equality<ITEM> EQUALITY>
1745 static constexpr ITERATOR_TYPE
1746 static_skip_any_character_in(
const THIS_RANGE& range,
const THIS_RANGE& rangeBlock, EQUALITY equality)
noexcept
1749 if (range.is_empty())
1752 return range.m_begin;
1756 if (rangeBlock.is_empty())
1763 return _static_skip_any_character_in(range, rangeBlock, equality);
1785 template<::comparison::equality<ITEM> EQUALITY>
1786 constexpr ITERATOR_TYPE _skip_any_character_in(
const THIS_RANGE& rangeBlock, EQUALITY equality)
const
1789 return static_skip_any_character_in(*
this, rangeBlock, equality);
1794 constexpr ITERATOR_TYPE skip_any_character_in(
const SCOPED_STRING& range)
const {
1843 constexpr ITERATOR_TYPE rear_skip_any_character_in(
const THIS_RANGE& range)
const noexcept
1885 template<::comparison::equality<ITEM> EQUALITY>
1886 static constexpr ITERATOR_TYPE
1887 _static_rear_skip_any_character_in(THIS_RANGE range,
const THIS_RANGE& rangeBlock, EQUALITY equality)
noexcept
1890 ITERATOR_TYPE pend = range.m_end;
1897 auto pBlockScan = rangeBlock.begin();
1902 if (equality.equals(*pend, *pBlockScan))
1914 if (rangeBlock.is_end(pBlockScan))
1930 }
while (!range.is_before_begin(pend));
1941 template<::comparison::equality<ITEM> EQUALITY>
1942 static constexpr ITERATOR_TYPE
1943 static_rear_skip_any_character_in(THIS_RANGE range,
const THIS_RANGE& rangeBlock, EQUALITY equality)
noexcept
1955 if (range.is_empty())
1966 if (rangeBlock.is_empty())
1971 return range.m_begin;
1975 return _static_rear_skip_any_character_in(range, rangeBlock, equality);
2027 using BASE_RANGE::_skip;
2029 constexpr const_iterator _skip(CHARACTER
item)
const {
2036 using BASE_RANGE::skip;
2038 constexpr const_iterator skip(CHARACTER
item)
const {
2159 using BASE_RANGE::_rear_find_first_character_in;
2161 constexpr const_iterator _rear_find_first_character_in(
const SCOPED_STRING& range)
const noexcept {
2168 using BASE_RANGE::rear_find_first_character_in;
2170 constexpr const_iterator rear_find_first_character_in(
const SCOPED_STRING& range)
const noexcept {
2207 using BASE_RANGE::_begins;
2209 constexpr bool _begins(
const SCOPED_STRING& range)
const {
2216 using BASE_RANGE::begins;
2218 constexpr bool begins(
const SCOPED_STRING& range)
const {
2224 bool begins_eat(
const SCOPED_STRING& range) {
2226 if (!this->begins(range))
2233 this->m_begin += range.size();
2241 ::collection::count begins_count(
bool(*character_is_function)(CHARACTER
character))
const
2244 ::collection::count c = 0;
2246 while (character_is_function(this->begin()[c])) c++;
2326 using BASE_RANGE::_ends;
2328 constexpr bool _ends(
const SCOPED_STRING& range)
const {
2335 using BASE_RANGE::ends;
2337 constexpr bool ends(
const SCOPED_STRING& range)
const {
2386 template<
typename PRED>
2387 bool is_every_char(PRED pred)
const {
2389 for (::collection::index i = 0; i < this->length(); i++) {
2391 if (!pred(this->
operator[](i))) {
2404 template<
typename NUMBER>
2405 NUMBER& translate_index(NUMBER& number)
const {
2409 number += this->size() + 1;
2418 else if (number > this->size()) {
2420 number = this->size();
2430 inline bool contains(
const SCOPED_STRING& scopedstr = 0)
const;
2433 inline bool contains(CHARACTER ch)
const { return ::is_set(find(ch)); }
2436 contains(
const SCOPED_STRING& scopedstr,
const CHARACTER** ppszBeg,
const CHARACTER** ppszEnd =
nullptr)
const;
2439 template<prototype_array STRING_ARRAY>
2440 inline bool contains_any(
const STRING_ARRAY& stra)
const;
2442 template<prototype_array STRING_ARRAY>
2443 inline bool contains_all(
const STRING_ARRAY& stra)
const;
2446 inline bool case_insensitive_contains(
const SCOPED_STRING& scopedstr = 0)
const;
2451 case_insensitive_contains(
const SCOPED_STRING& scopedstr,
const CHARACTER** ppszBeg,
const CHARACTER** ppszEnd =
nullptr)
const;
2454 template<prototype_array STRING_ARRAY>
2455 inline bool case_insensitive_contains_at_least_one_of(
const STRING_ARRAY& stra)
const;
2457 template<prototype_array STRING_ARRAY>
2458 inline bool case_insensitive_contains_all(
const STRING_ARRAY& stra)
const;
2462 inline bool unicode_case_insensitive_contains(
const SCOPED_STRING& scopedstr = 0)
const;
2467 unicode_case_insensitive_contains(
const SCOPED_STRING& scopedstr,
const CHARACTER** ppszBeg,
const CHARACTER** ppszEnd =
nullptr)
const;
2470 template<prototype_array STRING_ARRAY>
2471 inline bool unicode_case_insensitive_contains_at_least_one_of(
const STRING_ARRAY& stra)
const;
2473 template<prototype_array STRING_ARRAY>
2474 inline bool unicode_case_insensitive_contains_all(
const STRING_ARRAY& stra)
const;
2477 template<::comparison::equality<CHARACTER> EQUALITY>
2478 ::collection::count _occurrence_count_of(
const SCOPED_STRING& scopedstr, EQUALITY equality)
const {
2480 character_count nLen = scopedstr.size();
2482 character_count count = 0;
2484 auto range = (*this)();
2486 while ((range.begin(range.find(scopedstr, equality))) !=
nullptr) {
2490 range.begin() += nLen;
2499 ::collection::count occurrence_count_of(
const SCOPED_STRING& scopedstr = 0)
const {
2506 ::collection::count case_insensitive_occurrence_count_of(
const SCOPED_STRING& scopedstr = 0)
const {
2517 const_iterator find(CHARACTER ch)
const RELEASENOTHROW;
2521 const_iterator case_insensitive_find(CHARACTER ch)
const RELEASENOTHROW;
2530 character_count case_insensitive_find_index(CHARACTER ch)
const RELEASENOTHROW {
return this->index_of(case_insensitive_find(ch)); }
2531 character_count case_insensitive_find_index(CHARACTER ch, character_count start)
const RELEASENOTHROW {
return this->index_of((*
this)(start).case_insensitive_find(ch)); }
2533 const_iterator find_skip_or_end(CHARACTER ch = 0)
const RELEASENOTHROW
2536 auto p = this->begin();
2538 while (p < this->end()) {
2560 ITERATOR_TYPE
find_first_whitespace() const RELEASENOTHROW {
return this->find_first_character_in(typed_whitespace<CHARACTER>()); }
2562 ITERATOR_TYPE skip_whitespace() const RELEASENOTHROW {
return this->skip_any_character_in(typed_whitespace<CHARACTER>()); }
2564 ::character_count count_left(
const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) const RELEASENOTHROW {
return this->skip_any_character_in(range) - this->begin(); }
2569 ITERATOR_TYPE rear_find_first_whitespace() const RELEASENOTHROW {
return this->rear_find_first_character_in(typed_whitespace<CHARACTER>()); }
2571 ITERATOR_TYPE rear_skip_whitespace() const RELEASENOTHROW {
return this->rear_skip_any_character_in(typed_whitespace<CHARACTER>()); }
2573 ::character_count count_right(
const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) const RELEASENOTHROW {
return this->m_end - this->rear_skip_any_character_in(range); }
2577 ::character_count count_left_and_right(
const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) const RELEASENOTHROW { ::character_count c;
return ((c = count_left(range)) == this->size()) ? c : c + count_right(range); }
2630 const_string_range begins_bitten(
const SCOPED_STRING & scopedstrPrefix)
const
2633 if (this->begins(scopedstrPrefix))
2636 return {this->begin() + scopedstrPrefix.size(), this->end()};
2706 const_string_range& operator=(
const THIS_RANGE& range)
2708 BASE_RANGE::operator=(range);
2712 const_string_range& operator=(const_string_range&& range) {
2713 BASE_RANGE::operator=(::transfer(range));
2719 const_string_range& operator=(
const block& block);
2727 inline bool case_insensitive_begins(
const SCOPED_STRING& scopedstrPrefix)
const;
2729 inline bool case_insensitive_ends(
const SCOPED_STRING& scopedstrSuffix)
const;
2741 const_iterator
unicode_find(
const SCOPED_STRING& scopedstr)
const RELEASENOTHROW;
2743 const_iterator unicode_case_insensitive_find(
const SCOPED_STRING& scopedstr)
const RELEASENOTHROW;
2744 ::collection::index unicode_case_insensitive_find_index(
const SCOPED_STRING& scopedstr, character_count start = 0) const RELEASENOTHROW
2747 return this->index_of(this->
operator()(start).unicode_case_insensitive_find(scopedstr));
2754 const_iterator unicode_rear_find(
const SCOPED_STRING& scopedstr)
const RELEASENOTHROW;
2756 const_iterator unicode_case_insensitive_rear_find(
const SCOPED_STRING& scopedstr)
const RELEASENOTHROW;
2767 const_iterator
find_first(CHARACTER chSeparator, ::character_count start = 0) const RELEASENOTHROW;
2830 using BASE_RANGE::_rear_skip;
2834 const_iterator _rear_skip(CHARACTER ca) const RELEASENOTHROW
2837 return this->_rear_skip(ca, ::comparison::comparison < CHARACTER >());
2841 using BASE_RANGE::rear_skip;
2844 const_iterator rear_skip(
CHARACTER ca)
const RELEASENOTHROW
2847 return this->rear_skip(ca, ::comparison::comparison < CHARACTER>());
2864 CHARACTER last_char(character_count count = -1)
const;
2867 inline character_count unichar_count()
const;
2869 inline const_iterator unichar_at(character_count iUnicharIndex)
const;
2891 inline bool operator==(const ::character_range < const CHARACTER* >& range)
const;
2893 template <
character_count n >
2894 inline bool operator==(
const CHARACTER(&s)[n])
const
2897 return this->equals(s);
2901 template <
typename OTHER_CHARACTER >
2902 inline bool operator==(const ::character_range < const OTHER_CHARACTER* >& range)
const
2903 requires other_primitive_character < OTHER_CHARACTER, CHARACTER >;
2907 inline bool operator==(const ::ansi_character* psz)
const {
return this->equals(psz); }
2909 inline bool operator==(const ::wd16_character* psz)
const {
return this->equals(psz); }
2911 inline bool operator==(const ::wd32_character* psz)
const {
return this->equals(psz); }
2913 inline bool operator==(const ::inline_number_string& inline_number_string)
const {
2914 return this->equals((
const SCOPED_STRING&)inline_number_string);
2946 bool xml_is_comment()
const;
2962 STRING surrounded(
const SCOPED_STRING& scopedstr)
const;
2964 STRING surrounded(
const SCOPED_STRING& scopedstrLeft,
const SCOPED_STRING& scopedstrRight)
const;
2966 STRING f64_quoted(
bool bEscape =
false)
const;
2968 STRING single_quoted(
bool bEscape)
const;
2971 STRING_ARRAY explode(
const SCOPED_STRING& scopedstrSeparator,
bool bAddEmpty =
true)
const;
2980 STRING_RANGE _get_count_parts_from_beginning(::collection::count cPathPartCountToConsume, CHARACTER chSeparator)
const
2983 auto range = this->operator()();
2985 auto cConsumed = cPathPartCountToConsume;
2987 range.m_begin =
range.__count_parts_from_beginning(cConsumed, chSeparator);
2989 if (cPathPartCountToConsume == cConsumed)
3016 THIS_RANGE right(character_count nCount)
const;
3018 THIS_RANGE left(character_count count)
const;
3020 THIS_RANGE left(const_iterator p)
const { return ::transfer(this->left(p - this->begin())); }
3022 THIS_RANGE left_including_any_character_in(
const SCOPED_STRING& scopedstrCharSet)
const;
3024 THIS_RANGE left_skipping_any_character_in(
const SCOPED_STRING& scopedstrCharSet)
const;
3029 inline ITERATOR_TYPE __count_parts_from_beginning(::collection::count & cPathMaxPartCount, CHARACTER chPartSeparator)
const
3032 ::collection::index i = 0;
3034 auto p = this->m_begin;
3036 for (; i < cPathMaxPartCount; i++)
3039 p = string_find_character(p, chPartSeparator);
3052 cPathMaxPartCount = i;