acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
const_string_range.h
1// From string_range.h by camilo on 2023-02-20 20:24 <3ThomasBorregaardSorensen!!
2#pragma once
3
4
5#include "acme/prototype/string/character_range.h"
6
7
8#include <algorithm>
9
10#define IMPLEMENT_TYPED_STRING_LITERAL(NAME, LITERAL) \
11template < typename T > consteval auto typed_##NAME() { throw "interface only for typed_" #NAME; return nullptr; } \
12template < > consteval auto typed_##NAME<::i8>() { return LITERAL; } \
13template < > consteval auto typed_##NAME<wchar_t>() { return L##LITERAL; } \
14template < > consteval auto typed_##NAME<char16_t>() { return u##LITERAL; } \
15template < > consteval auto typed_##NAME<char32_t>() { return U##LITERAL; }
16
17
18template<prototype_character CHARACTER>
19constexpr ::character_range<const CHARACTER *>
20inline _start_count_string_range(const CHARACTER *psz, memsize start, memsize count);
21
22//
23//template < typename T >
24//consteval auto typed_whitespace() { throw "interface onlye"; return nullptr; }
25//
26//template < >
27//consteval auto typed_whitespace<::i8>() { return "/t/r/n "; }
28//template < >
29//consteval auto typed_whitespace<wchar_t>() { return L"/t/r/n "; }
30//template < >
31//consteval auto typed_whitespace<char16_t>() { return u"/t/r/n "; }
32//template < >
33//consteval auto typed_whitespace<char32_t>() { return U"/t/r/n "; }
34IMPLEMENT_TYPED_STRING_LITERAL(whitespace, "\t\r\n ")
35
36
37#include "acme/prototype/collection/array_range.h"
38#include "acme/prototype/collection/comparable_eq_range.h"
39#include "acme/prototype/collection/comparable_range.h"
40#include "acme/prototype/collection/null_terminated_iterator.h"
41#include "acme/prototype/collection/null_terminated_range.h"
42
43
44template<typename ITERATOR_TYPE>
45class string_range;
46
47
48
49template < typename CHAR_POINTER >
51{
52
53 CHAR_POINTER end_of_line;
54 CHAR_POINTER next_line;
55
56};
57
58
59//template < typename ITERATOR_TYPE >
60//class scoped_string_base;
61
62
63
64
65
66
78template<typename ITERATOR_TYPE>
79class const_string_range :
80 //public ::comparable_range < ::comparable_eq_range < ::array_range < ::character_range < ITERATOR_TYPE > > > >
81 //public ::array_range < ::character_range < ITERATOR_TYPE > > >
82 public ::character_range<ITERATOR_TYPE> {
83public:
84
85 using BASE_RANGE = ::character_range<ITERATOR_TYPE>;
86 using RAW_CHARACTER_RANGE = typename BASE_RANGE::RAW_CHARACTER_RANGE;
87
88 //using BASE_RANGE = ::comparable_range < ::comparable_eq_range < ::array_range < ::character_range < ITERATOR_TYPE > > > >;
89
90 using THIS_RANGE = ::const_string_range<ITERATOR_TYPE>;
91
92 using STRING_RANGE = ::string_range<ITERATOR_TYPE>;
93
94
95 using ITEM_POINTER = get_type_item_pointer<ITERATOR_TYPE>;
96 using ITEM = non_const<dereference<ITEM_POINTER> >;
97 using CHARACTER = ITEM;
98
99 using BASE_DATA = BASE_RANGE::BASE_DATA;
100
101
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;
105
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;
109
110 //using ITEM_POINTER = typename get_type_item_pointer < this_iterator >::type;
111
112 //using ITEM = non_const < dereference < ITEM_POINTER > >;
113
114 using SCOPED_STRING = scoped_string_base<ITERATOR_TYPE>;
115
116
117 using ARG_ITEM = typename BASE_RANGE::ARG_ITEM;
118
119 using STRING = string_base < ITERATOR_TYPE >;
120
121 using STRING_ARRAY = ::string_base_array < STRING, STRING, e_type_string_array >;
122
123
124 const_string_range(no_initialize_t) : BASE_RANGE(no_initialize_t{}) {}
125
126 const_string_range(nullptr_t) : BASE_RANGE(nullptr) {}
127
128 const_string_range() {}
129
130
131 //template<character_count n>
132 //constexpr const_string_range(const CHARACTER(&s)[n]) :
133 // BASE_RANGE(no_initialize_t{})
134 //{
135
136 // if constexpr (n >= 1)
137 // {
138
139 // if (s[n - 1] == CHARACTER{})
140 // {
141
142 // this->m_begin = s;
143 // this->m_end = s + n - 1;
144 // this->m_erange = e_range_null_terminated
145 // | e_range_string_literal;
146
147 // return;
148
149 // }
150
151 // }
152
153 // this->m_begin = s;
154 // this->m_end = s + n;
155 // this->m_erange = e_range_none | e_range_string_literal;
156
157 //}
158
159
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)) {
163 }
164
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) { }
169
170 constexpr const_string_range(const const_string_range & range) :
171 BASE_RANGE(range.m_begin, range.m_end, range.m_erange) { }
172
173 constexpr const_string_range(const_string_range && range) :
174 BASE_RANGE(::transfer(range)) { }
175
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) { }
178
179 //explicit const_string_range(const ::atom& atom);
180
181 const_string_range(const ::block& block);
182
183 const_string_range(ITERATOR_TYPE psz) :
184 const_string_range(psz, string_safe_length(psz)) {}
185
186
187 const_string_range start_count(character_count start, character_count count = -1)
188 {
189
190 if (start > this->size())
191 {
192
193 return {};
194
195 }
196
197 character_count end;
198
199 if (count < 0)
200 {
201
202 end = this->size() + count + 1;
203
204 }
205 else
206 {
207
208 end = start + count;
209
210 }
211
212 if (end >= this->size())
213 {
214
215 return {};
216
217 }
218
219 auto erange = this->m_erange;
220
221 if (start != 0)
222 {
223
224 if (end != 0)
225 {
226
227 erange = e_range_none;
228
229 }
230 // else
231 // {
232 //
233 // erange = erange & ~e_range_string;
234 //
235 // }
236
237 }
238 else if (end != 0)
239 {
240
241 erange = e_range_none;
242
243 }
244
245 return {
246 this->m_begin + start,
247 this->m_begin + end,
248 erange};
249
250 }
251
252
253 ::collection::count length() const {return this->size();}
254
255
256 const_string_range & assign_bounded(ITERATOR_TYPE psz, character_count start, character_count count)
257 {
258
259 *this = ::_start_count_string_range(psz, start, count);
260
261 return *this;
262
263 }
264
265 const_string_range subrange(character_count iFirst) const;
266
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)); }
269
270
271
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); }
276
277 //auto this_range() const {return *this;}
278
279 //auto subrange(character_count start, character_count count) const { auto range = *this; ::_start_count_range(range, start, count); return range; }
280
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])
283 {
284 if constexpr (std::is_same_v<CHARACTER, ::i8>)
285 return c;
286 else if constexpr (std::is_same_v<CHARACTER, wchar_t>)
287 return w;
288 else if constexpr (std::is_same_v<CHARACTER, char16_t>)
289 return u16;
290 else if constexpr (std::is_same_v<CHARACTER, char32_t>)
291 return u32;
292 else
293 static_assert(sizeof(CHARACTER) == 0, "Unsupported character type");
294 }
295
296
297 //auto & last() { return ::get(this->end() - 1); }
298 auto& last() const { return (const CHARACTER&) ::get(this->end() - 1); }
299
300 auto& last(::collection::index i) const { return (const CHARACTER&) ::get(this->end() - 1 - i); }
301
302 auto last_index() const { return this->size() - 1; }
303
304 auto last_index(::collection::index i) const { return this->size() - 1 - i; }
305
306 bool is_trimmed_empty() const;
307
308 //void clear()
309 //{
310 //this->m_begin=nullptr;
311 //this->m_end = nullptr;
312 //this->m_erange = e_range_none;
313 //}
314
315
316 constexpr THIS_RANGE _begin_set(ITERATOR_TYPE pbegin) const
317 {
318
319 return THIS_RANGE{
320 pbegin,
321 this->m_end,
322 (enum_range)this->m_erange,
323 this->m_pbasedata
324 };
325
326 }
327
328
329 constexpr THIS_RANGE begin_set(ITERATOR_TYPE pbegin) const
330 {
331
332 if (pbegin < this->m_begin)
333 {
334
335 throw "pbegin < this->m_begin";
336
337 }
338 else if (pbegin > this->m_end)
339 {
340
341 throw "pbegin > this->m_end";
342
343 }
344
345 return _begin_set(pbegin);
346
347 }
348
349
350 constexpr THIS_RANGE _end_set(ITERATOR_TYPE pend) const
351 {
352
353 return pend == this->m_end ?
354 *this :
355 THIS_RANGE{
356 this->m_begin,
357 pend,
358 e_range_none
359 }
360 ;
361
362 }
363
364
365 constexpr THIS_RANGE end_set(ITERATOR_TYPE pend) const
366 {
367
368 if (pend < this->m_begin)
369 {
370
371 throw "pend < this->m_begin";
372
373 }
374 else if (pend > this->m_end)
375 {
376
377 throw "pend > this->m_end";
378
379 }
380
381 return _end_set(pend);
382
383 }
384
385
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
390 {
391 return ::_start_end_range(STRING_RANGE(*this), start, end);
392 }
393 template < typed_character_pointer < typename const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
394 STRING_RANGE operator()(CHARACTER_POINTER start) const
395 {
396 return STRING_RANGE(start, this->end());
397 }
398 template < prototype_integral START >
399 STRING_RANGE operator()(START start) const;
400 STRING_RANGE operator()() const;
401
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); }
410 //STRING_RANGE operator()() const;
411
412 ::end_of_line_and_next_line < const CHARACTER* > end_of_line_and_next_line() const
413 {
414
415 ::end_of_line_and_next_line < const CHARACTER* > pair;
416
417 pair.end_of_line = this->find_first_character_in("\r\n\0");
418
419 pair.next_line = pair.end_of_line;
420
421 if (!*pair.next_line)
422 {
423
424 pair.next_line = nullptr;
425
426 }
427 else if (*pair.next_line == '\r')
428 {
429
430 pair.next_line++;
431
432 if (*pair.next_line == '\n')
433 {
434
435 pair.next_line++;
436
437 }
438
439 }
440 else if (*pair.next_line == '\n')
441 {
442
443 pair.next_line++;
444
445 }
446 else
447 {
448
449 throw_exception(error_failed);
450
451 }
452
453 return pair;
454
455 }
456
457
458 constexpr bool has_character() const { return !this->is_empty(); }
459
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); }
462
463 //inline bool has_character() const noexcept { return !this->is_empty(); }
464 inline character_count get_upper_bound(character_count i = -1) const noexcept { return this->size() + i; }
465
466 operator ::block() const { return { (::u8*)this->m_begin, this->length_in_bytes() }; }
467
468 inline CHARACTER _character_at(character_count i) const { return this->data()[i]; }
469 inline CHARACTER character_at(character_count i) const
470 {
471 return i < 0 || i >= this->size() ? CHARACTER{} : this->_character_at(i);
472 }
473
474
475
476
477
478 //inline CHARACTER *data() { return (CHARACTER *) this->begin(); }
479
480 inline const CHARACTER* data() const { return this->begin(); }
481
482 inline operator const CHARACTER* () const { return this->data(); }
483
484 //inline operator CHARACTER *() { return this->data(); }
485
486 //inline const CHARACTER *ptr_at(::collection::index i) { return this->data() + i; }
487
488 inline const CHARACTER* address_at(::collection::index i) const { return this->data() + i; }
489
490 //inline const CHARACTER *reverse_ptr(::collection::index i) { return this->data() + this->size() + i; }
491
492 inline const CHARACTER* rear_address(::collection::index i) const { return this->end() + i; }
493
494 inline const CHARACTER& operator[](::collection::index i) const { return this->data()[i]; }
495
496 character_count index_of(const CHARACTER* p) const { return ::index_of(p, data()); }
497
498
499 const_string_range trimmed_left() const
500 {
501
502 return _begin_set(skip_any_character_in(typed_whitespace<CHARACTER>()));
503
504 }
505
506
507 const_string_range trimmed_left(const SCOPED_STRING& scopedstr) const
508 {
509
510 return _begin_set(skip_any_character_in(scopedstr));
511
512 }
513
514
515 const_string_range trimmed_right() const
516 {
517
518 return _end_set(rear_skip_any_character_in(typed_whitespace<CHARACTER>()));
519
520 }
521
522
523 const_string_range trimmed_right(const SCOPED_STRING & scopedstr) const
524 {
525
526 return _end_set(rear_skip_any_character_in(scopedstr));
527
528 }
529
530
531 const_string_range trimmed() const
532 {
533
534 return trimmed_right().trimmed_left();
535
536 }
537
538
539 constexpr bool _is_p_in_range(ITERATOR_TYPE p) const
540 {
541
542 return p >= this->m_begin && p <= this->m_begin;
543
544 }
545
546
547 const_string_range & trim_left(const SCOPED_STRING& scopedstrAnyPrefixCharacterToTrim)
548 {
549
550 ASSERT(this->is_working_string_range());
551
552 auto pszBegin = this->skip_any_character_in(scopedstrAnyPrefixCharacterToTrim);
553
554 if (pszBegin
555 && pszBegin != this->m_begin
556 && this->_is_p_in_range(pszBegin))
557 {
558
559 this->m_begin = pszBegin;
560
561 }
562
563 return *this;
564
565 }
566
567
568 const_string_range& trim_left()
569 {
570
571 return this->trim_left(::typed_whitespace < CHARACTER >());
572
573 }
574
575
576 const_string_range & trim_right(const SCOPED_STRING& scopedstrAnySuffixCharacterToTrim)
577 {
578
579 ASSERT(this->is_working_string_range());
580
581 auto pszEnd = this->rear_skip_any_character_in(scopedstrAnySuffixCharacterToTrim);
582
583 if (pszEnd
584 && pszEnd != this->m_end
585 && this->_is_p_in_range(pszEnd))
586 {
587
588 this->m_end = pszEnd;
589
590 }
591
592 return *this;
593
594 }
595
596
597 const_string_range& trim_right()
598 {
599
600 return this->trim_right(::typed_whitespace < CHARACTER >());
601
602 }
603
604
605 const_string_range & trim(
606 const SCOPED_STRING& scopedstrAnyPrefixCharacterToTrim,
607 const SCOPED_STRING& scopedstrAnySuffixCharacterToTrim)
608 {
609
610 return trim_right(scopedstrAnySuffixCharacterToTrim).
611 trim_left(scopedstrAnyPrefixCharacterToTrim);
612
613 }
614
615
616 const_string_range& trim()
617 {
618
619 return trim_right().trim_left();
620
621 }
622
623
624 bool defer_trim(const SCOPED_STRING& scopedstrAnyPrefixCharacterToTrim, const SCOPED_STRING& scopedstrAnySuffixCharacterToTrim)
625 {
626
627 ASSERT(this->is_working_string_range());
628
629 auto pszCandidateBegin = this->skip_any_character_in(scopedstrAnyPrefixCharacterToTrim);
630
631 auto pszCandidateEnd = this->rear_skip_any_character_in(scopedstrAnySuffixCharacterToTrim);
632
633 if (pszCandidateBegin <= this->m_begin
634 || pszCandidateEnd >= this->m_end)
635 {
636
637 return false;
638
639 }
640
641 this->m_begin = pszCandidateBegin;
642
643 this->m_end = pszCandidateEnd;
644
645 return *this;
646
647 }
648
649
650
651 const_string_range trimmed(const SCOPED_STRING& scopedstr) const
652 {
653
654 return trimmed_right(scopedstr).trimmed_left(scopedstr);
655
656 }
657
658
659 // string_range &operator=(const THIS_RANGE &range)
660 // {
661 // BASE_RANGE::operator=(range);
662 // return *this;
663 // }
664 //
665 // string_range &operator=(string_range &&range) {
666 // BASE_RANGE::operator=(::transfer(range));
667 // return *this;
668 // }
669
670 // string_range &operator=(const atom &atom);
671 //
672 // string_range &operator=(const block &block);
673 //
674
675 THIS_RANGE get_utf8_char() const;
676
677
678 //::std::strong_ordering order(const string_range &range) const noexcept;
679 //using NATURAL_POINTER::order;
680
681 //::std::strong_ordering order(const SCOPED_STRING &range) const noexcept;
682 //::std::strong_ordering case_insensitive_order(const SCOPED_STRING& range) const noexcept;
683
684 ::std::strong_ordering collate(const SCOPED_STRING& range) const noexcept;
685
686 ::std::strong_ordering case_insensitive_collate(const SCOPED_STRING& range) const noexcept;
687
688 //::std::strong_ordering order(const SCOPED_STRING &range, character_count n) const noexcept;
689
690 //::std::strong_ordering case_insensitive_order(const SCOPED_STRING &range, character_count n) const noexcept;
691
692 //::std::strong_ordering collate(const SCOPED_STRING &range, character_count n) const noexcept;
693
694 //::std::strong_ordering case_insensitive_collate(const SCOPED_STRING &range, character_count n) const noexcept;
695
696 //::std::strong_ordering order(character_count start, character_count count, const SCOPED_STRING &range) const noexcept;
697
698 //::std::strong_ordering case_insensitive_order(character_count start, character_count count, const SCOPED_STRING &range) const noexcept;
699
700 //::std::strong_ordering collate(character_count start, character_count count, const SCOPED_STRING &range) const noexcept;
701
702 //::std::strong_ordering
703 //case_insensitive_collate(character_count start, character_count count, const SCOPED_STRING &range) const noexcept;
704
705 //::std::strong_ordering
706 //order(character_count start, character_count count, const SCOPED_STRING &range, character_count iStart2, character_count iCount2) const noexcept;
707
708 //::std::strong_ordering
709 //case_insensitive_order(character_count start, character_count count, const SCOPED_STRING &range, character_count iStart2,
710 // character_count iCount2) const noexcept;
711
712 //::std::strong_ordering
713 //collate(character_count start, character_count count, const SCOPED_STRING &range, character_count iStart2, character_count iCount2) const noexcept;
714
715 //::std::strong_ordering
716 //case_insensitive_collate(character_count start, character_count count, const SCOPED_STRING &range, character_count iStart2,
717 // character_count iCount2) const noexcept;
718
719 //inline ::i32 operator<=>(const string_range &range) const { return order(range); }
720 //inline bool operator==(const string_range &range) const { return size() != range.size() ? false : !order(range); }
721 //inline bool operator>(const string_range &range) const { return order(ansistr) > 0; }
722 //inline bool operator<(const string_range &range) const { return order(ansistr) < 0; }
723 //inline bool operator!=(const string_range &range) const { return !operator ==(ansistr); }
724 //inline bool operator>=(const string_range &range) const { return !operator <(ansistr); }
725 //inline bool operator<=(const string_range &range) const { return !operator >(ansistr); }
726
727
728 //inline bool operator==(const string_range &range) const { return order(ansistr) == 0; }
729 //inline bool operator>(const string_range &range) const { return order(ansistr) > 0; }
730 //inline bool operator<(const string_range &range) const { return order(ansistr) < 0; }
731 //inline bool operator!=(const string_range &range) const { return !operator ==(ansistr); }
732 //inline bool operator>=(const string_range &range) const { return !operator <(ansistr); }
733 //inline bool operator<=(const string_range &range) const { return !operator >(ansistr); }
734
735 inline bool operator==(const THIS_RANGE& range) const { return this->equals(range); }
736 //inline ::std::strong_ordering operator<=>(const SCOPED_STRING &range) const { return this->order(range); }
737
738
739
740
741 using BASE_RANGE::_order;
742
743 constexpr ::std::strong_ordering _order(const SCOPED_STRING& range) const
744 {
745
746 return _order(range, ::comparison::comparison<ITEM>());
747
748 }
749
750
751 using BASE_RANGE::order;
752
753 //constexpr ::std::strong_ordering order(const SCOPED_STRING& range) const noexcept;
754
755
756 constexpr ::std::strong_ordering operator<=>(const SCOPED_STRING& range) const {
757
758 return this->order(range);
759
760 }
761
762
763 template < typed_character_range < CHARACTER > CHARACTER_RANGE >
764 constexpr bool equals(const CHARACTER_RANGE& range) const
765 {
766
767 auto sizeRange = this->size();
768
769 if (this->is_this_range(range))
770 {
771
772 return true;
773
774 }
775
776 return sizeRange != range.size() ? false :
777 (sizeRange <= 0 ?
778 true :
779 _string_count_compare(this->m_begin, range.m_begin, sizeRange) == 0
780 );
781
782 }
783
784
785 template < typed_character_pointer < CHARACTER > CHARACTER_POINTER >
786 constexpr bool equals(CHARACTER_POINTER psz) const
787 {
788
789 auto sizeThis = this->size();
790
791 if (psz == this->m_begin)
792 {
793
794 return sizeThis == string_safe_length(psz);
795
796 }
797
798 return _string_count_compare(this->m_begin, psz, sizeThis) == 0
799 && psz[sizeThis] == CHARACTER{};
800
801 }
802
803
804 constexpr bool has_file_extension_without_dot(const SCOPED_STRING& scopedstrFileExtensionWithoutDot) const
805 {
806
807 if (this->character_at(this->size() - scopedstrFileExtensionWithoutDot.size() - 1) != '.')
808 {
809
810 return false;
811
812 }
813
814 if (!this->case_insensitive_ends(scopedstrFileExtensionWithoutDot))
815 {
816
817 return false;
818
819 }
820
821 return true;
822
823 }
824
825
826 constexpr bool equals(const SCOPED_STRING& scopedstr) const
827 {
828
829 auto sizeRange = this->size();
830
831 return sizeRange != scopedstr.size() ? false :
832 (sizeRange <= 0 ?
833 true :
834 _string_count_compare(this->m_begin, scopedstr.m_begin, sizeRange) == 0
835 );
836
837 }
838
839
840 template < typed_character_range < CHARACTER > CHARACTER_RANGE >
841 constexpr bool case_insensitive_equals(const CHARACTER_RANGE& range) const
842 {
843
844 auto sizeRange = this->size();
845
846 return sizeRange != range.size() ? false :
847 (sizeRange <= 0 ?
848 true :
849 _case_insensitive_string_count_compare(this->m_begin, range.m_begin, sizeRange) == 0
850 );
851
852 }
853
854
855 template < typed_character_pointer < CHARACTER > CHARACTER_POINTER >
856 constexpr bool case_insensitive_equals(CHARACTER_POINTER psz) const
857 {
858
859 auto sizeThis = this->size();
860
861 if (this->is_empty())
862 {
863
864 if (::is_empty(psz))
865 {
866
867 return true;
868
869 }
870 else
871 {
872
873 return false;
874
875 }
876
877 }
878 else if (::is_empty(psz))
879 {
880
881 return false;
882
883 }
884 else if (0 != _case_insensitive_string_count_compare(this->m_begin, psz, sizeThis))
885 {
886
887 return false;
888
889 }
890 else if (psz[sizeThis] != CHARACTER{})
891 {
892
893 return false;
894
895 }
896 else
897 {
898
899 return true;
900
901 }
902
903 }
904
905
906 constexpr bool case_insensitive_equals(const SCOPED_STRING& scopedstr) const
907 {
908
909 auto sizeRange = this->size();
910
911 return sizeRange != scopedstr.size() ? false :
912 (sizeRange <= 0 ?
913 true :
914 _case_insensitive_string_count_compare(this->m_begin, scopedstr.m_begin, sizeRange) == 0
915 );
916
917 }
918
919
920
921 template < typed_character_range < CHARACTER > CHARACTER_RANGE >
922 constexpr ::i32 compare(const CHARACTER_RANGE& range) const
923 {
924
925 auto sizeThis = this->size();
926
927 ::i32 iOrdering = 0;
928
929 return this->is_empty() ?
930 (range.is_empty() ? 0 :
931 -1) :
932 (range.is_empty() ? 1 :
933 ((iOrdering = _string_count_compare(this->m_begin, range.begin(), sizeThis)) == 0 ?
934 ::compare(sizeThis, range.size()) : iOrdering));
935
936 }
937
938
939 template < typed_character_pointer < CHARACTER > CHARACTER_POINTER >
940 constexpr ::i32 compare(CHARACTER_POINTER psz) const
941 {
942
943 auto sizeThis = this->size();
944
945 ::i32 iOrdering = 0;
946
947 return this->is_empty() ?
948 (::is_empty(psz) ? 0 :
949 -1) :
950 (::is_empty(psz) ? 1 :
951 ((iOrdering = _string_count_compare(this->m_begin, psz, sizeThis)) == 0 ?
952 (psz[sizeThis] == CHARACTER{} ?
953 0 :
954 -1)
955 : iOrdering));
956 }
957
958
959 constexpr ::i32 compare(const SCOPED_STRING& scopedstr) const
960 {
961
962 auto sizeThis = this->size();
963
964 ::i32 iOrdering = 0;
965
966 return this->is_empty() ?
967 (scopedstr.is_empty() ? 0 :
968 -1) :
969 (scopedstr.is_empty() ? 1 :
970 ((iOrdering = _string_count_compare(this->m_begin, scopedstr.m_begin, sizeThis)) == 0
971 ?
972 ::compare(sizeThis, scopedstr.size()) : iOrdering));
973
974 }
975
976
977 template < typed_character_range < CHARACTER > CHARACTER_RANGE >
978 constexpr ::i32 case_insensitive_compare(const CHARACTER_RANGE& range) const
979 {
980
981 auto sizeThis = this->size();
982
983 ::i32 iOrdering = 0;
984
985 return this->is_empty() ?
986 (range.is_empty() ? 0 :
987 -1) :
988 (range.is_empty() ? 1 : ((iOrdering = _case_insensitive_string_count_compare(
989 this->m_begin, range.begin(), sizeThis)) == 0
990 ? ::compare(sizeThis, range.size())
991 : iOrdering));
992
993 }
994
995
996 template < typed_character_pointer < CHARACTER > CHARACTER_POINTER >
997 constexpr ::i32 case_insensitive_compare(CHARACTER_POINTER psz) const
998 {
999
1000 auto sizeThis = this->size();
1001
1002 ::i32 iOrdering = 0;
1003
1004 return this->is_empty() ?
1005 (::is_empty(psz) ? 0 :
1006 -1) :
1007 (::is_empty(psz) ? 1 : ((iOrdering = _case_insensitive_string_count_compare(this->m_begin, psz, sizeThis)) == 0
1008 ?
1009 (psz[sizeThis] == CHARACTER{}?
1010 0 :
1011 -1)
1012 : iOrdering));
1013
1014 }
1015
1016
1017 constexpr ::i32 case_insensitive_compare(const SCOPED_STRING& scopedstr) const
1018 {
1019
1020 auto sizeThis = this->size();
1021
1022 ::i32 iOrdering = 0;
1023
1024 return this->is_empty() ?
1025 (scopedstr.is_empty() ? 0 :
1026 -1) :
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())
1030 : iOrdering));
1031
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 template < typed_character_range < CHARACTER > CHARACTER_RANGE >
1101 constexpr ::std::strong_ordering order(const CHARACTER_RANGE& range) const
1102 {
1103
1104 return this->compare(range) <=> 0;
1105//
1106// auto sizeThis = this->size();
1107//
1108// ::std::strong_ordering ordering(1<=>1);
1109//
1110// return this->is_empty() ?
1111// (range.is_empty() ? ::std::strong_ordering::equal :
1112// ::std::strong_ordering::less) :
1113// (range.is_empty() ? ::std::strong_ordering::greater :
1114// ((ordering = _string_count_compare(this->m_begin, range.begin(), sizeThis)) == 0 ?
1115// sizeThis <=> range.size() : ordering));
1116
1117 }
1118
1119
1120 template < typed_character_pointer < CHARACTER > CHARACTER_POINTER >
1121 constexpr ::std::strong_ordering order(CHARACTER_POINTER psz) const
1122 {
1123
1124 return this->compare(psz) <=> 0;
1125
1126// auto sizeThis = this->size();
1127//
1128// ::std::strong_ordering ordering(1<=>1);
1129//
1130// return this->is_empty() ?
1131// (::is_empty(psz) ? ::std::strong_ordering::equal :
1132// ::std::strong_ordering::less) :
1133// (::is_empty(psz) ? ::std::strong_ordering::greater :
1134// ((ordering = _string_count_compare(this->m_begin, psz, sizeThis)) == 0 ?
1135// (psz[sizeThis] == CHARACTER{} ?
1136// ::std::strong_ordering::equal :
1137// ::std::strong_ordering::less)
1138// : ordering));
1139 }
1140
1141
1142 constexpr ::std::strong_ordering order(const SCOPED_STRING& scopedstr) const
1143 {
1144
1145 return this->compare(scopedstr) <=> 0;
1146//
1147// auto sizeThis = this->size();
1148//
1149// ::std::strong_ordering ordering(1<=>1);
1150//
1151// return this->is_empty() ?
1152// (scopedstr.is_empty() ? ::std::strong_ordering::equal :
1153// ::std::strong_ordering::less) :
1154// (scopedstr.is_empty() ? ::std::strong_ordering::greater :
1155// ((ordering = _string_count_compare(this->m_begin, scopedstr.m_begin, sizeThis)) == 0 ?
1156// sizeThis <=> scopedstr.size() : ordering));
1157
1158 }
1159
1160
1161 template < typed_character_range < CHARACTER > CHARACTER_RANGE >
1162 constexpr ::std::strong_ordering case_insensitive_order(const CHARACTER_RANGE& range) const
1163 {
1164
1165 return this->case_insensitive_compare(range) <=> 0;
1166// auto sizeThis = this->size();
1167//
1168// ::std::strong_ordering ordering(1<=>1);
1169//
1170// return this->is_empty() ?
1171// (range.is_empty() ? ::std::strong_ordering::equal :
1172// ::std::strong_ordering::less) :
1173// (range.is_empty() ? ::std::strong_ordering::greater :
1174// ((ordering = _case_insensitive_string_count_compare(this->m_begin, range.begin(), sizeThis)) == 0 ?
1175// sizeThis <=> range.size() : ordering));
1176
1177 }
1178
1179
1180 template < typed_character_pointer < CHARACTER > CHARACTER_POINTER >
1181 constexpr ::std::strong_ordering case_insensitive_order(CHARACTER_POINTER psz) const
1182 {
1183
1184 return this->case_insensitive_compare(psz) <=> 0;
1185// auto sizeThis = this->size();
1186//
1187// ::std::strong_ordering ordering(1<=>1);
1188//
1189// return this->is_empty() ?
1190// (::is_empty(psz) ? ::std::strong_ordering::equal :
1191// ::std::strong_ordering::less) :
1192// (::is_empty(psz) ? ::std::strong_ordering::greater :
1193// ((ordering = _case_insensitive_string_count_compare(this->m_begin, psz, sizeThis)) == 0 ?
1194// (psz[sizeThis] == CHARACTER{}?
1195// ::std::strong_ordering::equal :
1196// ::std::strong_ordering::less)
1197// : ordering));
1198
1199 }
1200
1201
1202 constexpr ::std::strong_ordering case_insensitive_order(const SCOPED_STRING& scopedstr) const
1203 {
1204
1205 return this->case_insensitive_compare(scopedstr) <=> 0;
1206
1207// auto sizeThis = this->size();
1208//
1209// ::std::strong_ordering ordering(1<=>1);
1210//
1211// return this->is_empty() ?
1212// (scopedstr.is_empty() ? ::std::strong_ordering::equal :
1213// ::std::strong_ordering::less) :
1214// (scopedstr.is_empty() ? ::std::strong_ordering::greater :
1215// ((ordering = _case_insensitive_string_count_compare(this->m_begin, scopedstr.m_begin, sizeThis)) == 0 ?
1216// sizeThis <=> scopedstr.size() : ordering));
1217
1218 }
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230 //using BASE_RANGE::_equals;
1231
1232 //constexpr bool _equals(const SCOPED_STRING& range) const {
1233
1234 // return this->binary_equals(range);
1235
1236 //}
1237
1238
1239 //using BASE_RANGE::equals;
1240
1241 //constexpr bool equals(const SCOPED_STRING& range) const {
1242
1243 // return this->binary_equals(range);
1244
1245 //}
1246
1247 //constexpr bool case_insensitive_equals(const SCOPED_STRING& range) const noexcept {
1248
1249 // return this->equals(range, ::comparison::case_insensitive<ITEM>());
1250
1251 //}
1252
1253 //bool equals(const SCOPED_STRING &range, character_count n) const noexcept {
1254
1255 // return this->equals_start_count(range, 0, n, ::comparison::comparison<ITEM>());
1256
1257 //}
1258
1259 //bool case_insensitive_equals(const SCOPED_STRING &range, character_count n) const noexcept {
1260
1261 // return this->equals_start_count(range, 0, n, ::comparison::case_insensitive<ITEM>());
1262
1263 //}
1264
1265 //bool equals(character_count start, character_count count, const SCOPED_STRING &range) const noexcept {
1266
1267 // return this->equals_start_count(range, start, count, ::comparison::comparison<ITEM>());
1268
1269 //}
1270
1271 //bool case_insensitive_equals(character_count start, character_count count, const SCOPED_STRING &range) const noexcept {
1272
1273 // return this->equals_start_count(range, start, count, ::comparison::case_insensitive<ITEM>());
1274
1275 //}
1276
1277 //bool
1278 //equals(character_count start, character_count count, const SCOPED_STRING &range, character_count iStart2, character_count iCount2) const noexcept {
1279
1280 // return this->equals_start_count(range.start_count(iStart2, iCount2), start, count,
1281 // ::comparison::comparison<ITEM>());
1282
1283 //}
1284
1285 //bool case_insensitive_equals(character_count start, character_count count, const SCOPED_STRING &range, character_count iStart2,
1286 // character_count iCount2) const noexcept {
1287
1288 // return this->equals_start_count(range.start_count(iStart2, iCount2), start, count,
1289 // ::comparison::case_insensitive<ITEM>());
1290
1291 //}
1292
1293
1294
1295// using BASE_RANGE::_equals_start;
1296//
1297// constexpr bool _equals_start(const SCOPED_STRING & range, memsize start) const
1298// {
1299//
1300// return this->_equals_start(range, start, ::comparison::comparison < ITEM >());
1301//
1302// }
1303//
1304//
1305// using BASE_RANGE::equals_start;
1306//
1307// constexpr bool equals_start(const SCOPED_STRING & range, memsize start) const
1308// {
1309//
1310// return this->equals_start(range, start, ::comparison::comparison < ITEM >());
1311//
1312// }
1313//
1314//
1315// using BASE_RANGE::_equals_start_count;
1316//
1317// constexpr bool _equals_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1318// {
1319//
1320// return this->_equals_start_count(range, start, count, ::comparison::comparison < ITEM >());
1321//
1322// }
1323//
1324//
1325// using BASE_RANGE::equals_start_count;
1326//
1327// constexpr bool equals_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1328// {
1329//
1330// return this->equals_start_count(range, start, count, ::comparison::comparison < ITEM >());
1331//
1332// }
1333//
1334
1335 using BASE_RANGE::_find;
1336
1337 constexpr const_iterator _find(const SCOPED_STRING& range) const {
1338
1339 return this->_find(range, ::comparison::comparison<ITEM>());
1340
1341 }
1342
1343
1344 using BASE_RANGE::find;
1345
1346 constexpr const_iterator find(const SCOPED_STRING& range) const {
1347
1348 return this->find(range, ::comparison::comparison<ITEM>());
1349
1350 }
1351 constexpr character_count find_index(const SCOPED_STRING& range, character_count start = 0) const
1352 {
1353
1354 return this->index_of(start <= 0 ? this->find(range) : (*this)(start).find(range));
1355
1356 }
1357 constexpr character_count find_index(CHARACTER ch, character_count start = 0) const
1358 {
1359
1360 return this->index_of(start <= 0 ? this->find(ch) : (*this)(start).find(ch));
1361
1362 }
1363
1364
1365 // using BASE_RANGE::_find_start;
1366 //
1367 // constexpr const_iterator _find_start(const SCOPED_STRING & range, memsize start) const
1368 // {
1369 //
1370 // return this->_find_start(range, start, ::comparison::comparison < ITEM >());
1371 //
1372 // }
1373 //
1374 //
1375 // using BASE_RANGE::find_start;
1376 //
1377 // constexpr const_iterator find_start(const SCOPED_STRING & range, memsize start) const
1378 // {
1379 //
1380 // return this->find_start(range, start, ::comparison::comparison < ITEM >());
1381 //
1382 // }
1383 //
1384 //
1385 // using BASE_RANGE::_find_start_count;
1386 //
1387 // constexpr const_iterator _find_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1388 // {
1389 //
1390 // return this->_find_start_count(range, start, count, ::comparison::comparison < ITEM >());
1391 //
1392 // }
1393 //
1394 //
1395 // using BASE_RANGE::find_start_count;
1396 //
1397 // constexpr const_iterator find_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1398 // {
1399 //
1400 // return this->find_start_count(range, start, count, ::comparison::comparison < ITEM >());
1401 //
1402 // }
1403
1404
1405 using BASE_RANGE::_rear_find;
1406
1407 constexpr const_iterator _rear_find(const SCOPED_STRING& range, const_iterator end = nullptr) const
1408 {
1409
1410 return (*this)(0, ::is_null(end) ? this->end() : end)._rear_find(range, ::comparison::comparison<ITEM>());
1411
1412 }
1413
1414
1415 using BASE_RANGE::rear_find;
1416
1417 constexpr const_iterator rear_find(const SCOPED_STRING& range, const_iterator end = nullptr) const
1418 {
1419
1420 return (*this)(0, ::is_null(end) ? this->end() : end).rear_find(range, ::comparison::comparison<ITEM>());
1421
1422 }
1423
1424 constexpr character_count _rear_find_index(const SCOPED_STRING& range, character_count end = -1) const
1425 {
1426
1427 return this->index_of((*this)(0, end >= 0 ? end : this->size() + end + 1)._rear_find(range));
1428
1429 }
1430
1431
1432 constexpr character_count rear_find_index(const SCOPED_STRING& range, character_count end = -1) const
1433 {
1434
1435 return this->index_of((*this)(0, end >= 0 ? end : this->size() + end + 1).rear_find(range));
1436
1437 }
1438
1439
1440 constexpr const_iterator _rear_find(CHARACTER character, const_iterator end = nullptr) const
1441 {
1442
1443 return (*this)(0, ::is_null(end) ? this->end() : end).rear_find(character, ::comparison::comparison<ITEM>());
1444
1445 }
1446
1447
1448 constexpr const_iterator rear_find(CHARACTER character, const_iterator end = nullptr) const
1449 {
1450
1451 return (*this)(0, ::is_null(end) ? this->end() : end).rear_find(character, ::comparison::comparison<ITEM>());
1452
1453 }
1454
1455
1456 constexpr character_count _rear_find_index(CHARACTER character, character_count end = -1) const
1457 {
1458
1459 return this->index_of((*this)(0, end >= 0 ? end : this->size() + end + 1)._rear_find(character));
1460
1461 }
1462
1463
1464 constexpr character_count rear_find_index(CHARACTER character, character_count end = -1) const
1465 {
1466
1467 return this->index_of((*this)(0, end >= 0 ? end : this->size() + end + 1).rear_find(character));
1468
1469 }
1470
1471
1472 const_iterator case_insensitive_find(const SCOPED_STRING& scopedstr) const RELEASENOTHROW
1473 {
1474
1475 return this->find(scopedstr, ::comparison::case_insensitive<ITEM>());
1476
1477 }
1478
1479
1480 character_count case_insensitive_find_index(const SCOPED_STRING& scopedstr) const RELEASENOTHROW
1481 {
1482
1483 return this->index_of(case_insensitive_find(scopedstr));
1484
1485 }
1486
1487
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)); }
1489
1490
1491 constexpr const_iterator _case_insensitive_rear_find(const SCOPED_STRING& scopedstr) const
1492 {
1493
1494 return this->_rear_find(scopedstr, ::comparison::case_insensitive<ITEM>());
1495
1496 }
1497
1498
1499 character_count _case_insensitive_rear_find_index(const SCOPED_STRING& scopedstr, character_count end = -1) const RELEASENOTHROW
1500 {
1501
1502 return this->index_of((*this)(0, end >= 0 ? end : this->size() + end + 1)._case_insensitive_rear_find(scopedstr));
1503
1504 }
1505
1506
1507 constexpr const_iterator case_insensitive_rear_find(const SCOPED_STRING& scopedstr) const
1508 {
1509
1510 return this->rear_find(scopedstr, ::comparison::case_insensitive<ITEM>());
1511
1512 }
1513
1514
1515 character_count case_insensitive_rear_find_index(const SCOPED_STRING& scopedstr, character_count end = -1) const RELEASENOTHROW
1516 {
1517
1518
1519 return this->index_of((*this)(0, end >= 0 ? end : this->size() + end + 1).case_insensitive_rear_find(scopedstr));
1520
1521 }
1522
1523
1524 // using BASE_RANGE::_rear_find_start;
1525 //
1526 // constexpr const_iterator _rear_find_start(const SCOPED_STRING & range, memsize start) const
1527 // {
1528 //
1529 // return this->_rear_find_start(range, start, ::comparison::comparison < ITEM >());
1530 //
1531 // }
1532 //
1533 //
1534 // using BASE_RANGE::rear_find_start;
1535 //
1536 // constexpr const_iterator rear_find_start(const SCOPED_STRING & range, memsize start) const
1537 // {
1538 //
1539 // return this->rear_find_start(range, start, ::comparison::comparison < ITEM >());
1540 //
1541 // }
1542 //
1543 //
1544 // using BASE_RANGE::_rear_find_start_count;
1545 //
1546 // constexpr const_iterator _rear_find_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1547 // {
1548 //
1549 // return this->_rear_find_start_count(range, start, count, ::comparison::comparison < ITEM >());
1550 //
1551 // }
1552 //
1553 //
1554 // using BASE_RANGE::rear_find_start_count;
1555 //
1556 // constexpr const_iterator rear_find_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1557 // {
1558 //
1559 // return this->rear_find_start_count(range, start, count, ::comparison::comparison < ITEM >());
1560 //
1561 // }
1562
1563
1564 using BASE_RANGE::_find_first_character;
1565
1566 constexpr const_iterator _find_first_character(CHARACTER ch) const {
1567
1568 return this->_find_first_character(ch, ::comparison::comparison<ITEM>());
1569
1570 }
1571
1572 constexpr character_count _find_first_character_index(CHARACTER ch) const {
1573 return this->index_of(_find_first_character(ch));
1574 }
1575
1576 using BASE_RANGE::find_first_character;
1577
1578 constexpr const_iterator find_first_character(CHARACTER ch) const {
1579
1580 return this->find_first_character(ch, ::comparison::comparison<ITEM>());
1581
1582 }
1583
1584 using BASE_RANGE::_find_first_character_in;
1585
1586 constexpr const_iterator _find_first_character_in(const SCOPED_STRING& range) const {
1587
1588 return this->_find_first_character_in(range, ::comparison::comparison<ITEM>());
1589
1590 }
1591
1592 constexpr character_count _find_first_character_in_index(const SCOPED_STRING& range) const {
1593 return this->index_of(_find_first_character_in(range));
1594 }
1595
1596 using BASE_RANGE::find_first_character_in;
1597
1598 constexpr const_iterator find_first_character_in(const SCOPED_STRING& range) const {
1599
1600 return this->find_first_character_in(range, ::comparison::comparison<ITEM>());
1601
1602 }
1603
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));
1606 }
1607
1608 constexpr bool contains_any_character_in(const SCOPED_STRING& range) const {
1609
1610 return ::found(this->find_first_character_in(range));
1611
1612 }
1613
1614
1615 // Convert the string_base < ITERATOR_TYPE > to lowercase
1616 //template < typename ITERATOR_TYPE >
1617 string_base < ITERATOR_TYPE > lowered() const;
1618 string_base < ITERATOR_TYPE > uppered() const;
1619
1620
1621 // using BASE_RANGE::_find_first_character_in_start;
1622 //
1623 // constexpr const_iterator _find_first_character_in_start(const SCOPED_STRING & range, memsize start) const
1624 // {
1625 //
1626 // return this->_find_first_character_in_start(range, start, ::comparison::comparison < ITEM >());
1627 //
1628 // }
1629 //
1630 //
1631 // using BASE_RANGE::find_first_character_in_start;
1632 //
1633 // constexpr const_iterator find_first_character_in_start(const SCOPED_STRING & range, memsize start) const
1634 // {
1635 //
1636 // return this->find_first_character_in_start(range, start, ::comparison::comparison < ITEM >());
1637 //
1638 // }
1639 //
1640 //
1641 // using BASE_RANGE::_find_first_character_in_start_count;
1642 //
1643 // constexpr const_iterator _find_first_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1644 // {
1645 //
1646 // return this->_find_first_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
1647 //
1648 // }
1649 //
1650 //
1651 // using BASE_RANGE::find_first_character_in_start_count;
1652 //
1653 // constexpr const_iterator find_first_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1654 // {
1655 //
1656 // return this->find_first_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
1657 //
1658 // }
1659
1660
1661 //constexpr ITERATOR_TYPE skip_any_character_in(const SCOPED_STRING& range) const
1662 //{
1663
1664 // return this->_skip_any_character_in(range, ::comparison::comparison<ITEM>());
1665
1666 //}
1667
1668
1669 //constexpr character_count skip_any_character_in_index(const SCOPED_STRING& range, ::character_count start = 0) const
1670 //{
1671
1672 // return this->index_of((*this)(start).skip_any_character_in(range).begin());
1673
1674 //}
1675
1676
1677 //using BASE_RANGE::skip_any_character_in;
1678
1679 //static constexpr bool
1680 // _static_initialize_skip_any_character_in(THIS_RANGE & rangeRetur, const THIS_RANGE& range, const THIS_RANGE& rangeBlock) noexcept
1681 //{
1682
1683
1684
1685 // return false;
1686
1687 //}
1688
1689
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
1693 {
1694
1695 ITERATOR_TYPE pbegin = range.m_begin;
1696
1697 do
1698 {
1699
1700 auto pBlockScan = rangeBlock.begin();
1701
1702 while (true)
1703 {
1704
1705 if (equality.equals(*pbegin, *pBlockScan))
1706 {
1707
1708 // found a matching item...
1709 // continue skip_any_character_inning...
1710
1711 break;
1712
1713 }
1714
1715 pBlockScan++;
1716
1717 if (rangeBlock.is_end(pBlockScan))
1718 {
1719
1720 // Iterated through all pBlock items
1721 // and didn't find any that match *p
1722
1723 // so p is the end of the skip_any_character_in for matching items...
1724
1725 return pbegin;
1726
1727 }
1728
1729 };
1730
1731 pbegin++;
1732
1733 } while (!range.is_end(pbegin));
1734
1735 // reached end of the skip_any_character_inning range...
1736 // each skip_any_character_inned item matched some item in range...
1737 // return address immediately after end of skip_any_character_inning...
1738
1739 return pbegin;
1740
1741 }
1742
1743
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
1747 {
1748
1749 if (range.is_empty())
1750 {
1751
1752 return range.m_begin;
1753
1754 }
1755
1756 if (rangeBlock.is_empty())
1757 {
1758
1759 return range.m_end;
1760
1761 }
1762
1763 return _static_skip_any_character_in(range, rangeBlock, equality);
1764
1765 }
1766
1767
1768 //template<::comparison::equality<ITEM> EQUALITY>
1769 //constexpr THIS_RAW_RANGE _skip_any_character_in(const THIS_RAW_RANGE& rangeBlock, EQUALITY equality) const
1770 //{
1771
1772 // return _static_skip_any_character_in(*this, rangeBlock, equality);
1773
1774 //}
1775
1776
1777 //template<::comparison::equality<ITEM> EQUALITY>
1778 //constexpr const_iterator skip_any_character_in(const THIS_RAW_RANGE& rangeBlock, EQUALITY equality) const
1779 //{
1780
1781 // return static_skip_any_character_in(*this, rangeBlock, equality);
1782
1783 //}
1784
1785 template<::comparison::equality<ITEM> EQUALITY>
1786 constexpr ITERATOR_TYPE _skip_any_character_in(const THIS_RANGE& rangeBlock, EQUALITY equality) const
1787 {
1788
1789 return static_skip_any_character_in(*this, rangeBlock, equality);
1790
1791 }
1792
1793
1794 constexpr ITERATOR_TYPE skip_any_character_in(const SCOPED_STRING& range) const {
1795
1796 return this->_skip_any_character_in(range, ::comparison::comparison<ITEM>());
1797
1798 }
1799
1800
1801 // using BASE_RANGE::_skip_any_character_in_start;
1802 //
1803 // constexpr const_iterator _skip_any_character_in_start(const SCOPED_STRING & range, memsize start) const
1804 // {
1805 //
1806 // return this->_skip_any_character_in_start(range, start, ::comparison::comparison < ITEM >());
1807 //
1808 // }
1809 //
1810 //
1811 // using BASE_RANGE::skip_any_character_in_start;
1812 //
1813 // constexpr const_iterator skip_any_character_in_start(const SCOPED_STRING & range, memsize start) const
1814 // {
1815 //
1816 // return this->skip_any_character_in_start(range, start, ::comparison::comparison < ITEM >());
1817 //
1818 // }
1819 //
1820 //
1821 // using BASE_RANGE::_skip_any_character_in_start_count;
1822 //
1823 // constexpr const_iterator _skip_any_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1824 // {
1825 //
1826 // return this->_skip_any_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
1827 //
1828 // }
1829 //
1830 //
1831 // using BASE_RANGE::skip_any_character_in_start_count;
1832 //
1833 // constexpr const_iterator skip_any_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
1834 // {
1835 //
1836 // return this->skip_any_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
1837 //
1838 // }
1839
1840
1841 //using BASE_RANGE::_rear_skip_any_character_in;
1842
1843 constexpr ITERATOR_TYPE rear_skip_any_character_in(const THIS_RANGE& range) const noexcept
1844 {
1845
1846 return static_rear_skip_any_character_in(*this, range, ::comparison::comparison<ITEM>());
1847
1848 }
1849
1850
1851 //constexpr THIS_RANGE rear_skip_any_character_in(const SCOPED_STRING& range) const noexcept {
1852
1853 // return this->rear_skip_any_character_in(range, ::comparison::comparison<ITEM>());
1854
1855 //}
1856
1857
1858 //static constexpr bool
1859 // _initialize_rear_skip_any_character_in(const_iterator& p, const THIS_RAW_RANGE& range, const THIS_RAW_RANGE& rangeBlock) noexcept
1860 //{
1861
1862 // if (range.is_empty())
1863 // {
1864
1865 // p = range.end() - 1;
1866
1867 // return true;
1868
1869 // }
1870
1871 // if (range.is_empty())
1872 // {
1873
1874 // p = range.end() - 1;
1875
1876 // return true;
1877
1878 // }
1879
1880 // return false;
1881
1882 //}
1883
1884
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
1888 {
1889
1890 ITERATOR_TYPE pend = range.m_end;
1891
1892 pend--;
1893
1894 do
1895 {
1896
1897 auto pBlockScan = rangeBlock.begin();
1898
1899 while (true)
1900 {
1901
1902 if (equality.equals(*pend, *pBlockScan))
1903 {
1904
1905 // found a matching item...
1906 // continue skip_any_character_inning...
1907
1908 break;
1909
1910 }
1911
1912 pBlockScan++;
1913
1914 if (rangeBlock.is_end(pBlockScan))
1915 {
1916
1917 // Iterated through all pBlock items
1918 // and didn't find any that match *p
1919
1920 // so p is the end of the skip_any_character_in for matching items...
1921
1922 return pend + 1;
1923
1924 }
1925
1926 };
1927
1928 pend--;
1929
1930 } while (!range.is_before_begin(pend));
1931
1932 // reached end of the skip_any_character_inning range...
1933 // each skip_any_character_inned item matched some item in range...
1934 // return address immediately after end of skip_any_character_inning...
1935
1936 return pend + 1;
1937
1938 }
1939
1940
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
1944 {
1945
1946 //const_iterator p;
1947
1948 //if (_initialize_rear_skip_any_character_in(p, range, rangeBlock))
1949 //{
1950
1951 // return p;
1952
1953 //}
1954
1955 if (range.is_empty())
1956 {
1957
1958 //p = range.end() - 1;
1959
1960 //return true;
1961
1962 return range.m_end;
1963
1964 }
1965
1966 if (rangeBlock.is_empty())
1967 {
1968
1969 //p = range.end() - 1;
1970
1971 return range.m_begin;
1972
1973 }
1974
1975 return _static_rear_skip_any_character_in(range, rangeBlock, equality);
1976
1977 }
1978
1979
1980 //template<::comparison::equality<ITEM> EQUALITY>
1981 //constexpr ITERATOR_TYPE _rear_skip_any_character_in(const THIS_RAW_RANGE& rangeBlock, EQUALITY equality) const
1982 //{
1983
1984 // return _static_rear_skip_any_character_in(*this, rangeBlock, equality);
1985
1986 //}
1987
1988
1989 //template<::comparison::equality<ITEM> EQUALITY>
1990 //constexpr ITERATOR_TYPE rear_skip_any_character_in(const THIS_RANGE& rangeBlock, EQUALITY equality) const
1991 //{
1992
1993 // return static_rear_skip_any_character_in(*this, rangeBlock, equality);
1994
1995 //}
1996
1997
1998 // using BASE_RANGE::rear_skip_any_character_in_start;
1999 //
2000 // constexpr const_iterator rear_skip_any_character_in_start(const SCOPED_STRING & range, memsize start) const
2001 // {
2002 //
2003 // return this->rear_skip_any_character_in_start(range, start, ::comparison::comparison < ITEM >());
2004 //
2005 // }
2006 //
2007 //
2008 // using BASE_RANGE::_rear_skip_any_character_in_start_count;
2009 //
2010 // constexpr const_iterator _rear_skip_any_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2011 // {
2012 //
2013 // return this->_rear_skip_any_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
2014 //
2015 // }
2016 //
2017 //
2018 // using BASE_RANGE::rear_skip_any_character_in_start_count;
2019 //
2020 // constexpr const_iterator rear_skip_any_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2021 // {
2022 //
2023 // return this->rear_skip_any_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
2024 //
2025 // }
2026
2027 using BASE_RANGE::_skip;
2028
2029 constexpr const_iterator _skip(CHARACTER item) const {
2030
2031 return this->_skip(item, ::comparison::comparison<ITEM>());
2032
2033 }
2034
2035
2036 using BASE_RANGE::skip;
2037
2038 constexpr const_iterator skip(CHARACTER item) const {
2039
2040 return this->skip(item, ::comparison::comparison<ITEM>());
2041
2042 }
2043
2044
2045 // using BASE_RANGE::_skip_start;
2046 //
2047 // constexpr const_iterator _skip_start(const ITEM & item, memsize start) const
2048 // {
2049 //
2050 // return this->_skip_start(item, start, ::comparison::comparison < ITEM >());
2051 //
2052 // }
2053 //
2054 //
2055 // using BASE_RANGE::skip_start;
2056 //
2057 // constexpr const_iterator skip_start(const ITEM & item, memsize start) const
2058 // {
2059 //
2060 // return this->skip_start(item, start, ::comparison::comparison < ITEM >());
2061 //
2062 // }
2063 //
2064 //
2065 // using BASE_RANGE::_skip_start_count;
2066 //
2067 // constexpr const_iterator _skip_start_count(const ITEM & item, memsize start, memsize count) const
2068 // {
2069 //
2070 // return this->_skip_start_count(item, start, count, ::comparison::comparison < ITEM >());
2071 //
2072 // }
2073 //
2074 //
2075 // using BASE_RANGE::skip_start_count;
2076 //
2077 // constexpr const_iterator skip_start_count(const ITEM & item, memsize start, memsize count) const
2078 // {
2079 //
2080 // return this->skip_start_count(item, start, count, ::comparison::comparison < ITEM >());
2081 //
2082 // }
2083
2084
2085
2086
2087 //using BASE_RANGE::_rear_find;
2088
2089 //constexpr const_iterator _rear_find(ARG_ITEM item) const {
2090
2091 // return this->_rear_find(item, ::comparison::comparison<ITEM>());
2092
2093 //}
2094
2095
2096 //using BASE_RANGE::rear_find;
2097
2098 //constexpr const_iterator rear_find(ARG_ITEM item) const {
2099
2100 // return this->rear_find(item, ::comparison::comparison<ITEM>());
2101
2102 //}
2103
2104 //constexpr character_count _rear_find_index(ARG_ITEM item) const {
2105
2106 // return this->index_of(this->_rear_find(item));
2107
2108 //}
2109
2110
2111 //constexpr character_count rear_find_index(ARG_ITEM item) const {
2112
2113 // return this->index_of(this->rear_find(item));
2114
2115 //}
2116
2117
2118 // using BASE_RANGE::_rear_find_item_start;
2119 //
2120 // constexpr const_iterator _rear_find_item_start(const ITEM & item, memsize start) const
2121 // {
2122 //
2123 // return this->_rear_find_item_start(item, start, ::comparison::comparison < ITEM >());
2124 //
2125 // }
2126 //
2127 //
2128 // using BASE_RANGE::rear_find_item_start;
2129 //
2130 // constexpr const_iterator rear_find_item_start(const ITEM & item, memsize start) const
2131 // {
2132 //
2133 // return this->rear_find_item_start(item, start, ::comparison::comparison < ITEM >());
2134 //
2135 // }
2136 //
2137 //
2138 // using BASE_RANGE::_rear_find_item_start_count;
2139 //
2140 // constexpr const_iterator _rear_find_item_start_count(const ITEM & item, memsize start, memsize count) const
2141 // {
2142 //
2143 // return this->_rear_find_item_start_count(item, start, count, ::comparison::comparison < ITEM >());
2144 //
2145 // }
2146 //
2147 //
2148 // using BASE_RANGE::rear_find_item_start_count;
2149 //
2150 // constexpr const_iterator rear_find_item_start_count(const ITEM & item, memsize start, memsize count) const
2151 // {
2152 //
2153 // return this->rear_find_item_start_count(item, start, count, ::comparison::comparison < ITEM >());
2154 //
2155 // }
2156
2157
2158
2159 using BASE_RANGE::_rear_find_first_character_in;
2160
2161 constexpr const_iterator _rear_find_first_character_in(const SCOPED_STRING& range) const noexcept {
2162
2163 return this->_rear_find_first_character_in(range, ::comparison::comparison<ITEM>());
2164
2165 }
2166
2167
2168 using BASE_RANGE::rear_find_first_character_in;
2169
2170 constexpr const_iterator rear_find_first_character_in(const SCOPED_STRING& range) const noexcept {
2171
2172 return this->rear_find_first_character_in(range, ::comparison::comparison<ITEM>());
2173
2174 }
2175
2176
2177 // using BASE_RANGE::rear_find_first_character_in_start;
2178 //
2179 // constexpr const_iterator rear_find_first_character_in_start(const SCOPED_STRING & range, memsize start) const
2180 // {
2181 //
2182 // return this->rear_find_first_character_in_start(range, start, ::comparison::comparison < ITEM >());
2183 //
2184 // }
2185 //
2186 //
2187 // using BASE_RANGE::_rear_find_first_character_in_start_count;
2188 //
2189 // constexpr const_iterator _rear_find_first_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2190 // {
2191 //
2192 // return this->_rear_find_first_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
2193 //
2194 // }
2195 //
2196 //
2197 // using BASE_RANGE::rear_find_first_character_in_start_count;
2198 //
2199 // constexpr const_iterator rear_find_first_character_in_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2200 // {
2201 //
2202 // return this->rear_find_first_character_in_start_count(range, start, count, ::comparison::comparison < ITEM >());
2203 //
2204 // }
2205
2206
2207 using BASE_RANGE::_begins;
2208
2209 constexpr bool _begins(const SCOPED_STRING& range) const {
2210
2211 return this->_begins(range, ::comparison::comparison<ITEM>());
2212
2213 }
2214
2215
2216 using BASE_RANGE::begins;
2217
2218 constexpr bool begins(const SCOPED_STRING& range) const {
2219
2220 return this->begins(range, ::comparison::comparison<ITEM>());
2221
2222 }
2223
2224 bool begins_eat(const SCOPED_STRING& range) {
2225
2226 if (!this->begins(range))
2227 {
2228
2229 return false;
2230
2231 }
2232
2233 this->m_begin += range.size();
2234
2235 return true;
2236
2237 }
2238
2239
2240
2241 ::collection::count begins_count(bool(*character_is_function)(CHARACTER character)) const
2242 {
2243
2244 ::collection::count c = 0;
2245
2246 while (character_is_function(this->begin()[c])) c++;
2247
2248 return c;
2249
2250 }
2251
2252
2253 // ::collection::count consume(bool(*character_is_function)(CHARACTER character), character_count minimum_count);
2254
2255
2256 // ::collection::count consume_spaces(character_count minimum_count = 0)
2257 // {
2258 //
2259 // return consume(&character_isspace, minimum_count);
2260 //
2261 // }
2262
2263
2264 // ::string_base < ITERATOR_TYPE > consume_quoted_value();
2265 //
2266 // ::string_base < ITERATOR_TYPE > consume_token_until_any_character_in(const SCOPED_STRING & scopedstrCharacters = 0, bool bReturnSeparator = false, bool bSkipAnyCharactersIn = true);
2267 //
2268 // bool defer_consume(const SCOPED_STRING & range)
2269 // {
2270 //
2271 // if (!this->begins(range))
2272 // {
2273 //
2274 // return false;
2275 //
2276 // }
2277 //
2278 // this->begin() += range.size();
2279 //
2280 // return true;
2281 //
2282 // }
2283
2284
2285 // using BASE_RANGE::_begins_start;
2286 //
2287 // constexpr bool _begins_start(const SCOPED_STRING & range, memsize start) const
2288 // {
2289 //
2290 // return this->_begins_start(range, start, ::comparison::comparison < ITEM >());
2291 //
2292 // }
2293 //
2294 //
2295 // using BASE_RANGE::begins_start;
2296 //
2297 // constexpr bool begins_start(const SCOPED_STRING & range, memsize start) const
2298 // {
2299 //
2300 // return this->begins_start(range, start, ::comparison::comparison < ITEM >());
2301 //
2302 // }
2303 //
2304 //
2305 // using BASE_RANGE::_begins_start_count;
2306 //
2307 // constexpr bool _begins_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2308 // {
2309 //
2310 // return this->_begins_start_count(range, start, count, ::comparison::comparison < ITEM >());
2311 //
2312 // }
2313 //
2314 //
2315 // using BASE_RANGE::begins_start_count;
2316 //
2317 // constexpr bool begins_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2318 // {
2319 //
2320 // return this->begins_start_count(range, start, count, ::comparison::comparison < ITEM >());
2321 //
2322 // }
2323
2324
2325
2326 using BASE_RANGE::_ends;
2327
2328 constexpr bool _ends(const SCOPED_STRING& range) const {
2329
2330 return this->_ends(range, ::comparison::comparison<ITEM>());
2331
2332 }
2333
2334
2335 using BASE_RANGE::ends;
2336
2337 constexpr bool ends(const SCOPED_STRING& range) const {
2338
2339 return this->ends(range, ::comparison::comparison<ITEM>());
2340
2341 }
2342
2343
2344 // using BASE_RANGE::_ends_start;
2345 //
2346 // constexpr bool _ends_start(const SCOPED_STRING & range, memsize start) const
2347 // {
2348 //
2349 // return this->_ends_start(range, start, ::comparison::comparison < ITEM >());
2350 //
2351 // }
2352 //
2353 //
2354 // using BASE_RANGE::ends_start;
2355 //
2356 // constexpr bool ends_start(const SCOPED_STRING & range, memsize start) const
2357 // {
2358 //
2359 // return this->ends_start(range, start, ::comparison::comparison < ITEM >());
2360 //
2361 // }
2362 //
2363 //
2364 // using BASE_RANGE::_ends_start_count;
2365 //
2366 // constexpr bool _ends_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2367 // {
2368 //
2369 // return this->_ends_start_count(range, start, count, ::comparison::comparison < ITEM >());
2370 //
2371 // }
2372 //
2373 //
2374 // using BASE_RANGE::ends_start_count;
2375 //
2376 // constexpr bool ends_start_count(const SCOPED_STRING & range, memsize start, memsize count) const
2377 // {
2378 //
2379 // return this->ends_start_count(range, start, count, ::comparison::comparison < ITEM >());
2380 //
2381 // }
2382
2383
2384
2385
2386 template<typename PRED>
2387 bool is_every_char(PRED pred) const {
2388
2389 for (::collection::index i = 0; i < this->length(); i++) {
2390
2391 if (!pred(this->operator[](i))) {
2392
2393 return false;
2394
2395 }
2396
2397 }
2398
2399 return true;
2400
2401 }
2402
2403
2404 template<typename NUMBER>
2405 NUMBER& translate_index(NUMBER& number) const {
2406
2407 if (number < 0) {
2408
2409 number += this->size() + 1;
2410
2411 if (number < 0) {
2412
2413 number = 0;
2414
2415 }
2416
2417 }
2418 else if (number > this->size()) {
2419
2420 number = this->size();
2421
2422 }
2423
2424 return number;
2425
2426 }
2427
2428
2429 //inline bool contains(CHARACTER ch = 0) const;
2430 inline bool contains(const SCOPED_STRING& scopedstr = 0) const;
2431
2432 //inline bool contains(const string_base &str = 0) const;
2433 inline bool contains(CHARACTER ch) const { return ::is_set(find(ch)); }
2434
2435 inline bool
2436 contains(const SCOPED_STRING& scopedstr, const CHARACTER** ppszBeg, const CHARACTER** ppszEnd = nullptr) const;
2437 //inline bool contains(const string_base &str, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd = nullptr) const;
2438
2439 template<prototype_array STRING_ARRAY>
2440 inline bool contains_any(const STRING_ARRAY& stra) const;
2441
2442 template<prototype_array STRING_ARRAY>
2443 inline bool contains_all(const STRING_ARRAY& stra) const;
2444
2445 //inline bool case_insensitive_contains(CHARACTER ch = 0) const;
2446 inline bool case_insensitive_contains(const SCOPED_STRING& scopedstr = 0) const;
2447
2448 //inline bool case_insensitive_contains(const string_base &str = 0) const;
2449 //inline bool case_insensitive_contains(CHARACTER ch, const CHARACTER ** ppszBeg) const;
2450 inline bool
2451 case_insensitive_contains(const SCOPED_STRING& scopedstr, const CHARACTER** ppszBeg, const CHARACTER** ppszEnd = nullptr) const;
2452 //inline bool case_insensitive_contains(const string_base &str, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd = nullptr) const;
2453
2454 template<prototype_array STRING_ARRAY>
2455 inline bool case_insensitive_contains_at_least_one_of(const STRING_ARRAY& stra) const;
2456
2457 template<prototype_array STRING_ARRAY>
2458 inline bool case_insensitive_contains_all(const STRING_ARRAY& stra) const;
2459
2460
2461 //inline bool unicode_case_insensitive_contains(CHARACTER ch = 0) const;
2462 inline bool unicode_case_insensitive_contains(const SCOPED_STRING& scopedstr = 0) const;
2463
2464 //inline bool unicode_case_insensitive_contains(const string_base &str = 0) const;
2465 //inline bool unicode_case_insensitive_contains(CHARACTER ch, const CONST_STRING_RANGE &* ppszBeg) const;
2466 inline bool
2467 unicode_case_insensitive_contains(const SCOPED_STRING& scopedstr, const CHARACTER** ppszBeg, const CHARACTER** ppszEnd = nullptr) const;
2468 //inline bool unicode_case_insensitive_contains(const string_base &str, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd = nullptr) const;
2469
2470 template<prototype_array STRING_ARRAY>
2471 inline bool unicode_case_insensitive_contains_at_least_one_of(const STRING_ARRAY& stra) const;
2472
2473 template<prototype_array STRING_ARRAY>
2474 inline bool unicode_case_insensitive_contains_all(const STRING_ARRAY& stra) const;
2475
2476
2477 template<::comparison::equality<CHARACTER> EQUALITY>
2478 ::collection::count _occurrence_count_of(const SCOPED_STRING& scopedstr, EQUALITY equality) const {
2479
2480 character_count nLen = scopedstr.size();
2481
2482 character_count count = 0;
2483
2484 auto range = (*this)();
2485
2486 while ((range.begin(range.find(scopedstr, equality))) != nullptr) {
2487
2488 count++;
2489
2490 range.begin() += nLen;
2491
2492 }
2493
2494 return count;
2495
2496 }
2497
2498
2499 ::collection::count occurrence_count_of(const SCOPED_STRING& scopedstr = 0) const {
2500
2501 return _occurrence_count_of(scopedstr, ::comparison::comparison<CHARACTER>());
2502
2503 }
2504
2505
2506 ::collection::count case_insensitive_occurrence_count_of(const SCOPED_STRING& scopedstr = 0) const {
2507
2508 return _occurrence_count_of(scopedstr, ::comparison::case_insensitive<CHARACTER>());
2509
2510 }
2511
2512
2513
2514 // find routines
2515
2516 // find the first occurrence of character 'ch', starting at index 'iStart'
2517 const_iterator find(CHARACTER ch) const RELEASENOTHROW;
2518
2519 // character_count find(CHARACTER ch) const RELEASENOTHROW;
2520 // character_count find(CHARACTER ch) const RELEASENOTHROW;
2521 const_iterator case_insensitive_find(CHARACTER ch) const RELEASENOTHROW;
2522
2523 // find routines
2524
2525// find the first occurrence of character 'ch', starting at index 'iStart'
2526 //character_count find_index(CHARACTER ch) const RELEASENOTHROW { return this->index_of(this->find(ch)); }
2527
2528 // character_count find(CHARACTER ch) const RELEASENOTHROW;
2529 // character_count 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)); }
2532
2533 const_iterator find_skip_or_end(CHARACTER ch = 0) const RELEASENOTHROW
2534 {
2535
2536 auto p = this->begin();
2537
2538 while (p < this->end()) {
2539
2540 if (*p == ch) {
2541
2542 p++;
2543
2544 return p;
2545
2546 }
2547
2548 p++;
2549
2550 }
2551
2552 return p;
2553
2554 }
2555
2560 ITERATOR_TYPE find_first_whitespace() const RELEASENOTHROW { return this->find_first_character_in(typed_whitespace<CHARACTER>()); }
2561
2562 ITERATOR_TYPE skip_whitespace() const RELEASENOTHROW { return this->skip_any_character_in(typed_whitespace<CHARACTER>()); }
2563
2564 ::character_count count_left(const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) const RELEASENOTHROW { return this->skip_any_character_in(range) - this->begin(); }
2565
2566 // string_range& trim_left(const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) RELEASENOTHROW { this->m_begin += count_left(range); return *this; }
2567
2568
2569 ITERATOR_TYPE rear_find_first_whitespace() const RELEASENOTHROW { return this->rear_find_first_character_in(typed_whitespace<CHARACTER>()); }
2570
2571 ITERATOR_TYPE rear_skip_whitespace() const RELEASENOTHROW { return this->rear_skip_any_character_in(typed_whitespace<CHARACTER>()); }
2572
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); }
2574
2575 // string_range& trim_right(const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) RELEASENOTHROW { this->m_end -= count_right(range); return *this; }
2576
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); }
2578
2579 // string_range& trim(const SCOPED_STRING& range = typed_whitespace<CHARACTER>()) RELEASENOTHROW { trim_left(range); trim_right(range); return *this; }
2580
2581 // bool paired_trim(CHARACTER character1, CHARACTER character2)
2582 // {
2583 //
2584 // if (this->size() < 2)
2585 // {
2586 //
2587 // return false;
2588 //
2589 // }
2590 //
2591 // if (this->first() != character1 || this->last() != character2)
2592 // {
2593 //
2594 // return false;
2595 //
2596 // }
2597 //
2598 // this->begin()++;
2599 //
2600 // this->end()--;
2601 //
2602 // return true;
2603 //
2604 // }
2605
2606
2607 // bool begins_eat(CHARACTER character)
2608 // {
2609 //
2610 // if (this->size() <= 0)
2611 // {
2612 //
2613 // return false;
2614 //
2615 // }
2616 //
2617 // if (this->first() != character)
2618 // {
2619 //
2620 // return false;
2621 //
2622 // }
2623 //
2624 // this->begin()++;
2625 //
2626 // return true;
2627 //
2628 // }
2629
2630 const_string_range begins_bitten(const SCOPED_STRING & scopedstrPrefix) const
2631 {
2632
2633 if (this->begins(scopedstrPrefix))
2634 {
2635
2636 return {this->begin() + scopedstrPrefix.size(), this->end()};
2637
2638 }
2639
2640 return *this;
2641
2642 }
2643
2644 // bool defer_consume_character(CHARACTER & character)
2645 // {
2646 //
2647 // if (this->size() <= 0)
2648 // {
2649 //
2650 // return false;
2651 //
2652 // }
2653 //
2654 // character = this->first();
2655 //
2656 // this->begin()++;
2657 //
2658 // return true;
2659 //
2660 // }
2661
2662
2663 // ::i32 defer_consume_digit(::i32 iBase)
2664 // {
2665 //
2666 // CHARACTER character;
2667 //
2668 // if (!defer_consume_character(character))
2669 // {
2670 //
2671 // return -1;
2672 //
2673 // }
2674 //
2675 // if (character >= '0' && character <= ('0' + minimum(iBase - 1, 9)))
2676 // {
2677 //
2678 // return character - '0';
2679 //
2680 // }
2681 //
2682 // if (iBase <= 10)
2683 // {
2684 //
2685 // return -1;
2686 //
2687 // }
2688 //
2689 // if (character >= 'a' && character <= ('a' + minimum(iBase - 11, 'z')))
2690 // {
2691 //
2692 // return character - 'a';
2693 //
2694 // }
2695 // else if (character >= 'A' && character <= ('A' + minimum(iBase - 11, 'Z')))
2696 // {
2697 //
2698 // return character - 'A';
2699 //
2700 // }
2701 //
2702 // return -1;
2703 //
2704 // }
2705
2706 const_string_range& operator=(const THIS_RANGE& range)
2707 {
2708 BASE_RANGE::operator=(range);
2709 return *this;
2710 }
2711
2712 const_string_range& operator=(const_string_range&& range) {
2713 BASE_RANGE::operator=(::transfer(range));
2714 return *this;
2715 }
2716
2717 //const_string_range& operator=(const atom& atom);
2718
2719 const_string_range& operator=(const block& block);
2720
2721
2722
2723
2724 //inline bool begins(const SCOPED_STRING & scopedstrPrefix) const;
2725 //inline bool ends(const SCOPED_STRING & scopedstrSuffix) const;
2726
2727 inline bool case_insensitive_begins(const SCOPED_STRING& scopedstrPrefix) const;
2728
2729 inline bool case_insensitive_ends(const SCOPED_STRING& scopedstrSuffix) const;
2730
2731
2732 // look for a specific sub-string_base
2733
2734 //bool _find_prefix(character_count & i, const string_base &str, character_count & start, character_count & blockLen, character_count & nEndPosition, const CHARACTER ** ppszTail) const RELEASENOTHROW;
2735
2736 // find the first occurrence of string_base 'block', starting at index 'iStart'
2737 //const_iterator find(const SCOPED_STRING &scopedstr) const RELEASENOTHROW;
2738
2739
2740
2741 const_iterator unicode_find(const SCOPED_STRING& scopedstr) const RELEASENOTHROW;
2742
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
2745 {
2746
2747 return this->index_of(this->operator()(start).unicode_case_insensitive_find(scopedstr));
2748
2749 }
2750
2751 // find the first occurrence of string_base 'block', starting at index 'iStart', if found returns the index of first character after the end of the found string_base
2752 //const_iterator rear_find(const SCOPED_STRING &scopedstr) const RELEASENOTHROW;
2753
2754 const_iterator unicode_rear_find(const SCOPED_STRING& scopedstr) const RELEASENOTHROW;
2755
2756 const_iterator unicode_case_insensitive_rear_find(const SCOPED_STRING& scopedstr) const RELEASENOTHROW;
2757
2758 // find the first occurrence of any of the characters in string_base 'pszCharSet'
2759 //const_iterator find_first_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2760 //const_iterator find_first_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW;
2761 //character_count find_first_character_in(const CHARACTER * blockCharacters, character_count iStart = 0) const RELEASENOTHROW;
2762
2763 //const_iterator _find_first_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2764 //const_iterator _find_first_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW;
2766
2767 const_iterator find_first(CHARACTER chSeparator, ::character_count start = 0) const RELEASENOTHROW;
2768
2769 //character_count find_first_in(const string_base &str) const RELEASENOTHROW;
2770 //character_count find_first_in(const string_base &str) const RELEASENOTHROW;
2772 //character_count find_first_in(CHARACTER ca) const RELEASENOTHROW;
2773
2774 //const_iterator skip_any_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2775
2776 //const_iterator skip_any_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2777
2778 //character_count skip_any_character_in(const CHARACTER * pszCharacters) const RELEASENOTHROW;
2779 // const_iterator skip(CHARACTER chSkip) const RELEASENOTHROW;
2780
2781 //const_iterator
2782 //_skip_any_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2783
2784 //const_iterator _skip_any_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2785
2786 //character_count _skip_any_character_in(const CHARACTER * pszCharacters) const RELEASENOTHROW;
2787 //const_iterator _skip(CHARACTER chSkip) const RELEASENOTHROW;
2788
2789
2790//character_count find_last_not_in(const string_base &str, character_count pos = -1) const RELEASENOTHROW;
2791 //character_count find_last_not_in(const string_base &str) const RELEASENOTHROW;
2793 //character_count find_last_not_in(CHARACTER ca, character_count pos = -1) const RELEASENOTHROW;
2794
2795// const_iterator rear_find_first_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2796//
2797// const_iterator rear_find_first_character_in(const SCOPED_STRING &scopedstrCharacters, character_count iStart,
2798// character_count n) const RELEASENOTHROW;
2799 //character_count rear_find_first_character_in(const CHARACTER * blockCharacters) const RELEASENOTHROW;
2800
2801// const_iterator _rear_find_first_character_in(const SCOPED_STRING &scopedstrCharacters) const RELEASENOTHROW;
2802//
2803// const_iterator _rear_find_first_character_in(const SCOPED_STRING &scopedstrCharacters, character_count iStart,
2804// character_count n) const RELEASENOTHROW;
2805 //character_count _rear_find_first_character_in(const CHARACTER * blockCharacters) const RELEASENOTHROW;
2806
2807 //character_count find_first_of(const string_base &str) const RELEASENOTHROW;
2808 //character_count find_first_of(const string_base &str) const RELEASENOTHROW;
2809 //character_count find_first_of(const CHARACTER * pszCharacters) const RELEASENOTHROW;
2810 //character_count find_first_of(CHARACTER ca) const RELEASENOTHROW;
2811 //character_count find_first_of(CHARACTER ca, character_count pos) const RELEASENOTHROW;
2812
2813 //character_count find_first_not_of(const string_base &str) const RELEASENOTHROW;
2814 //character_count find_first_not_of(const string_base &str) const RELEASENOTHROW;
2815 //character_count find_first_not_of(const string_base &str) const RELEASENOTHROW;
2816 //character_count find_first_not_of(CHARACTER ca) const RELEASENOTHROW;
2817
2818 //const_iterator rear_skip_any_character_in(const SCOPED_STRING &scopedstr) const RELEASENOTHROW;
2819 //const_iterator rear_skip_any_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW;
2820 //character_count rear_skip_any_character_in(const CHARACTER * psz, character_count pos = -1) const RELEASENOTHROW;
2821
2822 //const_iterator rear_skip(CHARACTER ca) const RELEASENOTHROW;
2823 //const_iterator rear_skip(CHARACTER ca) const RELEASENOTHROW;
2824
2825
2826 //const_iterator _rear_skip_any_character_in(const SCOPED_STRING &scopedstr) const RELEASENOTHROW;
2827 //const_iterator _rear_skip_any_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW;
2828
2829
2830 using BASE_RANGE::_rear_skip;
2831
2832
2833 //const_iterator _rear_skip_any_character_in(CHARACTER ca) const RELEASENOTHROW;
2834 const_iterator _rear_skip(CHARACTER ca) const RELEASENOTHROW
2835 {
2836
2837 return this->_rear_skip(ca, ::comparison::comparison < CHARACTER >());
2838
2839 }
2840
2841 using BASE_RANGE::rear_skip;
2842
2843 //character_count _rear_skip_any_character_in(const CHARACTER * psz, character_count pos = -1) const RELEASENOTHROW;
2844 const_iterator rear_skip(CHARACTER ca) const RELEASENOTHROW
2845 {
2846
2847 return this->rear_skip(ca, ::comparison::comparison < CHARACTER>());
2848
2849 }
2850
2851 //character_count find_last_of(const string_base &str, character_count pos = -1) const RELEASENOTHROW;
2852 //character_count find_last_of(const string_base &str) const RELEASENOTHROW;
2854 //character_count find_last_of(CHARACTER ca, character_count pos = -1) const RELEASENOTHROW;
2855
2856 // find the last occurrence of character 'ch'
2857 //const_iterator rear_find(CHARACTER ch) const RELEASENOTHROW;
2858
2859 // find the last occurrence of string_base 'sz'
2860 //const_iterator rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW;
2861
2862
2863
2864 CHARACTER last_char(character_count count = -1) const;
2865
2866
2867 inline character_count unichar_count() const;
2868
2869 inline const_iterator unichar_at(character_count iUnicharIndex) const;
2870
2871
2872 //const_iterator __replace(const_iterator start, const_iterator end, const SCOPED_STRING & scopedstr)
2873 //{
2874
2875 // ::memory_transfer((void *)start, start + scopedstr.size(), this->end() - end);
2876
2877 // string_count_copy(start, scopedstr.begin(), scopedstr.size());
2878
2879 //}
2880
2881
2882 //bool equals(const string_base &str) const;
2883 //bool case_insensitive_equals(const string_base &str) const;
2884 //inline bool operator==(const ::ansi_string& str) const;
2885
2886 //inline bool operator==(const ::wd16_string& str) const;
2887
2888 //inline bool operator==(const ::wd32_string& str) const;
2889
2890// template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
2891 inline bool operator==(const ::character_range < const CHARACTER* >& range) const;
2892
2893 template < character_count n >
2894 inline bool operator==(const CHARACTER(&s)[n]) const
2895 {
2896
2897 return this->equals(s);
2898
2899 }
2900
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 >;
2904
2905 //inline bool operator ==(const SCOPED_STRING & scopedstr) const { return this->equals(scopedstr); }
2906
2907 inline bool operator==(const ::ansi_character* psz) const { return this->equals(psz); }
2908
2909 inline bool operator==(const ::wd16_character* psz) const { return this->equals(psz); }
2910
2911 inline bool operator==(const ::wd32_character* psz) const { return this->equals(psz); }
2912
2913 inline bool operator==(const ::inline_number_string& inline_number_string) const {
2914 return this->equals((const SCOPED_STRING&)inline_number_string);
2915 }
2916
2917 //inline ::std::strong_ordering operator<=>(const string_base & range) const { return this->order(range); }
2918 //inline ::std::strong_ordering operator<=>(const SCOPED_STRING &scopedstr) const { return this->order(scopedstr); }
2919 //inline ::std::strong_ordering operator<=>(const CHARACTER * psz) const { return *this <=> ((const SCOPED_STRING &)psz); }
2920 //inline ::i32 operator<=>(CHARACTER ch) const;
2921 //inline bool operator==(CHARACTER ch) const;
2922 //inline bool operator==(CHARACTER ch) const;
2923 //inline bool operator>(const string_base &str2) const;
2924 //inline bool operator>(CHARACTER ch) const;
2925 //inline bool operator<(const string_base &str2) const;
2926 //inline bool operator<(CHARACTER ch) const;
2927 //inline bool operator!=(const string_base &str) const { return !operator ==(scopedstr); }
2928 //inline bool operator!=(CHARACTER ch) const { return !operator ==(ch); }
2929 //inline bool operator>=(const string_base &str) const { return !operator <(scopedstr); }
2930 //inline bool operator>=(CHARACTER ch) const { return !operator <(ch); }
2931 //inline bool operator<=(const CHARACTER * psz) const { return !operator >(scopedstr); }
2932 //inline bool operator<=(CHARACTER ch) const { return !operator >(ch); }
2933
2934
2935
2936 //character_count rear_find(CHARACTER ch) const RELEASENOTHROW
2937 //{
2938 // return rear_find(ch, iStart);
2939 //};
2940 //character_count rear_find(const string_base &str) const RELEASENOTHROW
2941 //{
2942 // return rear_find(sz, iStart);
2943 //};
2944
2945
2946 bool xml_is_comment() const;
2947
2948
2958 ::std::strong_ordering escape_case_insensitive_count_order(const ::scoped_string& scopedstr, ::i32 escape) const;
2959
2960
2961
2962 STRING surrounded(const SCOPED_STRING& scopedstr) const;
2963
2964 STRING surrounded(const SCOPED_STRING& scopedstrLeft, const SCOPED_STRING& scopedstrRight) const;
2965
2966 STRING f64_quoted(bool bEscape = false) const;
2967
2968 STRING single_quoted(bool bEscape) const;
2969
2970
2971 STRING_ARRAY explode(const SCOPED_STRING& scopedstrSeparator, bool bAddEmpty = true) const;
2972
2973
2974 //ITERATOR_TYPE __count_parts_from_beginning(::collection::count & cPathPartCountToConsume, CHARACTER chSeparator) const;
2975
2976
2977 //::collection::count count_parts_from_beginning(::collection::count cPathPartCountToConsume, CHARACTER chSeparator) const;
2978
2979
2980 STRING_RANGE _get_count_parts_from_beginning(::collection::count cPathPartCountToConsume, CHARACTER chSeparator) const
2981 {
2982
2983 auto range = this->operator()();
2984
2985 auto cConsumed = cPathPartCountToConsume;
2986
2987 range.m_begin = range.__count_parts_from_beginning(cConsumed, chSeparator);
2988
2989 if (cPathPartCountToConsume == cConsumed)
2990 {
2991
2992 return range;
2993
2994 }
2995
2996 return {};
2997
2998 }
2999
3000
3001 //STRING_RANGE get_count_parts_from_beginning(::collection::count cPathPartCountToConsume, CHARACTER chSeparator) const
3002 //{
3003
3004 // if (cPathPartCountToConsume <= 0)
3005 // {
3006
3007 // return this->operator()();
3008
3009 // }
3010
3011 // return this->_get_count_parts_from_beginning(cPathPartCountToConsume, chSeparator);
3012
3013 //}
3014
3015
3016 THIS_RANGE right(character_count nCount) const;
3017
3018 THIS_RANGE left(character_count count) const;
3019
3020 THIS_RANGE left(const_iterator p) const { return ::transfer(this->left(p - this->begin())); }
3021
3022 THIS_RANGE left_including_any_character_in(const SCOPED_STRING& scopedstrCharSet) const;
3023
3024 THIS_RANGE left_skipping_any_character_in(const SCOPED_STRING& scopedstrCharSet) const;
3025
3026 //THIS_RANGE consume_token_until_any_character_in(const SCOPED_STRING& scopedstrCharacters = 0, bool bReturnSeparator = false, bool bSkipAnyCharactersIn = true) const;
3027
3028
3029 inline ITERATOR_TYPE __count_parts_from_beginning(::collection::count & cPathMaxPartCount, CHARACTER chPartSeparator) const
3030 {
3031
3032 ::collection::index i = 0;
3033
3034 auto p = this->m_begin;
3035
3036 for (; i < cPathMaxPartCount; i++)
3037 {
3038
3039 p = string_find_character(p, chPartSeparator);
3040
3041 if (::is_null(p))
3042 {
3043
3044 break;
3045
3046 }
3047
3048 p = p + 1;
3049
3050 }
3051
3052 cPathMaxPartCount = i;
3053
3054 return p;
3055
3056 }
3057
3058
3059};
3060
3061
3062
3063
3064#include "const_string_range_static_array.h"
3065
3066
3067
3068template<prototype_character CHARACTER>
3069constexpr ::character_range<const CHARACTER*> _string_range(const CHARACTER* psz);
3070
3071template<prototype_character CHARACTER>
3072constexpr ::character_range<const CHARACTER*>
3073_start_count_string_range(const CHARACTER* psz, memsize start, memsize count);
3074
3075
3076
3077//template < std::size_t n >
3078//class ansi_string_literal :
3079// public const_ansi_range
3080//{
3081//public:
3082//
3083// ::i8 m_s[n]{};
3084//
3085// constexpr ansi_string_literal(::i8 const(&s)[n])
3086// {
3087// std::ranges::copy(s, m_s);
3088// this->m_begin = s;
3089// this->m_end = s + (s[n-1]=='\0'? n-1:n);
3090// this->m_erange = (enum_range) (e_range_string_literal
3091// | (s[n - 1] == '\0' ? e_range_null_terminated : 0));
3092//
3093// }
3094//
3095//
3096//};
3097//
3098//
3099//template < ansi_string_literal literal >
3100//constexpr auto operator ""_ansi()
3101//{
3102//
3103// return literal;
3104//
3105//}
3106//
3107
3108CLASS_DECL_ACME void log_const_ansi_range_literal(::i32 n);
3109
3110
3111template < typename ITERATOR_TYPE >
3112class string_literal_base :
3113 public const_string_range < ITERATOR_TYPE >
3114{
3115public:
3116
3117
3118 using BASE_RANGE = const_string_range < ITERATOR_TYPE >;
3119
3120
3121 constexpr string_literal_base(ITERATOR_TYPE s, std::size_t n) :
3122 BASE_RANGE(no_initialize_t{})
3123 {
3124
3125 this->m_begin = s;
3126 this->m_end = s + n;
3127 this->m_erange = e_range_string_literal;
3128 this->m_pbasedata = nullptr;
3129
3130 }
3131
3132 constexpr string_literal_base(ITERATOR_TYPE s) :
3133 string_literal_base(s, string_safe_length(s))
3134 {
3135
3136 }
3137
3138
3139};
3140
3141
3142using string_literal = string_literal_base < const_char_pointer >;
3143using wstring_literal = string_literal_base < const ::wide_character * >;
3144
3145
3146constexpr string_literal_base < const_char_pointer >operator ""_ansi(const_char_pointer s, std::size_t n)
3147{
3148
3149 return { s, n };
3150
3151}
3152
3153
3154constexpr string_literal_base < const ::wd16_character * > operator ""_wd16(const ::wd16_character * s, std::size_t n)
3155{
3156
3157 return { s, n };
3158
3159}
3160
3161
3162constexpr string_literal_base < const ::wd32_character* > operator ""_wd32(const ::wd32_character * s, std::size_t n)
3163{
3164
3165 return { s, n };
3166
3167}
3168
3169
3170template < prototype_character CHARACTER, character_count n >
3171::const_string_range < const CHARACTER * > as_range(const CHARACTER(&s)[n])
3172{
3173 return
3174 {
3175 s,
3176 s + (s[n - 1] == CHARACTER{} ? n - 1 : n)
3177 };
3178
3179}
3180
3181
3182template < typename TYPED_STRING_LITERAL, typename CHARACTER >
3184::std::is_same_v < TYPED_STRING_LITERAL, CHARACTER >&&
3185prototype_character < TYPED_STRING_LITERAL >;
3186
3187
3188
3189
3190
3191
3192
3193
3194
Definition aaa_character.h:10
Definition __begin.h:14
Definition _template_after_initial_concepts.h:15
::std::strong_ordering escape_case_insensitive_count_order(const ::scoped_string &scopedstr, ::i32 escape) const
Definition _impl_const_string_range.h:195
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
ITERATOR_TYPE find_first_whitespace() const RELEASENOTHROW
for the rear_* functions the most relevant returned value is actually in m_end.
Definition const_string_range.h:2560
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 item.h:93
Definition _template_forward_declaration.h:327
Definition range.h:223
Definition scoped_string_base.h:13
Definition string_range.h:13
Definition const_string_range.h:3183
Definition _1.h:16
Definition _tags.h:5