acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
_impl_string_base1.h
1//
2// _string_base_impl.h
3// acme
4//
5// Created by Camilo Sasuke Thomas Borregaard Soerensen on 08/06/22.
6// Copyright (c) 2022 Camilo Sasuke Thomas Borregaard Soerensen. All rights reserved.
7//
8#pragma once
9
10
11template < prototype_character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
12inline ::std::strong_ordering _sz_compare(const CHARACTER * pA, const CHARACTER * pB, ORDERING ordering) noexcept
13{
14
15 while (true)
16 {
17
18 auto order = ordering.order(*pA, *pB);
19
20 if (order != 0 || !*pA || !*pB)
21 {
22
23 return order;
24
25 }
26
27 pA++;
28
29 pB++;
30
31 }
32
33}
34
35
36template < prototype_character CHARACTER >
37constexpr ::std::strong_ordering _sz_compare(const CHARACTER * pA, const CHARACTER * pB) noexcept
38{
39
40 return _sz_compare(pA, pB, ::comparison::comparison<CHARACTER>());
41
42}
43
44
45template < prototype_character CHARACTER >
46constexpr ::std::strong_ordering case_insensitive__sz_compare(const CHARACTER * pA, const CHARACTER * pB) noexcept
47{
48
49 return _sz_compare(pA, pB, ::comparison::case_insensitive < CHARACTER >());
50
51}
52
53
54template < prototype_character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
55inline ::std::strong_ordering _sz_count_compare(const CHARACTER * pA, const CHARACTER * pB, character_count sizeB, ORDERING ordering) noexcept
56{
57
58 auto pBEnd = pB + sizeB;
59
60 while (true)
61 {
62
63 if (pB >= pBEnd)
64 {
65
66 return *pA <=> 0;
67
68 }
69
70 auto order = ordering.order(*pA, *pB);
71
72 if (order != 0 || !*pA)
73 {
74
75 return order;
76
77 }
78
79 pA++;
80
81 pB++;
82
83 }
84
85}
86
87
88template < prototype_character CHARACTER >
89constexpr ::std::strong_ordering _sz_count_compare(const CHARACTER * pA, const CHARACTER * pB, character_count sizeB) noexcept
90{
91
92 return _sz_count_compare(pA, pB, sizeB, ::comparison::comparison<CHARACTER>());
93
94}
95
96
97template < prototype_character CHARACTER >
98constexpr ::std::strong_ordering case_insensitive__sz_count_compare(const CHARACTER * pA, const CHARACTER * pB, character_count sizeB) noexcept
99{
100
101 return _sz_count_compare(pA, pB, sizeB, ::comparison::case_insensitive < CHARACTER >());
102
103}
104
105
106template < prototype_character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
107inline ::std::strong_ordering _count_sz_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB, ORDERING ordering) noexcept
108{
109
110 auto pAEnd = pA + sizeA;
111
112 while (true)
113 {
114
115 if (pA >= pAEnd)
116 {
117
118 return ordering.order({}, *pB);
119
120 }
121
122 auto order = ordering.order(*pA, *pB);
123
124 if (order != 0 || !*pB)
125 {
126
127 return order;
128
129 }
130
131 pA++;
132
133 pB++;
134
135 }
136
137}
138
139
140template < prototype_character CHARACTER >
141constexpr ::std::strong_ordering _count_sz_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB) noexcept
142{
143
144 return _count_sz_compare(pA, sizeA, pB, ::comparison::comparison<CHARACTER>());
145
146}
147
148
149template < prototype_character CHARACTER >
150constexpr ::std::strong_ordering case_insensitive__count_sz_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB) noexcept
151{
152
153 return _count_sz_compare(pA, sizeA, pB, ::comparison::case_insensitive < CHARACTER >());
154
155}
156
157
158
159//template < typename ITERATOR_TYPE >
160//inline ::std::strong_ordering case_insensitive__string_compare(const CHARACTER * pszA, character_count sizeA, const_char_pointer pszB, character_count sizeB) noexcept
161//{
162//
163// character_count lenCompare = minimum(sizeA, sizeB);
164//
165// auto ordering = case_insensitive_string_count_compare(scopedstrA, pszB, lenCompare);
166//
167// if (ordering != 0)
168// {
169//
170// return ordering;
171//
172// }
173//
174// return sizeA <=> sizeB;
175//
176//}
177
178
179template < typename ITERATOR_TYPE >
180inline ::std::strong_ordering _scopedstr_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
181{
182
183 character_count len = minimum(scopedstrA.size(), scopedstrB.size());
184
185 auto order = string_count_collate(scopedstrA.begin(), scopedstrB.begin(), len);
186
187 if (order != 0)
188 {
189
190 return order;
191
192 }
193
194 return scopedstrA.size() <=> scopedstrB.size();
195
196}
197
198
199template < typename ITERATOR_TYPE >
200inline ::std::strong_ordering _case_insensitive_scopedstr_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
201{
202
203 character_count len = minimum(scopedstrA.size(), scopedstrB.size());
204
205 auto order = case_insensitive_string_count_collate(scopedstrA.begin(), scopedstrB.begin(), len);
206
207 if (order != 0)
208 {
209
210 return order;
211
212 }
213
214 return scopedstrA.size() <=> scopedstrB.size();
215
216}
217
218
219//template < typename ITERATOR_TYPE >
220//inline ::i32 string_compare(const CHARACTER * pszA, character_count sizeA, const_char_pointer pszB, character_count sizeB) noexcept
221//{
222//
223// ::i32 iCompare;
224//
225// if (string_compare_prefix(iCompare, pszA, pszB))
226// {
227//
228// return iCompare;
229//
230// }
231//
232// return _string_compare(scopedstrA, sizeA, pszB, sizeB);
233//
234//}
235
236
237//template < typename ITERATOR_TYPE >
238//inline ::i32 case_insensitive_string_order(const array_scopedstr<CHARACTER> & scopedstrA, ) noexcept
239//{
240//
241// ::i32 iCompare;
242//
243// if (string_compare_prefix(iCompare, pszA, pszB))
244// {
245//
246// return iCompare;
247//
248// }
249//
250// return case_insensitive__string_compare(scopedstrA, sizeA, pszB, sizeB);
251//
252//}
253
254
255template < typename ITERATOR_TYPE >
256inline ::std::strong_ordering range_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
257{
258
259 ::std::strong_ordering order(::std::strong_ordering::less);
260
261 if (scopedstrA._initialize_order(order, scopedstrA, scopedstrB))
262 {
263
264 return order;
265
266 }
267
268 return _string_collate(::string_base < ITERATOR_TYPE >(scopedstrA).c_str(), ::string_base < ITERATOR_TYPE >(scopedstrB).c_str());
269
270}
271
272
273template < typename ITERATOR_TYPE >
274inline ::std::strong_ordering case_insensitive_range_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
275{
276
277 ::std::strong_ordering order(::std::strong_ordering::less);
278
279 if (scopedstrA._initialize_order(order, scopedstrA, scopedstrB))
280 {
281
282 return order;
283
284 }
285
286 return _case_insensitive_string_collate(::string_base < ITERATOR_TYPE >(scopedstrA).c_str(), ::string_base < ITERATOR_TYPE >(scopedstrB).c_str());
287
288}
289
290
291template < prototype_character CHARACTER >
292inline ::std::strong_ordering _sz_count_collate(const CHARACTER * pszA, const CHARACTER * pszB, character_count sizeB) noexcept
293{
294
295 return range_collate<const CHARACTER>(scopedstrA, { pszB, sizeB });
296
297}
298
299
300template < prototype_character CHARACTER >
301inline ::std::strong_ordering _case_insensitive_sz_count_collate(const CHARACTER * pszA, const CHARACTER * pszB, character_count sizeB) noexcept
302{
303
304 return case_insensitive_range_collate<const CHARACTER>(scopedstrA, { pszB, sizeB });
305
306}
307
308
309inline ::std::strong_ordering _count_sz_collate(const_char_pointer pszA, character_count sizeA, const_char_pointer pszB) noexcept
310{
311
312 return range_collate<const_char_pointer >({ pszA, sizeA }, pszB);
313
314}
315
316
317inline ::std::strong_ordering _case_insensitive_count_sz_collate(const_char_pointer pszA, character_count sizeA, const_char_pointer pszB) noexcept
318{
319
320 return case_insensitive_range_collate<const_char_pointer >({ pszA, sizeA }, pszB);
321
322}
323
324
325CLASS_DECL_ACME ::string string_formatf(const_char_pointer pszFormat, ...);
326
327
328
329
330
331CLASS_DECL_ACME void foo123();
332
333
334//template < typename ITERATOR_TYPE >
335//inline void string_base < ITERATOR_TYPE >::construct1(const ITERATOR_TYPE p, character_count length)
336//{
337//
338// if (::is_null(p) || length <= 0)
339// {
340//
341// default_construct();
342//
343// return;
344//
345// }
346//
347// this->create_string(length);
348//
349// memory_copy((void *) this->m_begin, p, length * sizeof(CHARACTER));
350//
351// *(CHARACTER*)this->m_end = (CHARACTER)0;
352//
353//}
354//
355//
356//template < typename ITERATOR_TYPE >
357//template < ::i32 t_size >
358//inline string_base < ITERATOR_TYPE >::string_base(const const_string_range_static_array < ITERATOR_TYPE, t_size >& a)
359//{
360//
361// create_string(a.size());
362//
363// auto p = (CHARACTER*) this->begin();
364//
365// a.block_concatenate_to(p);
366//
367// p = {};
368//
369//}
370
371
372template < typename ITERATOR_TYPE >
373template < other_primitive_character < typename ::string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
374string_base< ITERATOR_TYPE>& string_base< ITERATOR_TYPE>::operator += (const const_string_range_static_array < const OTHER_CHARACTER *, t_size >& a)
375{
376
377 auto oldlen = this->size();
378
379 character_count iaLen[t_size];
380
381 character_count* plen = iaLen;
382
383 auto dstlen = a.__utf_length(this->begin(), plen);
384
385 auto p = get_buffer(dstlen);
386
387 p += oldlen;
388
389 plen = iaLen;
390
391 a.__utf_concatenate_to(p, plen);
392
393 *p = {};
394
395 return *this;
396
397}
398
399
400template < typename ITERATOR_TYPE >
401inline void string_base < ITERATOR_TYPE >::construct2(const RANGE& range)
402{
403
404 auto pmetadata = string_base::NATURAL_META_DATA::from_data(range.m_begin);
405
406 pmetadata->natural_increment_reference_count();
407
408 this->m_begin = (const CHARACTER*)range.m_begin;
409
410 this->m_end = (const CHARACTER*)range.m_end;
411
412 this->m_erange = range.m_erange;
413
414}
415
416
417//template < typename ITERATOR_TYPE >
418//template < prototype_character CHARACTER2 >
419//inline void string_base < ITERATOR_TYPE >::construct5(const CHARACTER2* p, character_count len)
420//{
421//
422// if (::is_null(p) || len <= 0)
423// {
424//
425// default_construct();
426//
427// return;
428//
429// }
430//
431// auto dstlen = utf_to_utf_length(this->begin(), p, len);
432//
433// create_string(dstlen);
434//
435// utf_to_utf((CHARACTER *)this->m_begin, p, len);
436//
437// *(CHARACTER*)this->m_end = (CHARACTER)0;
438//
439//}
440
441
442//template < typename ITERATOR_TYPE >
443//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
444//inline string_base < ITERATOR_TYPE >::string_base(const const_string_range_static_array < const OTHER_CHARACTER *, t_size > & a)
445//{
446//
447// character_count iaLen[t_size];
448//
449// character_count * plen = iaLen;
450//
451// auto len = a.__utf_length(this->begin(), plen);
452//
453// create_string(len);
454//
455// auto p = (CHARACTER * ) this->m_begin;
456//
457// plen = iaLen;
458//
459// a.__utf_concatenate_to(p, plen);
460//
461// *p = {};
462//
463//}
464
465
466//template < typename ITERATOR_TYPE >
467//void string_base< ITERATOR_TYPE >::construct1(const string_base& str)
468//{
469//
470// this->m_begin = str.m_begin;
471// this->m_end = str.m_end;
472// this->m_erange = str.m_erange;
473//
474// auto pmetadata = string_base::NATURAL_META_DATA::from_data(this->m_begin);
475//
476// pmetadata->natural_increment_reference_count();
477//
478//}
479//
480
481//template < typename ITERATOR_TYPE >
482//template < typename RANGE >
483//void string_base< ITERATOR_TYPE >::construct10(const RANGE& range)/* requires
484//::std::is_base_of_v < ::range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE >
485//&& !
486//(::std::is_base_of_v < string_base < ITERATOR_TYPE >, RANGE >
487// || ::std::is_same_v < string_base < ITERATOR_TYPE >, RANGE >)*/
488//{
489//
490// if (range.m_erange & e_range_string)
491// {
492//
493// this->construct1(*(const string_base*)&range);
494//
495// }
496// else
497// {
498//
499// this->construct5(range.data(), range.size());
500//
501// }
502//
503//}
504
505
506//template < typename ITERATOR_TYPE >
507//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
508//inline void string_base < ITERATOR_TYPE >::construct20(const ::range < const OTHER_CHARACTER* > & range)
509//{
510//
511// character_count len = __utf_to_utf_length(this->m_begin, range.m_begin, range.size());
512//
513// auto p = create_string(len);
514//
515// auto plen = &len;
516//
517// range.__utf_concatenate_to(p, plen);
518//
519// *p = {};
520//
521//}
522
523
524//template < typename ITERATOR_TYPE >
525//template < prototype_character CHARACTER2 >
526//inline void string_base < ITERATOR_TYPE >::construct20(const CHARACTER2 * start, character_count length, enum_range erange)
527//{
528//
529// if constexpr (sizeof(CHARACTER) == sizeof(CHARACTER2))
530// {
531//
532// if(erange & e_range_string)
533// {
534//
535// auto pmetadata = string_base::NATURAL_META_DATA::from_data(start);
536//
537// pmetadata->natural_increment_reference_count();
538//
539// this->m_begin = start;
540// this->m_end = start + length;
541// this->m_erange = erange;
542//
543// }
544// else
545// {
546//
547// this->construct1(start, length);
548//
549// }
550//
551// }
552// else
553// {
554//
555// this->construct5(start, length);
556//
557// }
558//
559//}
560
561
562//template < typename ITERATOR_TYPE >
563//template < prototype_character CHARACTER2 >
564//inline string_base < ITERATOR_TYPE >::string_base(CHARACTER2 chSrc, character_count repeat) :
565// string_base(nullptr)
566//{
567//
568// if (repeat <= 0)
569// {
570//
571// default_construct();
572//
573// return;
574//
575// }
576//
577// auto lenUnit = utf_to_utf_length(this->begin(), &chSrc, 1);
578//
579// auto len = lenUnit * repeat;
580//
581// create_string(len);
582//
583// CHARACTER sz[8];
584//
585// utf_to_utf(sz, &chSrc, 1);
586//
587// auto pTarget = (CHARACTER*) this->m_begin;
588//
589// while (repeat > 0)
590// {
591//
592// auto pSource = sz;
593//
594// for (::i32 j = 0; j < lenUnit; j++, pSource++)
595// {
596//
597// *pTarget++ = *pSource;
598//
599// }
600//
601// repeat--;
602//
603// }
604//
605// *(CHARACTER *)this->m_end = (CHARACTER)0;
606//
607//}
608
609
610//template < typename ITERATOR_TYPE >
611//inline string_base < ITERATOR_TYPE >::string_base(::ansi_character ansich, character_count repeat)
612//{
613//
614// assign(ansich, repeat);
615//
616//}
617//
618//
619//template < typename ITERATOR_TYPE >
620//inline string_base < ITERATOR_TYPE >::string_base(::wd16_character wd16ch, character_count repeat)
621//{
622//
623// assign(wd16ch, repeat);
624//
625//}
626//
627//
628//template < typename ITERATOR_TYPE >
629//inline string_base < ITERATOR_TYPE >::string_base(::wd32_character wd32ch, character_count repeat)
630//{
631//
632// assign(wd32ch, repeat);
633//
634//}
635
636
637template < typename ITERATOR_TYPE >
638inline character_count const_string_range < ITERATOR_TYPE >::unichar_count() const
639{
640
641 return ::unichar_count(this->begin());
642
643}
644
645
646//template < typename ITERATOR_TYPE >
647//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const natural_ansistring & ansistrSrc)
648//{
649//
650// return assign(*this, ansistrSrc);
651//
652//}
653
654
655//template < typename ITERATOR_TYPE >
656//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const natural_wd16string & wd16strSrc)
657//{
658//
659// return assign(*this, wd16strSrc);
660//
661//}
662
663
664//template < typename ITERATOR_TYPE >
665//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const natural_wd32string & wd32strSrc)
666//{
667//
668// return assign(*this, wd32strSrc.begin());
669//
670//}
671
672
673//template < typename ITERATOR_TYPE >
674//template < prototype_character CHARACTER2 >
675//string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const ::scoped_string_base < const CHARACTER2 * > & scopedstr)
676//{
677//
678// assign(scopedstr);
679//
680// return *this;
681//
682//}
683
684
685
686//template < typename ITERATOR_TYPE >
687//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const string_base & str)
688//{
689//
690// assign(scopedstr);
691//
692// return *this;
693//
694//}
695
696
697//template < typename ITERATOR_TYPE >
698//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const wd16_string & wd16str)
699//{
700//
701// return assign(*this, wd16str.begin());
702//
703//}
704
705
706//template < typename ITERATOR_TYPE >
707//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const wd32_string & wd32str)
708//{
709//
710// return assign(*this, wd32str.begin());
711//
712//}
713
714
715//template < typename ITERATOR_TYPE >
716//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const_char_pointer pansichar)
717//{
718//
719// return assign(*this, pansichar);
720//
721//}
722//
723//
724//template < typename ITERATOR_TYPE >
725//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const ::wd16_character * pwd16char)
726//{
727//
728// return assign(*this, pwd16char);
729//
730//}
731//
732//
733//template < typename ITERATOR_TYPE >
734//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const ::wd32_character * pwd32char)
735//{
736//
737// return assign(*this, pwd32char);
738//
739//}
740//
741//
742//template < typename ITERATOR_TYPE >
743//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(::ansi_character ansich)
744//{
745//
746// return assign(*this, ansich);
747//
748//}
749//
750//
751//template < typename ITERATOR_TYPE >
752//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(::wd16_character wd16ch)
753//{
754//
755// return assign(*this, wd16ch);
756//
757//}
758//
759//
760//template < typename ITERATOR_TYPE >
761//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(::wd32_character wd32ch)
762//{
763//
764// return assign(*this, wd32ch);
765//
766//}
767//
768//
769//template < typename ITERATOR_TYPE >
770//template < ::i32 t_nSize >
771//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator =(const static_string<CHARACTER, t_nSize > & ansistrSrc)
772//{
773//
774// assign(ansistrSrc);
775//
776// return *this;
777//
778//}
779
780//template < typename ITERATOR_TYPE >
781//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const string_base & str)
782//{
783//
784// return append(scopedstr);
785//
786//}
787
788
789//template < typename ITERATOR_TYPE >
790//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const ::const_ansi_range & scopedstr)
791//{
792//
793// return append(scopedstr);
794//
795//}
796
797
798//template < typename ITERATOR_TYPE >
799//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const const_wd16_range & wd16scopedstr)
800//{
801//
802// return append(wd16scopedstr);
803//
804//}
805//
806//
807//template < typename ITERATOR_TYPE >
808//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const const_wd32_range & wd32scopedstr)
809//{
810//
811// return append(wd32scopedstr);
812//
813//}
814
815
816//template < typename ITERATOR_TYPE >
817//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const inline_number_string & inlinenumberstring)
818//{
819//
820// return append(inlinenumberstring);
821//
822//}
823
824
825
826//template < typename ITERATOR_TYPE >
827//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const_char_pointer pszSrc)
828//{
829//
830// return append(scopedstrSrc);
831//
832//}
833//
834//
835//template < typename ITERATOR_TYPE >
836//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const ::wd16_character * pszSrc)
837//{
838//
839// return append(scopedstrSrc);
840//
841//}
842//
843//
844//template < typename ITERATOR_TYPE >
845//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const ::wd32_character * pszSrc)
846//{
847//
848// return append(scopedstrSrc);
849//
850//}
851//
852//
853//template < typename ITERATOR_TYPE >
854//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(::ansi_character ansich)
855//{
856//
857// return append(ansich);
858//
859//}
860//
861//
862//template < typename ITERATOR_TYPE >
863//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(::wd16_character wd16ch)
864//{
865//
866// return append(wd16ch);
867//
868//}
869//
870//
871//template < typename ITERATOR_TYPE >
872//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(::wd32_character wd32ch)
873//{
874//
875// return append(wd32ch);
876//
877//}
878
879
880//template < typename ITERATOR_TYPE >
881//template < ::i32 t_nSize >
882//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const static_string<CHARACTER, t_nSize > & ansistrSrc)
883//{
884//
885// return append(ansistrSrc);
886//
887//}
888
889
890//template < typename ITERATOR_TYPE >
891//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd16_character wd16ch) const
892//{
893//
894// string_base < ITERATOR_TYPE > ansistr;
895//
896// ansistr.append(wd16ch);
897//
898// return ansistr;
899//
900//}
901//
902//
903//template < typename ITERATOR_TYPE >
904//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd32_character wd32ch) const
905//{
906//
907// string_base < ITERATOR_TYPE > ansistr;
908//
909// ansistr.append(wd32ch);
910//
911// return ansistr;
912//
913//}
914
915
916//template < typename ITERATOR_TYPE >
917//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_char_pointer psz) const
918//{
919//
920// auto scopedstr(*this);
921//
922// scopedstr += psz;
923//
924// return ::transfer(scopedstr);
925//
926//}
927//
928//
929//template < typename ITERATOR_TYPE >
930//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const ::wd16_character * pwsz) const
931//{
932//
933// auto scopedstr(*this);
934//
935// scopedstr += pwsz;
936//
937// return ::transfer(scopedstr);
938//
939//}
940//
941//
942//template < typename ITERATOR_TYPE >
943//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const ::wd32_character * pwsz) const
944//{
945//
946// auto scopedstr(*this);
947//
948// scopedstr += pwsz;
949//
950// return ::transfer(scopedstr);
951//
952//}
953
954
955//template < typename ITERATOR_TYPE >
956//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_ansi_range ansiscopedstr) const
957//{
958//
959// auto scopedstr(*this);
960//
961// scopedstr += ansiscopedstr;
962//
963// return ::transfer(scopedstr);
964//
965//}
966//
967//
968//template < typename ITERATOR_TYPE >
969//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_wd16_range scopedstr) const
970//{
971//
972// auto scopedstr(*this);
973//
974// scopedstr += scopedstr;
975//
976// return ::transfer(scopedstr);
977//
978//}
979//
980//
981//template < typename ITERATOR_TYPE >
982//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_wd32_range scopedstr) const
983//{
984//
985// auto scopedstr(*this);
986//
987// scopedstr += scopedstr;
988//
989// return ::transfer(scopedstr);
990//
991//}
992
993
994
995//template < typename ITERATOR_TYPE >
996//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const inline_number_string & inlinenumberstring) const
997//{
998//
999// auto scopedstr(*this);
1000//
1001// scopedstr.append(inlinenumberstring);
1002//
1003// return ::transfer(scopedstr);
1004//
1005//}
1006//
1007//
1008//template < typename ITERATOR_TYPE >
1009//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::ansi_character ansich) const
1010//{
1011//
1012// auto scopedstr(*this);
1013//
1014// scopedstr += ansich;
1015//
1016// return ::transfer(scopedstr);
1017//
1018//}
1019//
1020//
1021//template < typename ITERATOR_TYPE >
1022//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd16_character wd16ch) const
1023//{
1024//
1025// auto scopedstr(*this);
1026//
1027// ansistr += wd16ch;
1028//
1029// return ::transfer(scopedstr);
1030//
1031//}
1032//
1033//
1034//
1035//template < typename ITERATOR_TYPE >
1036//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd32_character wd32ch) const
1037//{
1038//
1039// auto scopedstr(*this);
1040//
1041// scopedstr += wd32ch;
1042//
1043// return ::transfer(scopedstr);
1044//
1045//}
1046//
1047
1048
1049//template < typename ITERATOR_TYPE >
1050//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const string_base & str)
1051//{
1052//
1053// NATURAL_POINTER::operator=(str);
1054//
1055// return *this;
1056//
1057//}
1058
1059
1060//template < typename ITERATOR_TYPE >
1061//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(string_base && scopedstr)
1062//{
1063//
1064// NATURAL_POINTER::operator=(::transfer(scopedstr));
1065//
1066// return *this;
1067//
1068//}
1069
1070
1071//template < typename ITERATOR_TYPE >
1072//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const ansi_string & strSrc)
1073//{
1074//
1075// return assign(*this, strSrc.begin());
1076//
1077//}
1078//
1079//
1080//template < typename ITERATOR_TYPE >
1081//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd16_string & strSrc)
1082//{
1083//
1084// return assign(*this, strSrc.begin());
1085//
1086//}
1087//
1088//
1089//template < typename ITERATOR_TYPE >
1090//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd32_string & strSrc)
1091//{
1092//
1093// return assign(*this, strSrc.begin());
1094//
1095//}
1096//
1097
1098
1099template < typename ITERATOR_TYPE >
1100template < prototype_character CHARACTER2 >
1101inline ::string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const CHARACTER2 * start, character_count len)
1102{
1103
1104 _assign(start, len);
1105
1106 return *this;
1107
1108}
1109
1110
1111//template < typename ITERATOR_TYPE >
1112//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd16_string & widestrSrc, character_count count)
1113//{
1114//
1115// return assign(*this, widestrSrc.begin() + pos, count);
1116//
1117//}
1118//
1119//
1120//template < typename ITERATOR_TYPE >
1121//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd32_string & widestrSrc, character_count count)
1122//{
1123//
1124// return assign(*this, widestrSrc.begin() + pos, count);
1125//
1126//}
1127
1128//
1129//template < typename ITERATOR_TYPE >
1130//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const_char_pointer pszSrc)
1131//{
1132//
1133// return assign(*this, pszSrc);
1134//
1135//}
1136//
1137
1138
1139//template < typename ITERATOR_TYPE >
1140//template < prototype_character CHARACTER2 >
1141//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::start_count_length(character_count & start, character_count & count, const CHARACTER2 * pszSource)
1142//{
1143//
1144// character_count len = -1;
1145//
1146// if (start < 0)
1147// {
1148//
1149// start = 0;
1150//
1151// }
1152//
1153// if (count < 0)
1154// {
1155//
1156// len = string_safe_length(scopedstrSource);
1157//
1158// count += (len - start) + 1;
1159//
1160// if (count < 0)
1161// {
1162//
1163// count = 0;
1164//
1165// }
1166//
1167// }
1168//
1169// if (len < 0)
1170// {
1171//
1172// len = string_safe_length(scopedstrSource, start + count);
1173//
1174// if (len < 0)
1175// {
1176//
1177// return start + count;
1178//
1179// }
1180//
1181// }
1182//
1183// if (count + start > len)
1184// {
1185//
1186// count = len - start;
1187//
1188// }
1189//
1190// return len;
1191//
1192//}
1193
1194
1195//template < typename ITERATOR_TYPE >
1196//inline void string_range < ITERATOR_TYPE >::start_count(character_count & start, character_count & count, character_count len)
1197//{
1198//
1199// if (start < 0)
1200// {
1201//
1202// start = 0;
1203//
1204// }
1205//
1206// if (count < 0)
1207// {
1208//
1209// count += (len - start) + 1;
1210//
1211// if (count < 0)
1212// {
1213//
1214// count = 0;
1215//
1216// }
1217//
1218// }
1219//
1220// if (count + start > len)
1221// {
1222//
1223// count = len - start;
1224//
1225// }
1226//
1227//}
1228
1229
1230//template < typename ITERATOR_TYPE >
1231//template < prototype_character CHARACTER2 >
1232//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const CHARACTER2 * pszSource)
1233//{
1234//
1235// start_count_length(start, count, pszSource);
1236//
1237// return _assign(scopedstrSource, start, count);
1238//
1239//}
1240
1241
1242template < typename ITERATOR_TYPE >
1243template < prototype_character CHARACTER2 >
1244inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::_assign(const CHARACTER2 * pszSource, character_count len)
1245{
1246
1247 auto dstlen = utf_to_utf_length(this->begin(), pszSource, len);
1248
1249 if (dstlen <= 0)
1250 {
1251
1252 this->empty();
1253
1254 }
1255 else
1256 {
1257
1258 auto pszTarget = this->get_buffer(dstlen);
1259
1260 utf_to_utf(scopedstrTarget, pszSource, len);
1261
1262 this->release_buffer(dstlen);
1263
1264 }
1265
1266 return *this;
1267
1268}
1269
1270
1271//template < typename ITERATOR_TYPE >
1272//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const ::wd16_character * pwd16sz)
1273//{
1274//
1275// return assign(*this, pwd16sz);
1276//
1277//}
1278//
1279
1280//template < typename ITERATOR_TYPE >
1281//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const ::wd16_character * pwd16sz, character_count len)
1282//{
1283//
1284// return assign(*this, pwd16sz, len);
1285//
1286//}
1287
1288
1289//template < typename ITERATOR_TYPE >
1290//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const ::wd32_character * pwd32sz)
1291//{
1292//
1293// return assign(*this, pwd32sz);
1294//
1295//}
1296
1297
1298//template < typename ITERATOR_TYPE >
1299//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const ::wd32_character * pwd32sz, character_count len)
1300//{
1301//
1302// return assign(*this, pwd32sz, len);
1303//
1304//}
1305
1306
1307//template < typename ITERATOR_TYPE >
1308//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(::ansi_character ansich)
1309//{
1310//
1311// return assign(*this, &ansich, 1);
1312//
1313//}
1314//
1315//
1316//template < typename ITERATOR_TYPE >
1317//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(::wd16_character wd16ch)
1318//{
1319//
1320// return assign(*this, &wd16ch, 1);
1321//
1322//}
1323//
1324//
1325//template < typename ITERATOR_TYPE >
1326//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(::wd32_character wd32ch)
1327//{
1328//
1329// return assign(*this, &wd32ch, 1);
1330//
1331//}
1332
1333
1334template < typename ITERATOR_TYPE >
1335template < prototype_character CHARACTER2 >
1336inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(CHARACTER2 chSrc, character_count repeat)
1337{
1338
1339 if (repeat > 0)
1340 {
1341
1342 auto lenUnit = utf_to_utf_length(this->begin(), &chSrc, 1);
1343
1344 auto len = lenUnit * repeat;
1345
1346 auto psz = get_buffer(len);
1347
1348 CHARACTER sz[8];
1349
1350 utf_to_utf(sz, &chSrc, 1);
1351
1352 auto pTarget = psz;
1353
1354 while (repeat > 0)
1355 {
1356
1357 auto pSource = sz;
1358
1359 for (::collection::index j = 0; j < lenUnit; j++)
1360 {
1361
1362 *pTarget++ = *pSource;
1363
1364 }
1365
1366 repeat--;
1367
1368 }
1369
1370 release_buffer(len);
1371
1372 }
1373 else
1374 {
1375
1376 this->empty();
1377
1378 }
1379
1380 return *this;
1381
1382}
1383
1384
1385//template < typename ITERATOR_TYPE >
1386//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(::wd16_character wd16ch, character_count repeat)
1387//{
1388//
1389// if (repeat > 0)
1390// {
1391//
1392// auto lenUnit = utf_to_utf_length(this->begin(), &wd16ch, 1);
1393//
1394// auto len = lenUnit * repeat;
1395//
1396// auto psz = get_buffer(len);
1397//
1398// CHARACTER sz[8];
1399//
1400// utf_to_utf(sz, &wd16ch, 1);
1401//
1402// for (::collection::index i = 0; i < len; i += lenUnit)
1403// {
1404//
1405// ::memory_copy(scopedstr, sz, lenUnit * sizeof(CHARACTER));
1406//
1407// psz += lenUnit;
1408//
1409// }
1410//
1411// release_buffer(len);
1412//
1413// }
1414// else
1415// {
1416//
1417// this->natural_release();
1418//
1419// }
1420//
1421// return *this;
1422//
1423//}
1424
1425
1426//template < typename ITERATOR_TYPE >
1427//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(::wd32_character wd32ch, character_count repeat)
1428//{
1429//
1430// if (repeat > 0)
1431// {
1432//
1433// auto lenUnit = utf_to_utf_length(this->begin(), &wd32ch, 1);
1434//
1435// auto len = lenUnit * repeat;
1436//
1437// auto psz = get_buffer(len);
1438//
1439// CHARACTER sz[8];
1440//
1441// utf_to_utf(sz, &wd32ch, 1);
1442//
1443// for (::collection::index i = 0; i < len; i += lenUnit)
1444// {
1445//
1446// ::memory_copy(scopedstr, sz, lenUnit * sizeof(CHARACTER));
1447//
1448// psz += lenUnit;
1449//
1450// }
1451//
1452// release_buffer(len);
1453//
1454// }
1455// else
1456// {
1457//
1458// this->natural_release();
1459//
1460// }
1461//
1462// return *this;
1463//
1464//}
1465
1466
1467//template < typename ITERATOR_TYPE >
1468//template < ::i32 t_nSize >
1469//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const static_string<CHARACTER, t_nSize > & ansistrSrc)
1470//{
1471//
1472// return assign(ansistrSrc.begin(), ansistrSrc.length());
1473//
1474//}
1475//
1476
1477//
1478//template < typename ITERATOR_TYPE >
1479//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::const_ansi_range & ansiscopedstr)
1480//{
1481//
1482// return _append(ansiscopedstr.begin(), ansiscopedstr.size());
1483//
1484//}
1485
1486
1487//template < typename ITERATOR_TYPE >
1488//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::const_wd16_range & wd16scopedstr)
1489//{
1490//
1491// return _append(wd16scopedstr.begin(), wd16scopedstr.size());
1492//
1493//}
1494
1495
1496//template < typename ITERATOR_TYPE >
1497//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::const_wd32_range & wd32scopedstr)
1498//{
1499//
1500// return _append(wd32scopedstr.begin(), wd32scopedstr.size());
1501//
1502//}
1503
1504
1505//template < typename ITERATOR_TYPE >
1506//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const wd16_string & wd16strSrc)
1507//{
1508//
1509// return append(wd16strSrc.begin(), wd16strSrc.size());
1510//
1511//}
1512//
1513//
1514//template < typename ITERATOR_TYPE >
1515//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const wd32_string & wd32strSrc)
1516//{
1517//
1518// return append(wd32strSrc.begin(), wd32strSrc.size());
1519//
1520//}
1521
1522
1523//template < typename ITERATOR_TYPE >
1524//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const_char_pointer pszSrc)
1525//{
1526//
1527// return append(scopedstrSrc, string_safe_length(scopedstrSrc));
1528//
1529//}
1530//
1531//
1532//template < typename ITERATOR_TYPE >
1533//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::wd16_character * pwszSrc)
1534//{
1535//
1536// return append(pwszSrc, string_safe_length(pwszSrc));
1537//
1538//}
1539//
1540
1541//template < typename ITERATOR_TYPE >
1542//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::wd32_character * pwszSrc)
1543//{
1544//
1545// return append(pwszSrc, string_safe_length(pwszSrc));
1546//
1547//}
1548
1549
1550template < typename ITERATOR_TYPE >
1551template < other_primitive_character < typename ::string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
1552inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::_append(const OTHER_CHARACTER * pszSrc, character_count count)
1553{
1554
1555 auto nOldLength = this->length();
1556
1557 if (nOldLength < 0)
1558 {
1559
1560 nOldLength = 0;
1561
1562 }
1563
1564 character_count nNewLength = nOldLength + utf_to_utf_length(this->begin(), pszSrc, count);
1565
1566 auto pszBuffer = get_buffer(nNewLength, true);
1567
1568 utf_to_utf(scopedstrBuffer + nOldLength, pszSrc, count);
1569
1570 release_buffer(nNewLength);
1571
1572 return *this;
1573
1574}
1575
1576
1577//template < typename ITERATOR_TYPE >
1578//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::wd16_character * pszSrc)
1579//{
1580//
1581// auto nOldLength = this->length();
1582//
1583// if (nOldLength < 0)
1584// {
1585//
1586// nOldLength = 0;
1587//
1588// }
1589//
1590// character_count nNewLength = nOldLength + utf_to_utf_length(this->begin(), pszSrc, nLength);
1591//
1592// auto pszBuffer = get_buffer(nNewLength);
1593//
1594// utf_to_utf(scopedstrBuffer + nOldLength, pszSrc, nLength);
1595//
1596// release_buffer(nNewLength);
1597//
1598// return *this;
1599//
1600//}
1601//
1602//
1603//template < typename ITERATOR_TYPE >
1604//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const ::wd32_character * pszSrc)
1605//{
1606//
1607// auto nOldLength = this->length();
1608//
1609// if (nOldLength < 0)
1610// {
1611//
1612// nOldLength = 0;
1613//
1614// }
1615//
1616// character_count nNewLength = nOldLength + utf_to_utf_length(this->begin(), pszSrc, nLength);
1617//
1618// auto pszBuffer = get_buffer(nNewLength);
1619//
1620// utf_to_utf(scopedstrBuffer + nOldLength, pszSrc, nLength);
1621//
1622// release_buffer(nNewLength);
1623//
1624// return *this;
1625//
1626//}
1627
1628
1629template < typename ITERATOR_TYPE >
1630inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_character(::ansi_character ch)
1631{
1632
1633 return append(&ch, 1);
1634
1635}
1636
1637
1638template < typename ITERATOR_TYPE >
1639inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_character(::wd16_character wch)
1640{
1641
1642 return append(&wch, 1);
1643
1644}
1645
1646
1647template < typename ITERATOR_TYPE >
1648inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_character(::wd32_character wch)
1649{
1650
1651 return append(&wch, 1);
1652
1653}
1654
1655
1656template < typename ITERATOR_TYPE >
1657inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(character_count len, CHARACTER ch)
1658{
1659
1660 if (len > 0)
1661 {
1662
1663 character_count nOldLength = this->size();
1664
1665 character_count nNewLength = nOldLength + len;
1666
1667 CHARACTER * pszBuffer = this->get_buffer(nNewLength, true);
1668
1669 auto pch = pszBuffer + nOldLength;
1670
1671 auto p = pch + len - 1;
1672
1673 while (p >= pch)
1674 {
1675
1676 *p = ch;
1677
1678 p--;
1679
1680 }
1681
1682 this->release_buffer(nNewLength);
1683
1684 }
1685
1686 return *this;
1687
1688}
1689
1690//
1691//template < typename ITERATOR_TYPE >
1692//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(character_count len, ::ansi_character ch)
1693//{
1694//
1695// if (len > 0)
1696// {
1697//
1698// character_count nOldLength = this->size();
1699//
1700// character_count nNewLength = nOldLength + len;
1701//
1702// CHARACTER * pszBuffer = this->get_buffer(nNewLength);
1703//
1704// CHARACTER
1705//
1706// auto pch = pszBuffer + nOldLength;
1707//
1708// auto p = pch + len - 1;
1709//
1710// while (p >= pch)
1711// {
1712//
1713// *p = ch;
1714//
1715// p--;
1716//
1717// }
1718//
1719// this->release_buffer(nNewLength);
1720//
1721// }
1722//
1723// return *this;
1724//
1725//}
1726
1727
1728
1729//template < typename ITERATOR_TYPE >
1730//template < typename STATIC_TYPE_CHAR, ::i32 t_nSize >
1731//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append(const static_string<STATIC_TYPE_CHAR, t_nSize > & ansistrSrc)
1732//{
1733//
1734// return append(ansistrSrc.begin(), ansistrSrc.length());
1735//
1736//}
1737
1738
1739//template < typename ITERATOR_TYPE >
1740//inline ::std::strong_ordering string_base < ITERATOR_TYPE > ::order(const SCOPED_STRING & scopedstr) const noexcept
1741//{
1742//
1743// return this->BASE_RANGE::order(scopedstr, ::comparison::comparison <CHARACTER>());
1744//
1745//}
1746
1747
1748
1749//
1750//template < typename ITERATOR_TYPE >
1751//inline ::std::strong_ordering string_base < ITERATOR_TYPE > ::order(character_count start, character_count count, const SCOPED_STRING & scopedstr, character_count iStart2, character_count iCount2) const noexcept
1752//{
1753//
1754// if (start + count > size())
1755// {
1756//
1757// throw_exception(error_bad_argument);
1758//
1759// }
1760//
1761// if (iStart2 + iCount2 > scopedstr.size())
1762// {
1763//
1764// throw_exception(error_bad_argument);
1765//
1766// }
1767//
1768// return string_compare(this->begin() + start, count, scopedstr.begin() + iStart2, iCount2);
1769//
1770//}
1771//
1772//
1773//template < typename ITERATOR_TYPE >
1774//inline ::std::strong_ordering string_base < ITERATOR_TYPE > ::case_insensitive_order(character_count start, character_count count, const SCOPED_STRING & scopedstr, character_count iStart2, character_count iCount2) const noexcept
1775//{
1776//
1777// if (start + count > size())
1778// {
1779//
1780// throw_exception(error_bad_argument);
1781//
1782// }
1783//
1784// if (iStart2 + iCount2 > scopedstr.size())
1785// {
1786//
1787// throw_exception(error_bad_argument);
1788//
1789// }
1790//
1791// return case_insensitive_string_order(this->begin() + start, count, scopedstr.begin() + iStart2, iCount2);
1792//
1793//}
1794//
1795//
1796//template < typename ITERATOR_TYPE >
1797//inline ::std::strong_ordering string_base < ITERATOR_TYPE > ::collate(character_count start, character_count count, const SCOPED_STRING & scopedstr, character_count iStart2, character_count iCount2) const noexcept
1798//{
1799//
1800// if (start + count > size())
1801// {
1802//
1803// throw_exception(error_bad_argument);
1804//
1805// }
1806//
1807// if (iStart2 + iCount2 > scopedstr.size())
1808// {
1809//
1810// throw_exception(error_bad_argument);
1811//
1812// }
1813//
1814// return string_collate(this->begin() + start, count, scopedstr.begin() + iStart2, iCount2);
1815//
1816//}
1817//
1818//
1819//template < typename ITERATOR_TYPE >
1820//inline ::std::strong_ordering string_base < ITERATOR_TYPE > ::case_insensitive_collate(character_count start, character_count count, const SCOPED_STRING & scopedstr, character_count iStart2, character_count iCount2) const noexcept
1821//{
1822//
1823// if (start + count > size())
1824// {
1825//
1826// throw_exception(error_bad_argument);
1827//
1828// }
1829//
1830// if (iStart2 + iCount2 > scopedstr.size())
1831// {
1832//
1833// throw_exception(error_bad_argument);
1834//
1835// }
1836//
1837// return case_insensitive_string_collate(this->begin() + start, count, scopedstr.begin() + iStart2, iCount2);
1838//
1839//}
1840
1841
1842//template < typename ITERATOR_TYPE >
1843//inline ::i32 string_base < ITERATOR_TYPE >::operator<=>(const SCOPED_STRING & scopedstr) const { return order(scopedstr); }
1846//template < typename ITERATOR_TYPE >
1847//inline bool string_base < ITERATOR_TYPE >::operator==(const SCOPED_STRING & scopedstr) const { return !order(scopedstr); }
1848//template < typename ITERATOR_TYPE >
1849//inline bool string_base < ITERATOR_TYPE >::operator==(CHARACTER ch) const { return !order((scopedstr) string_base(ch)); }
1850//template < typename ITERATOR_TYPE >
1851//inline bool string_base < ITERATOR_TYPE >::operator>(const SCOPED_STRING & scopedstr) const { return order(scopedstr) > 0; }
1852//template < typename ITERATOR_TYPE >
1853//inline bool string_base < ITERATOR_TYPE >::operator>(CHARACTER wch) const { return order(string_base(wch)) > 0; }
1854//template < typename ITERATOR_TYPE >
1855//inline bool string_base < ITERATOR_TYPE >::operator<(const SCOPED_STRING & scopedstr) const { return order(scopedstr) < 0; }
1856//template < typename ITERATOR_TYPE >
1857//inline bool string_base < ITERATOR_TYPE >::operator<(CHARACTER ch) const { return order(string_base(ch)) < 0; }
1858
1859
1860template < typename ITERATOR_TYPE >
1861template < prototype_character CHARACTER2 >
1862string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::assign(const CHARACTER2 * start, const CHARACTER2 * end)
1863{
1864
1865 return assign(start, end - start);
1866
1867}
1868
1869
1870//template < typename ITERATOR_TYPE >
1871//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_first_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1872//{
1873//
1874// return find_first_of(scopedstr, pos);
1875//
1876//}
1877//
1878//
1879//template < typename ITERATOR_TYPE >
1880//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_first_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1881//{
1882//
1883// return find_first_of(scopedstr, pos, n);
1884//
1885//}
1886
1887
1888//template < typename ITERATOR_TYPE >
1889//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_first_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1890//{
1891//
1892// return find_first_of(s, pos);
1893//
1894//}
1895//
1896//
1897//template < typename ITERATOR_TYPE >
1898//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_first_in(CHARACTER ca) const RELEASENOTHROW
1899//{
1900//
1901// return find_first_of(ca, pos);
1902//
1903//}
1904
1905//
1906//template < typename ITERATOR_TYPE >
1907//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_first_character_in(const SCOPED_STRING & scopedstrSeparators) const RELEASENOTHROW
1908//{
1909//
1910// return this->find_first_character_in(scopedstrSeparators, ::comparison::comparison < CHARACTER >());
1911//
1912//}
1913
1914
1915//template < typename ITERATOR_TYPE >
1916//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::get_token(const SCOPED_STRING & scopedstrSeparators) const RELEASENOTHROW
1917//{
1918//
1919// auto psz = ::string_token({ this->begin() + pos, n }, scopedstrSeparators);
1920//
1921// return ::is_set(scopedstr) ? (::character_count)psz - this->begin() : -1;
1922//
1923//}
1924//
1925//
1926//template < typename ITERATOR_TYPE >
1927//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::get_token(const CHARACTER * pszSeparators) const RELEASENOTHROW
1928//{
1929//
1930// return ::string_token(this->begin() + pos, pszSeparators);
1931//
1932//}
1933//
1934//
1935//template < typename ITERATOR_TYPE >
1936//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::get_token(CHARACTER chSeparator) const RELEASENOTHROW
1937//{
1938//
1939// return ::string_find_character(ca, pos);
1940//
1941//}
1942
1943
1944//template < typename ITERATOR_TYPE >
1945//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::skip_any_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1946//{
1947//
1948// return this->skip_any_character_in(scopedstr, ::comparison::comparison < CHARACTER >());
1949//
1950//}
1951
1952
1953//template < typename ITERATOR_TYPE >
1954//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::skip_any_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1955//{
1956//
1957// return this->skip_any_character_in(scopedstr, ::comparison::comparison < CHARACTER >());
1958//
1959//}
1960
1961
1962//template < typename ITERATOR_TYPE >
1963//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::skip_any_character_in(const CHARACTER * psz) const RELEASENOTHROW
1964//{
1965//
1966// return offset_of(::scoped_string_base < const CHARACTER * >(this->begin() + pos, size() - pos).span(scopedstr, ::comparison::comparison < CHARACTER >()));
1967//
1968//}
1969
1970
1971//template < typename ITERATOR_TYPE >
1972//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::skip(CHARACTER chSkip) const RELEASENOTHROW
1973//{
1974//
1975// return this->skip(chSkip, ::comparison::comparison < CHARACTER >());
1976//
1977//}
1978
1979
1980//template < typename ITERATOR_TYPE >
1981//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_find_first_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1982//{
1983//
1984// return this->_find_first_character_in(scopedstr, ::comparison::comparison < CHARACTER >());
1985//
1986//}
1987
1988
1989//template < typename ITERATOR_TYPE >
1990//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_find_first_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
1991//{
1992//
1993// return offset_of(::scoped_string_base < const CHARACTER * >({ this->begin() + pos, n })._find_first_character_in(scopedstr, ::comparison::comparison < CHARACTER >()));
1994//
1995//}
1996
1997
1998//template < typename ITERATOR_TYPE >
1999//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_find_first_character_in(const CHARACTER * psz) const RELEASENOTHROW
2000//{
2001//
2002// return offset_of(::scoped_string_base < const CHARACTER * >(this->begin() + pos)._find_first_character_in(scopedstr, ::comparison::comparison < CHARACTER >()));
2003//
2004//}
2005
2006
2007//template < typename ITERATOR_TYPE >
2008//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_skip(CHARACTER chSkip) const RELEASENOTHROW
2009//{
2010//
2011// return this->_skip(chSkip, ::comparison::comparison < CHARACTER >());
2012//
2013//}
2014
2015
2016//template < typename ITERATOR_TYPE >
2017//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_last_not_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2018//{
2019//
2020// return find_last_not_of(scopedstr, pos);
2021//
2022//}
2023
2024
2025//template < typename ITERATOR_TYPE >
2026//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::find_last_not_in(CHARACTER ca) const RELEASENOTHROW
2027//{
2028//
2029// return find_last_not_of(ca, pos);
2030//
2031//}
2032
2033
2034//template < typename ITERATOR_TYPE >
2035//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::rear_find_first_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2036//{
2037//
2038// return BASE_RANGE::rear_find_first_character_in(scopedstr, ::comparison::comparison < CHARACTER >());
2039//
2040//}
2041
2042
2043//template < typename ITERATOR_TYPE >
2044//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::rear_find_first_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2045//{
2046//
2047// return offset_of(BASE_RANGE::rear_find_first_character_in_start_count(scopedstr, count));
2048//
2049//}
2050
2051
2052//template < typename ITERATOR_TYPE >
2053//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::rear_find_first_character_in(const CHARACTER * psz, character_count count) const RELEASENOTHROW
2054//{
2055//
2056// return offset_of(::string_rear_find_first_character_in({this->begin(), size() + count + 1}, {psz, ::string_safe_length(scopedstr)}));
2057//
2058//}
2059
2060
2061//template < typename ITERATOR_TYPE >
2062//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_rear_find_first_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2063//{
2064//
2065// return offset_of(BASE_RANGE::_rear_find_first_character_in_start(scopedstr));
2066//
2067//}
2068
2069
2070//
2071//template < typename ITERATOR_TYPE >
2072//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_rear_find_first_character_in(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2073//{
2074//
2075// return offset_of(BASE_RANGE::_rear_find_first_character_in_start_count(scopedstr, start, count));
2076//
2077//}
2078//
2079
2080//template < typename ITERATOR_TYPE >
2081//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::_rear_find_first_character_in(const CHARACTER * psz, character_count count) const RELEASENOTHROW
2082//{
2083//
2084// return offset_of(::_string_rear_find_first_character_in({this->begin(), size() + count + 1}, {psz, ::string_safe_length(scopedstr)}));
2085//
2086//}
2087
2088
2089//template < typename ITERATOR_TYPE >
2090//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::rear_find(CHARACTER ch) const RELEASENOTHROW
2091//{
2092//
2093// return this->rear_find(ch, comparison::comparison < CHARACTER >());
2094//
2095//}
2096
2097
2098template < typename ITERATOR_TYPE >
2099inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_left(character_count count) const
2100{
2101
2102 return { this->begin(), this->unichar_at(count) };
2103
2104}
2105
2106
2107
2108template < typename ITERATOR_TYPE >
2109inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iFirst) const
2110{
2111
2112 return { this->unichar_at(iFirst), this->end() };
2113
2114}
2115
2116
2117template < typename ITERATOR_TYPE >
2118inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iStart, character_count iCount) const
2119{
2120
2121 return { this->unichar_at(iStart), this->unichar_at(iStart + iCount) };
2122
2123}
2124
2125
2126//template < typename ITERATOR_TYPE >
2127//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::erase(character_count iIndex, character_count count)
2128//{
2129//
2130// return Delete(iIndex, count);
2131//
2132//}
2133
2134
2135template < prototype_character CHARACTER >
2136inline bool operator>(const CHARACTER * psz, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2137{
2138
2139 return string_compare(scopedstr, string_safe_length(scopedstr), scopedstr.begin(), scopedstr.size()) > 0;
2140
2141}
2142
2143
2144template < prototype_character CHARACTER >
2145inline bool operator > (CHARACTER ch, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2146{
2147
2148 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) > 0;
2149
2150}
2151
2152
2153template < prototype_character CHARACTER >
2154inline bool operator > (::wide_character ch, const typename ::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2155{
2156
2157 return wide_string(ch) > scopedstr;
2158
2159}
2160
2161
2162template < prototype_character CHARACTER >
2163inline bool operator>(::i32 i, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2164{
2165
2166 return ::string_base<CHARACTER>(i) > scopedstr;
2167
2168}
2169
2170
2171template < prototype_character CHARACTER >
2172inline bool operator<(const CHARACTER * psz, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2173{
2174
2175 return string_compare(scopedstr, string_save_length(scopedstr), scopedstr.begin(), scopedstr.size()) < 0;
2176
2177}
2178
2179
2180template < prototype_character CHARACTER >
2181inline bool operator<(CHARACTER ch, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2182{
2183
2184 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) < 0;
2185
2186}
2187
2188
2189template < prototype_character CHARACTER >
2190inline bool operator<(::i32 i, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
2191{
2192
2193 return ::string_base <CHARACTER>(i) < scopedstr;
2194
2195}
2196
2197
2198template < typename ITERATOR_TYPE >
2199inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::lower() const
2200{
2201
2202 return string_base < ITERATOR_TYPE >(*this).make_lower();
2203
2204}
2205
2206
2207template < typename ITERATOR_TYPE >
2208inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::upper() const
2209{
2210
2211 return string_base < ITERATOR_TYPE >(*this).make_upper();
2212
2213}
2214
2215
2216template < prototype_character CHARACTER >
2217inline const CHARACTER * FormatArgument(const typename GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr) noexcept
2218{
2219
2220 return scopedstr.begin();
2221
2222}
2223
2224
2225//template < typename ITERATOR_TYPE >
2226//inline string_base < ITERATOR_TYPE >::string_base(const SCOPED_STRING & scopedstr) :
2227// string_base((const_char_pointer )scopedstr.data(), (character_count)scopedstr.size())
2228//{
2229//
2230//
2231//}
2232
2233
2234//template < typename ITERATOR_TYPE >
2235//inline string_base < ITERATOR_TYPE >::string_base(const ansi_string & ansistr)
2236//{
2237//
2238// assign(ansistr.begin());
2239//
2240//}
2241//
2242//
2243//template < typename ITERATOR_TYPE >
2244//inline string_base < ITERATOR_TYPE >::string_base(const wd16_string & wd16str)
2245//{
2246//
2247// assign(wd16str.begin());
2248//
2249//}
2250//
2251//
2252//template < typename ITERATOR_TYPE >
2253//inline string_base < ITERATOR_TYPE >::string_base(const wd32_string & wd32str)
2254//{
2255//
2256// assign(wd32str.begin());
2257//
2258//}
2259
2260
2261//template < typename ITERATOR_TYPE >
2262//inline string_base < ITERATOR_TYPE >::string_base(const simple_ansistring & ansistr) :
2263// string_base(ansistr.begin())
2264//{
2265//
2266//}
2267//
2268//
2269//template < typename ITERATOR_TYPE >
2270//inline string_base < ITERATOR_TYPE >::string_base(const simple_wd16string & wd16str) :
2271// string_base(wd16str.begin())
2272//{
2273//
2274//}
2275//
2276//
2277//template < typename ITERATOR_TYPE >
2278//inline string_base < ITERATOR_TYPE >::string_base(const simple_wd32string & wd32str) :
2279// string_base(wd32str.begin())
2280//{
2281//
2282//}
2283
2284
2285template < typename ITERATOR_TYPE >
2286template < prototype_array A_STRING_ARRAY >
2287bool const_string_range < ITERATOR_TYPE >::contains_any(const A_STRING_ARRAY & stra) const
2288{
2289
2290 for (auto & scopedstr : stra)
2291 {
2292
2293 if (contains(scopedstr))
2294 {
2295
2296 return true;
2297
2298 }
2299
2300 }
2301
2302 return false;
2303
2304}
2305
2306
2307template < typename ITERATOR_TYPE >
2308template < prototype_array A_STRING_ARRAY >
2309bool const_string_range < ITERATOR_TYPE >::contains_all(const A_STRING_ARRAY & stra) const
2310{
2311
2312 for (auto & scopedstr : stra)
2313 {
2314
2315 if (!contains(scopedstr))
2316 {
2317
2318 return false;
2319
2320 }
2321
2322 }
2323
2324 return true;
2325
2326}
2327
2328
2329
2330
2331template < typename ITERATOR_TYPE >
2332template < prototype_array A_STRING_ARRAY >
2333bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_at_least_one_of(const A_STRING_ARRAY & stra) const
2334{
2335
2336 for (auto & scopedstr : stra)
2337 {
2338
2339 if (case_insensitive_contains(scopedstr))
2340 {
2341
2342 return true;
2343
2344 }
2345
2346 }
2347
2348 return false;
2349
2350}
2351
2352
2353template < typename ITERATOR_TYPE >
2354template < prototype_array A_STRING_ARRAY >
2355bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_all(const A_STRING_ARRAY & stra) const
2356{
2357
2358 for (auto & scopedstr : stra)
2359 {
2360
2361 if (!case_insensitive_contains(scopedstr))
2362 {
2363
2364 return false;
2365
2366 }
2367
2368 }
2369
2370 return true;
2371
2372}
2373
2374
2375template < typename ITERATOR_TYPE >
2376template < prototype_array A_STRING_ARRAY >
2377bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_at_least_one_of(const A_STRING_ARRAY & stra) const
2378{
2379
2380 for (auto & scopedstr : stra)
2381 {
2382
2383 if (unicode_case_insensitive_contains(scopedstr))
2384 {
2385
2386 return true;
2387
2388 }
2389
2390 }
2391
2392 return false;
2393
2394}
2395
2396
2397template < typename ITERATOR_TYPE >
2398template < prototype_array A_STRING_ARRAY >
2399bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_all(const A_STRING_ARRAY & stra) const
2400{
2401
2402 for (auto & scopedstr : stra)
2403 {
2404
2405 if (!unicode_case_insensitive_contains(scopedstr))
2406 {
2407
2408 return false;
2409
2410 }
2411
2412 }
2413
2414 return true;
2415
2416}
2417
2418
2419
2420template < typename ITERATOR_TYPE >
2421string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::Tokenize(const SCOPED_STRING & scopedstrTokens, character_count & start) const
2422{
2423 ASSERT(start >= 0);
2424
2425 if (start < 0)
2426 throw_exception(error_bad_argument);
2427
2428 if (scopedstrTokens.is_empty())
2429 {
2430 if (start < size())
2431 {
2432 return(string_base < ITERATOR_TYPE >(this->begin() + start));
2433 }
2434 }
2435 else
2436 {
2437 const CHARACTER * pszPlace = this->begin() + start;
2438 const CHARACTER * pszEnd = this->begin() + size();
2439 if (scopedstrPlace < pszEnd)
2440 {
2441 character_count nIncluding = string_skip_any_character_in(scopedstrPlace,
2442 scopedstrTokens);
2443
2444 if ((scopedstrPlace + nIncluding) < pszEnd)
2445 {
2446 pszPlace += nIncluding;
2447 character_count nExcluding = string_find_first_character_in(scopedstrPlace, scopedstrTokens);
2448
2449 character_count iFrom = start + nIncluding;
2450 character_count nUntil = nExcluding;
2451 start = iFrom + nUntil + 1;
2452
2453 return substr(iFrom, nUntil);
2454 }
2455 }
2456 }
2457
2458 // return is_empty string_base < ITERATOR_TYPE >, done tokenizing
2459 start = -1;
2460
2461 return(string_base < ITERATOR_TYPE >());
2462
2463}
2464
2465
2466
2467
2468template < typename ITERATOR_TYPE >
2469string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::intersection(const SCOPED_STRING & scopedstrFind) const
2470{
2471
2472 string_base < ITERATOR_TYPE > scopedstr;
2473
2474 for (character_count i = 0; i < size(); i++)
2475 {
2476
2477 auto ch = this->operator[](i);
2478
2479 if (scopedstrFind.contains(ch))
2480 {
2481
2482 scopedstr += ch;
2483
2484 }
2485
2486
2487 }
2488
2489 return scopedstr;
2490
2491}
2492
2493
2494template < typename ITERATOR_TYPE >
2495inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::concatenate_with_separator(const SCOPED_STRING & scopedstrSeparator, const SCOPED_STRING & scopedstr)
2496{
2497
2498 if (this->has_character())
2499 {
2500
2501 if (scopedstr.has_character())
2502 {
2503
2504 this->append(scopedstrSeparator + scopedstr);
2505
2506 }
2507
2508 }
2509 else if (scopedstr.has_character())
2510 {
2511
2512 this->assign(scopedstr);
2513
2514 }
2515
2516 return *this;
2517
2518}
2519
2520
2521
2522template < typename ITERATOR_TYPE >
2523inline void string_base < ITERATOR_TYPE >::get_string(CHARACTER * psz) const noexcept
2524{
2525
2526 string_count_copy(scopedstr, this->begin(), length());
2527
2528}
2529
2530
2531
2532//template < typename ITERATOR_TYPE >
2533//inline string_base < ITERATOR_TYPE >::NATURAL_META_DATA * string_base < ITERATOR_TYPE >::create_meta_data(character_count characterCount)
2534//{
2535//
2536// auto sizeStorageInBytes = null_terminated_character_count_to_byte_length(this->begin(), characterCount);
2537//
2538// auto pNew = this->_create_meta_data(sizeStorageInBytes);
2539//
2540// pNew->set_character_count(characterCount);
2541//
2542// return pNew;
2543//
2544//}
2545
2546
2547//template < typename ITERATOR_TYPE >
2548//typename string_base < ITERATOR_TYPE >::CHARACTER * string_base < ITERATOR_TYPE >::create_string(character_count characterCount)
2549//{
2550//
2551// auto pNew = this->create_meta_data(characterCount);
2552//
2553// this->m_begin = pNew->begin();
2554//
2555// this->m_end = this->m_begin + characterCount;
2556//
2557// this->set_string_flag();
2558//
2559// return (CHARACTER *) this->m_begin;
2560//
2561//}
2562
2563
2564//template < typename ITERATOR_TYPE >
2565//void string_base < ITERATOR_TYPE >::fork_string(character_count characterCount, bool bPreserve)
2566//{
2567//
2568// auto pNew = this->fork_meta_data(characterCount, bPreserve);
2569//
2570// this->m_begin = pNew->begin();
2571//
2572// this->m_end = this->m_begin + characterCount;
2573//
2574// this->set_string_flag();
2575//
2576//}
2577
2578
2579template < typename ITERATOR_TYPE >
2580string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::release_buffer(character_count characterCount)
2581{
2582
2583 if (characterCount < 0)
2584 {
2585
2586 characterCount = string_safe_length(this->begin()) + characterCount + 1;
2587
2588 }
2589
2590 this->NATURAL_POINTER::metadata()->set_character_count(characterCount);
2591
2592 this->m_end = this->m_begin + characterCount;
2593
2594 *(CHARACTER *)this->m_end = (CHARACTER) 0;
2595
2596 return *this;
2597
2598}
2599
2600
2601//template < typename ITERATOR_TYPE >
2602//inline character_count string_base < ITERATOR_TYPE >::storage_character_count() const { return this->NATURAL_POINTER::metadata()->storage_character_count(); }
2603
2604
2605template < typename ITERATOR_TYPE >
2606inline memsize string_base < ITERATOR_TYPE >::character_count_in_bytes() const { return this->NATURAL_POINTER::metadata()->character_count_in_bytes(); }
2607
2608
2609template < typename ITERATOR_TYPE >
2610inline memsize string_base < ITERATOR_TYPE >::null_terminated_character_count_in_bytes() const { return this->NATURAL_POINTER::metadata()->character_count_in_bytes() + sizeof(CHARACTER); }
2611
2612
2613template < typename ITERATOR_TYPE >
2614void string_base < ITERATOR_TYPE >::resize(character_count n, CHARACTER c)
2615{
2616
2617 character_count nOldSize = length();
2618
2619 if (n < nOldSize)
2620 {
2621
2622 this->truncate(n);
2623
2624 }
2625 else
2626 {
2627
2628 auto psz = this->get_buffer(n);
2629
2630 flood_characters(scopedstr + nOldSize, c, n - nOldSize);
2631
2632 this->release_buffer(n);
2633
2634 }
2635
2636}
2637
2638
2639
2640
2641
2642template < typename ITERATOR_TYPE >
2643inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::truncate(this_iterator p)
2644{
2645
2646 if(p <= this->begin())
2647 {
2648
2649 empty();
2650
2651 }
2652 else if(p < this->end())
2653 {
2654
2655 auto pmetadata = this->NATURAL_POINTER::metadata();
2656
2657 if (pmetadata->natural_is_shared())
2658 {
2659
2660 *this = (*this)(0, p);
2661
2662 }
2663 else
2664 {
2665
2666 auto characterCount = p - this->begin();
2667
2668 pmetadata->set_character_count(characterCount);
2669
2670 this->m_end = this->m_begin + characterCount;
2671
2672 *(CHARACTER *)this->m_end = (CHARACTER) 0;
2673
2674 }
2675
2676 }
2677
2678 return this->end();
2679
2680}
2681
2682
2683template < typename ITERATOR_TYPE >
2684inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::erase_beginning(this_iterator p)
2685{
2686
2687 //p = minimum_maximum(p, , size());
2688
2689 assign(p, this->m_end - p);
2690
2691 return this->m_begin;
2692
2693}
2694
2695
2696
2697template < typename ITERATOR_TYPE >
2698inline void string_base < ITERATOR_TYPE >::set_at(character_count iChar, CHARACTER ch)
2699{
2700
2701 auto p = this->NATURAL_POINTER::metadata();
2702
2703 if (iChar >= p->character_count())
2704 {
2705
2706 throw ::exception(error_index_out_of_bounds);
2707
2708 }
2709
2710 if (p->natural_is_shared())
2711 {
2712
2713 fork_string(maximum(p->character_count(), iChar + 1), true);
2714
2715 }
2716
2717 ((CHARACTER *)this->m_begin)[iChar] = ch;
2718
2719}
2720
2721template < typename ITERATOR_TYPE >
2722bool const_string_range < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr) const
2723{
2724
2725 return ::is_set(find(scopedstr));
2726
2727}
2728
2729
2730template < typename ITERATOR_TYPE >
2731bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr) const
2732{
2733
2734 return ::is_set(case_insensitive_find(scopedstr));
2735
2736}
2737
2738
2739//template < typename ITERATOR_TYPE >
2740//bool string_base < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2741//{
2742//
2743// auto pFind = find(scopedstr, start, count, ppszEnd);
2744//
2745// if (::is_null(pFind))
2746// {
2747//
2748// return false;
2749//
2750// }
2751//
2752// if (ppszBeg)
2753// {
2754//
2755// *ppszBeg = psz + iFind;
2756//
2757// }
2758//
2759// return true;
2760//
2761//}
2762//
2763//
2764//template < typename ITERATOR_TYPE >
2765//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2766//{
2767//
2768// auto pFind = case_insensitive_find(scopedstr, start, count, ppszEnd);
2769//
2770// if (::is_null(pFind))
2771// {
2772//
2773// return false;
2774//
2775// }
2776//
2777// if (ppszBeg)
2778// {
2779//
2780// *ppszBeg = psz + iFind;
2781//
2782// }
2783//
2784// return true;
2785//
2786//}
2787
2788
2789//template < typename ITERATOR_TYPE >
2790//bool string_base < ITERATOR_TYPE >::contains(CHARACTER ch) const
2791//{
2792//
2793// return find(ch, start, count) >= 0;
2794//
2795//}
2796
2797
2798//template < typename ITERATOR_TYPE >
2799//bool string_base < ITERATOR_TYPE >::contains(::wide_character wch) const
2800//{
2801//
2802// return find_w(unicode_to_utf8(wch), start, count) >= 0;
2803//
2804//}
2805
2806
2807//template < typename ITERATOR_TYPE >
2808//bool string_base < ITERATOR_TYPE >::contains(::i32 i) const // utf8 CHARACTER index
2809//{
2810//
2811// return find_w(unicode_to_utf8(i), start, count) >= 0;
2812//
2813//}
2814
2815
2816//template < typename ITERATOR_TYPE >
2817//bool string_base < ITERATOR_TYPE >::contains(const CHARACTER* psz) const
2818//{
2819//
2820// return find(scopedstr, start, count) >= 0;
2821//
2822//}
2823
2824
2825//template < typename ITERATOR_TYPE >
2826//bool string_base < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr) const
2827//{
2828//
2829// return find(scopedstr, start, count) >= 0;
2830//
2831//}
2832
2833
2834//template < typename ITERATOR_TYPE >
2835//bool string_base < ITERATOR_TYPE >::contains(CHARACTER ch) const
2836//{
2837//
2838// return find(ch, start, count) >= 0;
2839//
2840//}
2841//
2842//
2843//template < typename ITERATOR_TYPE >
2844//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(CHARACTER ch) const
2845//{
2846//
2847// return case_insensitive_find(ch, start, count) >= 0;
2848//
2849//}
2850
2851//template < typename ITERATOR_TYPE >
2852//bool string_base < ITERATOR_TYPE >::contains(CHARACTER ch, const CHARACTER ** ppszBeg) const
2853//{
2854//
2855// auto find = this->find(ch, start, count);
2856//
2857// if (find < 0)
2858// {
2859//
2860// return false;
2861//
2862// }
2863//
2864// if (::is_set(ppszBeg))
2865// {
2866//
2867// *ppszBeg = this->begin() + find;
2868//
2869// }
2870//
2871// return true;
2872//
2873//}
2874
2875
2876//template < typename ITERATOR_TYPE >
2877//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(CHARACTER ch, const CHARACTER ** ppszBeg) const
2878//{
2879//
2880// auto find = case_insensitive_find(ch, start, count);
2881//
2882// if (find < 0)
2883// {
2884//
2885// return false;
2886//
2887// }
2888//
2889// if (::is_set(ppszBeg))
2890// {
2891//
2892// *ppszBeg = this->begin() + find;
2893//
2894// }
2895//
2896// return true;
2897//
2898//}
2899//
2900//
2901//
2902//template < typename ITERATOR_TYPE >
2903//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(::wide_character wch) const
2904//{
2905//
2906// return unicode_case_insensitive_find(unicode_to_utf8(wch), start, count) >= 0;
2907//
2908//}
2909
2910
2911//template < typename ITERATOR_TYPE >
2912//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(::i32 i) const// utf8 CHARACTER index
2913//{
2914//
2915// return unicode_case_insensitive_find(unicode_to_utf8(i), start, count) >= 0;
2916//
2917//}
2918
2919//
2920//template < typename ITERATOR_TYPE >
2921//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const CHARACTER* psz) const
2922//{
2923//
2924// return case_insensitive_find(scopedstr, start, count) >= 0;
2925//
2926//}
2927
2928
2929//template < typename ITERATOR_TYPE >
2930//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr) const
2931//{
2932//
2933// return case_insensitive_find(scopedstr, start, count) >= 0;
2934//
2935//}
2936
2937
2938template < typename ITERATOR_TYPE >
2939bool const_string_range < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2940{
2941
2942 auto pFind = this->find(scopedstr);
2943
2944 if (::is_null(pFind))
2945 {
2946
2947 return false;
2948
2949 }
2950
2951 if (::is_set(ppszBeg))
2952 {
2953
2954 *ppszBeg = pFind;
2955
2956 }
2957
2958 if (::is_set(ppszEnd))
2959 {
2960
2961 *ppszEnd = pFind + scopedstr.size();
2962
2963 }
2964
2965 return true;
2966
2967}
2968
2969
2970template < typename ITERATOR_TYPE >
2971bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2972{
2973
2974 auto pFind = this->case_insensitive_find(scopedstr);
2975
2976 if (::is_null(pFind))
2977 {
2978
2979 return false;
2980
2981 }
2982
2983 if (::is_set(ppszBeg))
2984 {
2985
2986 *ppszBeg = pFind;
2987
2988 }
2989
2990 if (::is_set(ppszEnd))
2991 {
2992
2993 *ppszEnd = pFind + scopedstr.size();
2994
2995 }
2996
2997 return true;
2998
2999}
3000
3001
3002template < typename ITERATOR_TYPE >
3003bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
3004{
3005
3006 auto pFind = this->unicode_case_insensitive_find(scopedstr);
3007
3008 if (::is_null(pFind))
3009 {
3010
3011 return false;
3012
3013 }
3014
3015 if (::is_set(ppszBeg))
3016 {
3017
3018 *ppszBeg = pFind;
3019
3020 }
3021
3022 if (::is_set(ppszEnd))
3023 {
3024
3025 *ppszEnd = pFind + scopedstr.size();
3026
3027 }
3028
3029 return true;
3030
3031}
3032
3033
3034//template < typename ITERATOR_TYPE >
3035//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(CHARACTER ch, const CHARACTER ** ppszBeg) const
3036//{
3037//
3038// auto find = unicode_case_insensitive_find(ch, start, count);
3039//
3040// if (find < 0)
3041// {
3042//
3043// return false;
3044//
3045// }
3046//
3047// if (::is_set(ppszBeg))
3048// {
3049//
3050// *ppszBeg = this->begin() + find;
3051//
3052// }
3053//
3054// return true;
3055//
3056//}
3057
3058//template < typename ITERATOR_TYPE >
3059//bool string_base < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
3060//{
3061//
3062// auto find = this->find(scopedstr, start, count, ppszEnd);
3063//
3064// if (find < 0)
3065// {
3066//
3067// return false;
3068//
3069// }
3070//
3071// if (::is_set(ppszBeg))
3072// {
3073//
3074// *ppszBeg = this->begin() + find;
3075//
3076// }
3077//
3078// return true;
3079//
3080//}
3081
3082
3083//template < typename ITERATOR_TYPE >
3084//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
3085//{
3086//
3087// auto find = case_insensitive_find(scopedstr, start, count, ppszEnd);
3088//
3089// if (find < 0)
3090// {
3091//
3092// return false;
3093//
3094// }
3095//
3096// if (::is_set(ppszBeg))
3097// {
3098//
3099// *ppszBeg = this->begin() + find;
3100//
3101// }
3102//
3103// return true;
3104//
3105//}
3106
3107
3108//template < typename ITERATOR_TYPE >
3109//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
3110//{
3111//
3112// auto find = unicode_case_insensitive_find(scopedstr, start, count, ppszEnd);
3113//
3114// if (find < 0)
3115// {
3116//
3117// return false;
3118//
3119// }
3120//
3121// if (::is_set(ppszBeg))
3122// {
3123//
3124// *ppszBeg = this->begin() + find;
3125//
3126// }
3127//
3128// return true;
3129//
3130//}
3131
3132//template < typename ITERATOR_TYPE >
3133//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(CHARACTER wch) const
3134//{
3135//
3136// return unicode_case_insensitive_find(wch, start, count) >= 0;
3137//
3138//}
3139
3140//
3141//template < typename ITERATOR_TYPE >
3142//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(::i32 i) const// utf8 CHARACTER index
3143//{
3144//
3145// return unicode_case_insensitive_find(unicode_to_utf8(i), start, count) >= 0;
3146//
3147//}
3148
3149
3150template < typename ITERATOR_TYPE >
3151bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr) const
3152{
3153
3154 return ::is_set(unicode_case_insensitive_find(scopedstr));
3155
3156}
3157
3158
3159//template < typename ITERATOR_TYPE >
3160//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr) const
3161//{
3162//
3163// return unicode_case_insensitive_find(scopedstr, start, count) >= 0;
3164//
3165//}
3166
3167
3168//template < typename ITERATOR_TYPE >
3169//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::erase(character_count start, character_count character_count)
3170//{
3171//
3172// if (start < 0)
3173// {
3174//
3175// character_count = 0;
3176//
3177// }
3178//
3179// if (character_count < 0)
3180// {
3181//
3182// character_count = size();
3183//
3184// }
3185//
3186// Delete(start, character_count);
3187//
3188// return *this;
3189//
3190//}
3191
3192
3193template < typename ITERATOR_TYPE >
3194string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::erase(character_count iIndex, character_count count)
3195{
3196
3197 character_count nLength = size();
3198
3199 if (iIndex < 0)
3200 {
3201
3202 iIndex = 0;
3203
3204 }
3205
3206 if (count < 0)
3207 {
3208
3209 count = nLength;
3210
3211 }
3212
3213 if (count + iIndex > nLength)
3214 {
3215
3216 count = nLength - iIndex;
3217
3218 }
3219
3220 if (count < 0)
3221 {
3222
3223 return *this;
3224
3225 }
3226
3227 if (count + iIndex > nLength)
3228 {
3229
3230 count = nLength - iIndex;
3231
3232 }
3233
3234 if (count > 0)
3235 {
3236
3237 character_count nNewLength = nLength - count;
3238
3239 character_count nCopy = nLength - (iIndex + count) + 1;
3240
3241 CHARACTER * pszBuffer = get_buffer();
3242
3243 memory_transfer(scopedstrBuffer + iIndex, pszBuffer + iIndex + count, (size_t)nCopy);
3244
3245 release_buffer(nNewLength);
3246
3247 }
3248
3249 return *this;
3250
3251}
3252
3253
3254template < typename ITERATOR_TYPE >
3255inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i, CHARACTER ch)
3256{
3257
3258 if (i < 0)
3259 {
3260
3261 i = 0;
3262
3263 }
3264
3265 if (i > size())
3266 {
3267
3268 i = size();
3269
3270 }
3271
3272 character_count nNewLength = size() + 1;
3273
3274 CHARACTER * pszBuffer = get_buffer(nNewLength);
3275
3276 memory_transfer(scopedstrBuffer + i + 1, pszBuffer + i, nNewLength - i);
3277
3278 pszBuffer[i] = ch;
3279
3280 release_buffer(nNewLength);
3281
3282 return nNewLength;
3283
3284}
3285
3286
3287template < typename ITERATOR_TYPE >
3288inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i, const string_base & str)
3289{
3290
3291 if (i < 0)
3292 {
3293
3294 i = 0;
3295
3296 }
3297
3298 if (i > size())
3299 {
3300
3301 i = size();
3302
3303 }
3304
3305 character_count nInsertLength = str.size();
3306
3307 character_count nNewLength = size();
3308
3309 if (nInsertLength > 0)
3310 {
3311
3312 nNewLength += nInsertLength;
3313
3314 CHARACTER * pszBuffer = get_buffer(nNewLength);
3315
3316 memory_transfer(scopedstrBuffer + i + nInsertLength, pszBuffer + i, (nNewLength - i - nInsertLength + 1) * sizeof(CHARACTER));
3317
3318 memory_copy(scopedstrBuffer + i, str.begin(), nInsertLength * sizeof(CHARACTER));
3319
3320 release_buffer(nNewLength);
3321
3322 }
3323
3324 return nNewLength;
3325
3326}
3327
3328
3329template < typename ITERATOR_TYPE >
3330inline ::collection::count string_base < ITERATOR_TYPE >::replace_with(CHARACTER charNew, CHARACTER charOld, character_count start)
3331{
3332
3333 character_count count = 0;
3334
3335 // ::i16-circuit the nop case
3336 if (charOld != charNew)
3337 {
3338 // otherwise modify each character that matches in the string_base < ITERATOR_TYPE >
3339 bool bCopied = false;
3340 CHARACTER * pszBuffer = const_cast<CHARACTER *>(this->begin() + start); // We don't actually write to pszBuffer until we've called get_buffer().
3341
3342 character_count nLength = size();
3343 character_count iChar = 0;
3344 while (iChar < nLength)
3345 {
3346 // replace instances of the specified character only
3347 if (scopedstrBuffer[iChar] == charOld)
3348 {
3349 if (!bCopied)
3350 {
3351 bCopied = true;
3352 pszBuffer = get_buffer(nLength);
3353 }
3354 pszBuffer[iChar] = charNew;
3355 count++;
3356 }
3357 iChar = character_count((scopedstrBuffer + iChar + 1) - pszBuffer);
3358 }
3359 if (bCopied)
3360 {
3361 release_buffer(nLength);
3362 }
3363 }
3364
3365 return count;
3366}
3367
3368
3369
3370//template < typename ITERATOR_TYPE >
3371//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::case_insensitive_replace_with(const string_base & scopedstrNew, const string_base & scopedstrOld)
3372//{
3373//
3374// // can't have is_empty or nullptr pszOld
3375// // nSourceLen is in XCHARs
3376// character_count nSourceLen = scopedstrOld.size();
3377//
3378// if (nSourceLen == 0)
3379// {
3380//
3381// return(0);
3382//
3383// }
3384//
3385// // nReplacementLen is in XCHARs
3386// character_count nReplacementLen = scopedstrNew.size();
3387//
3388// // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
3389// character_count count = 0;
3390//
3391// {
3392//
3393// character_count i = start;
3394//
3395// character_count iFind;
3396//
3397// while ((iFind = case_insensitive_find(scopedstrOld, i, -1)) >= 0)
3398// {
3399//
3400// count++;
3401//
3402// i = iFind + nSourceLen;
3403//
3404// }
3405//
3406// }
3407//
3408// // if any changes were made, make them
3409// if (count > 0)
3410// {
3411//
3412// // if the buffer is too small, just
3413// // allocate a ___new buffer(slow but sure)
3414// character_count nOldLength = size();
3415//
3416// character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
3417//
3418// CHARACTER * pszBuffer = get_buffer(maximum(nNewLength, nOldLength));
3419//
3420// character_count i = start;
3421//
3422// character_count nEnd = nNewLength;
3423//
3424// character_count iFind;
3425//
3426// // loop again to actually do the work
3427// while (i < nEnd)
3428// {
3429//
3430// while ((iFind = case_insensitive_find(scopedstrOld, i, -1)) >= 0)
3431// {
3432//
3433// auto pszTarget = pszBuffer + iFind;
3434//
3435// character_count nBalance = nOldLength - character_count(scopedstrTarget - pszBuffer + nSourceLen);
3436//
3437// memory_transfer(scopedstrTarget + nReplacementLen, pszTarget + nSourceLen, nBalance * sizeof(CHARACTER));
3438//
3439// ::memory_copy(scopedstrTarget, scopedstrOld.begin(), nReplacementLen * sizeof(CHARACTER));
3440//
3441// i += nReplacementLen;
3442//
3443// pszTarget[nReplacementLen + nBalance] = 0;
3444//
3445// nOldLength += (nReplacementLen - nSourceLen);
3446//
3447// }
3448//
3449// i += string_safe_length(scopedstrBuffer + 1) + 1;
3450//
3451// }
3452//
3453// ASSERT(scopedstrBuffer[nNewLength] == 0);
3454//
3455// release_buffer(nNewLength);
3456//
3457// }
3458//
3459// return count;
3460//
3461//}
3462
3463
3464template < typename ITERATOR_TYPE >
3465//template < raw_pointer_castable < CHARACTER > PCHARNEW, raw_pointer_castable < CHARACTER > PCHAROLD >
3466::collection::count string_base < ITERATOR_TYPE >::replace_with_count(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start)
3467{
3468 // can't have is_empty or nullptr pszOld
3469
3470
3471 ::collection::count c = 0;
3472
3473 // nSourceLen is in XCHARs
3474 character_count nSourceLen = scopedstrOld.size();
3475 if (nSourceLen == 0)
3476 return(0);
3477 // nReplacementLen is in XCHARs
3478 character_count nReplacementLen = scopedstrNew.size();
3479
3480 // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
3481 character_count count = 0;
3482
3483 {
3484
3485 const CHARACTER * pszStart = this->begin() + start;
3486 // const CHARACTER * pszEnd = pszStart+size();
3487 const CHARACTER * pszTarget;
3488
3489 while ((scopedstrTarget = string_find_string(pszStart, scopedstrOld)) != nullptr)
3490 {
3491
3492 count++;
3493
3494 pszStart = pszTarget + nSourceLen;
3495
3496 c++;
3497
3498 }
3499
3500 }
3501
3502 // if any changes were made, make them
3503 if (count > 0)
3504 {
3505 // if the buffer is too small, just
3506 // allocate a ___new buffer(slow but sure)
3507 character_count nOldLength = size();
3508 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
3509
3510 CHARACTER * pszBuffer = get_buffer(maximum(nNewLength, nOldLength));
3511
3512 const CHARACTER * pszStart = pszBuffer + start;
3513 const CHARACTER * pszEnd = pszBuffer + nOldLength;
3514
3515 // loop again to actually do the work
3516 while (pszStart < pszEnd)
3517 {
3518
3519 CHARACTER * pszTarget;
3520
3521 while ((scopedstrTarget = (CHARACTER *)string_find_string(pszStart, scopedstrOld)) != nullptr)
3522 {
3523
3524 character_count nBalance = nOldLength - character_count(scopedstrTarget - pszBuffer + nSourceLen);
3525
3526 memory_transfer((void *)(scopedstrTarget + nReplacementLen), pszTarget + nSourceLen, nBalance * sizeof(CHARACTER));
3527
3528 ::memory_copy((void *)pszTarget, scopedstrNew, nReplacementLen * sizeof(CHARACTER));
3529
3530 pszStart = pszTarget + nReplacementLen;
3531
3532 pszTarget[nReplacementLen + nBalance] = 0;
3533
3534 nOldLength += (nReplacementLen - nSourceLen);
3535
3536 }
3537
3538 pszStart += string_safe_length(pszStart) + 1;
3539
3540 }
3541
3542 ASSERT(scopedstrBuffer[nNewLength] == 0);
3543
3544 release_buffer(nNewLength);
3545
3546 }
3547
3548 return c;
3549
3550}
3551
3552
3553template < typename ITERATOR_TYPE >
3554//template < raw_pointer_castable < CHARACTER > PCHARNEW, raw_pointer_castable < CHARACTER > PCHAROLD >
3555::collection::count string_base < ITERATOR_TYPE >::replace_with_ci_count(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start)
3556{
3557 // can't have is_empty or nullptr pszOld
3558
3559
3560 ::collection::count c = 0;
3561
3562 // nSourceLen is in XCHARs
3563 character_count nSourceLen = scopedstrOld.size();
3564 if (nSourceLen == 0)
3565 return(0);
3566 // nReplacementLen is in XCHARs
3567 character_count nReplacementLen = scopedstrOld.size();
3568
3569 // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
3570 character_count count = 0;
3571 {
3572 const CHARACTER * pszStart = this->begin() + start;
3573 // const CHARACTER * pszEnd = pszStart+size();
3574 const CHARACTER * pszTarget;
3575 while ((scopedstrTarget = case_insensitive_string_find_string(pszStart, scopedstrOld)) != nullptr)
3576 {
3577 count++;
3578 pszStart = pszTarget + nSourceLen;
3579 c++;
3580 }
3581 }
3582
3583 // if any changes were made, make them
3584 if (count > 0)
3585 {
3586 // if the buffer is too small, just
3587 // allocate a ___new buffer(slow but sure)
3588 character_count nOldLength = size();
3589 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
3590
3591 CHARACTER * pszBuffer = get_buffer(maximum(nNewLength, nOldLength));
3592
3593 CHARACTER * pszStart = pszBuffer + start;
3594 CHARACTER * pszEnd = pszBuffer + nOldLength;
3595
3596 // loop again to actually do the work
3597 while (pszStart < pszEnd)
3598 {
3599
3600 CHARACTER * pszTarget;
3601
3602 while ((scopedstrTarget = (CHARACTER *)case_insensitive_string_find_string(pszStart, scopedstrOld)) != nullptr)
3603 {
3604
3605 character_count nBalance = nOldLength - character_count(scopedstrTarget - pszBuffer + nSourceLen);
3606
3607 memory_transfer(scopedstrTarget + nReplacementLen, pszTarget + nSourceLen, nBalance * sizeof(CHARACTER));
3608
3609 ::memory_copy(scopedstrTarget, scopedstrNew, nReplacementLen * sizeof(CHARACTER));
3610
3611 pszStart = pszTarget + nReplacementLen;
3612
3613 pszTarget[nReplacementLen + nBalance] = 0;
3614
3615 nOldLength += (nReplacementLen - nSourceLen);
3616
3617 }
3618
3619 pszStart += string_safe_length(pszStart) + 1;
3620
3621 }
3622
3623 ASSERT(scopedstrBuffer[nNewLength] == 0);
3624
3625 release_buffer(nNewLength);
3626
3627 }
3628
3629 return c;
3630
3631}
3632
3633
3634//template < typename ITERATOR_TYPE >
3635//string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::replace(character_count start, character_count count, const SCOPED_STRING & scopedstr)
3636//{
3637//
3638// if (count < 0)
3639// {
3640//
3641// auto len = start + scopedstr.size();
3642//
3643// auto psz = get_buffer(len);
3644//
3645// string_count_copy(scopedstr + start, scopedstr.begin(), scopedstr.size());
3646//
3647// release_buffer(len);
3648//
3649// return *this;
3650//
3651// }
3652// else
3653// {
3654//
3655// auto len = start + scopedstr.size() + (size() - (start + count));
3656//
3657// auto psz = get_buffer(len);
3658//
3659// auto lenAfter1 = len - (start + scopedstr.size());
3660//
3661// auto lenAfter2 = len - (start + count);
3662//
3663// auto lenAfter = minimum(lenAfter1, lenAfter2);
3664//
3665// overlapped_string_count_copy(scopedstr + start + scopedstr.size(), psz + start + count, lenAfter);
3666//
3667// string_count_copy(scopedstr + start, scopedstr.begin(), scopedstr.size());
3668//
3669// release_buffer(len);
3670//
3671// return *this;
3672//
3673// }
3674//
3675//}
3676
3677
3678template < typename ITERATOR_TYPE >
3679string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::replace(const_iterator start, const_iterator end, const SCOPED_STRING & scopedstr)
3680{
3681
3682 auto finalLen = this->size() + scopedstr.size() - (end - start);
3683
3684 string str;
3685
3686 auto psz = str.get_buffer(finalLen);
3687
3688 memory_copy(scopedstr, this->begin(), start - this->begin());
3689
3690 memory_copy(scopedstr + (start - this->begin()), scopedstr.begin(), scopedstr.size());
3691
3692 memory_copy(scopedstr + (start - this->begin()) + scopedstr.size(), end, this->end() - end);
3693
3694 str.release_buffer(finalLen);
3695
3696 *this = ::transfer(str);
3697
3698 return *this;
3699
3700}
3701
3702
3703template < typename ITERATOR_TYPE >
3704inline ::collection::count string_base < ITERATOR_TYPE >::erase_character(CHARACTER chRemove)
3705{
3706
3707 character_count nLength = size();
3708
3709 CHARACTER * pszBuffer = get_buffer(nLength);
3710
3711 CHARACTER * pszSource = pszBuffer;
3712
3713 CHARACTER * pszDest = pszBuffer;
3714
3715 CHARACTER * pszEnd = pszBuffer + nLength;
3716
3717 while (scopedstrSource < pszEnd)
3718 {
3719 CHARACTER * pszNewSource = pszSource + 1;
3720 if (*pszSource != chRemove)
3721 {
3722 // copy the source to the destination. Remember to copy all bytes of an MBCS character
3723 // copy the source to the destination. Remember to copy all bytes of an MBCS character
3724 size_t NewSourceGap = (scopedstrNewSource - pszSource);
3725 CHARACTER * pszNewDest = pszDest + NewSourceGap;
3726 size_t i = 0;
3727 for (i = 0; pszDest != pszNewDest && i < NewSourceGap; i++)
3728 {
3729 *pszDest = *pszSource;
3730 pszSource++;
3731 pszDest++;
3732 }
3733 }
3734 pszSource = pszNewSource;
3735 }
3736 *pszDest = 0;
3737 character_count count = character_count(scopedstrSource - pszDest);
3738 release_buffer(nLength - count);
3739
3740 return(count);
3741
3742}
3743
3744// find the first occurrence of character 'ch', starting at character_count 'start'
3745template < typename ITERATOR_TYPE >
3746inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::find(CHARACTER ch) const RELEASENOTHROW
3747{
3748
3749 return this->find_first(ch);
3750
3751}
3752
3753
3754
3755//template < typename ITERATOR_TYPE >
3756//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find(CHARACTER ch) const RELEASENOTHROW
3757//{
3758//
3759// auto psz = string_find_character(this->begin() + start, ch);
3760//
3761// if (!psz)
3762// {
3763//
3764// return -1;
3765//
3766// }
3767//
3768// return psz - this->begin();
3769//
3770//}
3771
3772// find routines
3773
3775//template < typename ITERATOR_TYPE >
3776//inline string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find(CHARACTER ch) const RELEASENOTHROW
3777//{
3778// // start is in XCHARs
3779// ASSERT(start >= 0);
3780//
3781// // nLength is in XCHARs
3782// character_count nLength = size();
3783// if (start < 0 || start >= nLength)
3784// {
3785// return -1;
3786// }
3787//
3788// if (count < 0)
3789// count = nLength;
3790//
3791// if (count + start > nLength)
3792// count = nLength - start;
3793//
3794// if (count < 0)
3795// return -1;
3796//
3797// auto psz = this->begin() + start;
3798//
3799// for (::i32 i = 0; i < count; i++)
3800// {
3801//
3802// if (scopedstr[i] == ch)
3803// {
3804//
3805// return start + i;
3806//
3807// }
3808//
3809// }
3810//
3811// return -1;
3812//
3813//}
3814
3815// find the first occurrence of character 'ch', starting at character_count 'start'
3816template < typename ITERATOR_TYPE >
3817inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::case_insensitive_find(CHARACTER ch) const RELEASENOTHROW
3818{
3819 // start is in XCHARs
3820 //ASSERT(start >= 0);
3821
3822 // nLength is in XCHARs
3823 //character_count nLength = this->size();
3824// if (start < 0 || start >= nLength)
3825// {
3826// return(-1);
3827// }
3828
3829//if(nLength <= 0)
3830//{
3831//
3832// return -1;
3833//
3834//}
3835//
3836// if (count < 0)
3837// count = nLength;
3838//
3839// if (count + start > nLength)
3840// count = nLength - start;
3841//
3842// if (count < 0)
3843// return -1;
3844
3845 auto psz = this->begin();
3846
3847 while(scopedstr < this->end())
3848 {
3849
3850 if (character_tolower(*psz) == character_tolower(ch))
3851 {
3852
3853 return psz;
3854
3855 }
3856
3857 psz++;
3858
3859 }
3860
3861 return nullptr;
3862
3863}
3864
3865
3866//template < typename ITERATOR_TYPE >
3867//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::skip_whitespace() const RELEASENOTHROW
3868//{
3869//
3870// return skip_any_character_in("\t\n\r ");
3871//
3872//}
3873//
3874//
3875//template < typename ITERATOR_TYPE >
3876//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_whitespace() const RELEASENOTHROW
3877//{
3878//
3879// return find_first_character_in("\t\n\r ");
3880//
3881//}
3882
3883
3884template < typename ITERATOR_TYPE >
3885inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::find_first(CHARACTER ch, ::character_count start) const RELEASENOTHROW
3886{
3887
3888 return ::string_find_character(this->begin() + start, this->end(), ch);
3889
3890}
3891
3892
3893
3894// iconic prime good doxygen comment
3895
3896
3897
3912//template < typename ITERATOR_TYPE >
3913//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
3914//{
3915//
3916// return this->find(scopedstr, ::comparison::comparison < CHARACTER >());
3917//
3918//
3919// //character_count scopedstrLen;
3920//
3921// //character_count nEndExclusive;
3922//
3923// //character_count i;
3924//
3925// //if (_find_prefix(i, scopedstr, start, count, scopedstrLen, nEndExclusive))
3926// //{
3927//
3928// // return i;
3929//
3930// //}
3931//
3932// //auto psz = this->begin();
3933//
3934// //auto pszBlock = scopedstr.begin();
3935//
3936// //for (; i < nEndExclusive; i++)
3937// //{
3938//
3939// // bool bFound = true;
3940//
3941// // auto j = i;
3942//
3943// // for (; j < scopedstrLen; j++)
3944// // {
3945//
3946// // if (scopedstr[j] != pszBlock[j])
3947// // {
3948//
3949// // bFound = false;
3950//
3951// // break;
3952//
3953// // }
3954//
3955// // }
3956//
3957// // if (bFound)
3958// // {
3959//
3960// // if (::is_set(ppszTail))
3961// // {
3962//
3963// // *ppszTail = psz + j;
3964//
3965// // }
3966//
3967// // return i;
3968//
3969// // }
3970//
3971// // psz++;
3972//
3973// //}
3974//
3975// //return -1;
3976//
3977//}
3978
3979
3982//template < typename ITERATOR_TYPE >
3983//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::case_insensitive_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
3984//{
3985//
3986// return this->find(scopedstr, ::comparison::case_insensitive < CHARACTER >());
3987//
3988// //character_count scopedstrLen;
3989//
3990// //character_count nEndExclusive;
3991//
3992// //character_count i;
3993//
3994// //if (_find_prefix(i, scopedstr, start, count, scopedstrLen, nEndExclusive))
3995// //{
3996//
3997// // return i;
3998//
3999// //}
4000//
4001// //auto psz = this->begin();
4002//
4003// //auto pszBlock = scopedstr.begin();
4004//
4005// //for (; i < nEndExclusive; i++)
4006// //{
4007//
4008// // bool bFound = true;
4009//
4010// // auto j = i;
4011//
4012// // for (; j < scopedstrLen; j++)
4013// // {
4014//
4015// // if (character_tolower(scopedstr[j]) != character_tolower(scopedstrBlock[j]))
4016// // {
4017//
4018// // bFound = false;
4019//
4020// // break;
4021//
4022// // }
4023//
4024// // }
4025//
4026// // if (bFound)
4027// // {
4028//
4029// // if (::is_set(ppszTail))
4030// // {
4031//
4032// // *ppszTail = psz + j;
4033//
4034// // }
4035//
4036// // return i;
4037//
4038// // }
4039//
4040// // psz++;
4041//
4042// //}
4043//
4044// //return -1;
4045//
4046//}
4047
4048
4049// find the first occurrence of string_base < ITERATOR_TYPE > 'scopedstr', starting at character_count 'start'
4050template < typename ITERATOR_TYPE >
4051inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4052{
4053
4054 const_iterator p;
4055
4056 auto rangeScope = *this;
4057
4058 if (this->_initialize_find(p, scopedstr, rangeScope))
4059 {
4060
4061 return p;
4062
4063 }
4064
4065 auto psz = (const CHARACTER * ) p;
4066
4067 auto pszBlock = (const CHARACTER * ) scopedstr.begin();
4068
4069 auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
4070
4071 for (; psz < rangeScope.m_end; psz++)
4072 {
4073
4074 auto psz2 = psz;
4075
4076 auto pszBlock2 = pszBlock;
4077
4078 ::i32 len1;
4079
4080 ::i32 len2;
4081
4082 do
4083 {
4084
4085 if (unicode_index_length(scopedstr2, len1) != unicode_index_length(scopedstrBlock2, len2))
4086 {
4087
4088 break;
4089
4090 }
4091
4092 psz2 += len1;
4093
4094 pszBlock2 += len2;
4095
4096 }
4097 while (scopedstrBlock2 < pszBlockEnd);
4098
4099 if (scopedstrBlock2 >= pszBlockEnd)
4100 {
4101
4102 //if (ppszTail)
4103 //{
4104
4105 // *ppszTail = pszBlock2;
4106
4107 //}
4108
4109 return psz;
4110
4111 }
4112
4113 ::unicode_increment(psz);
4114
4115 }
4116
4117 return nullptr;
4118
4119}
4120
4121
4122// find the first occurrence of string_base < ITERATOR_TYPE > 'scopedstr', starting at character_count 'start'
4123template < typename ITERATOR_TYPE >
4124inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4125{
4126
4127 const_iterator p;
4128
4129 auto rangeScope = *this;
4130
4131 if (this->_initialize_find(p, scopedstr, rangeScope))
4132 {
4133
4134 return p;
4135
4136 }
4137
4138 auto psz = (const CHARACTER *)p;
4139
4140// auto pszBlock = (const CHARACTER *)scopedstr.begin();
4141//
4142// auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
4143
4144 for (; psz < rangeScope.m_end; psz++)
4145 {
4146
4147 bool bFound = true;
4148
4149 const CHARACTER * psz2 = psz;
4150
4151 const CHARACTER * pszSub2 = scopedstr;
4152
4153 ::i32 len1;
4154
4155 ::i32 len2;
4156
4157 while (*psz2 != '\0' && *pszSub2 != '\0')
4158 {
4159
4160 if (unicode_to_lower_case(unicode_index_length(scopedstr2, len1)) !=
4161 unicode_to_lower_case(unicode_index_length(scopedstrSub2, len2)))
4162 {
4163
4164 bFound = false;
4165
4166 break;
4167
4168 }
4169
4170 psz2 += len1;
4171
4172 psz2 += len2;
4173
4174 }
4175
4176 if (bFound)
4177 {
4178
4179 if (*pszSub2 == '\0')
4180 {
4181
4182 /* if (ppszTail)
4183 {
4184
4185 *ppszTail = psz2;
4186
4187 }*/
4188
4189 return psz;
4190
4191 }
4192 else
4193 {
4194
4195 return nullptr;
4196
4197 }
4198
4199 }
4200
4201 //psz++;
4202
4203 }
4204
4205 return nullptr;
4206
4207}
4208
4209
4210//template < typename ITERATOR_TYPE >
4211//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4212//{
4213//
4214// return rear_find(scopedstr, ::comparison::comparison < CHARACTER >());
4215//
4216//}
4217
4218
4219template < typename ITERATOR_TYPE >
4220inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4221{
4222
4223 auto psz = (const CHARACTER *)this->begin();
4224
4225 auto pszEnd = (const CHARACTER *)this->end();
4226
4227 unicode_decrement(pszEnd, psz);
4228
4229 auto pszBlock = (const CHARACTER *)scopedstr.begin();
4230
4231 auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
4232
4233 unicode_decrement(scopedstrBlockEnd, pszBlock);
4234
4235 if (::is_null(scopedstrBlockEnd))
4236 {
4237
4238 return pszEnd;
4239
4240 }
4241
4242 while(::is_set(pszEnd))
4243 {
4244
4245 //bool bFound = true;
4246
4247 const CHARACTER * pszSub2 = pszBlockEnd;
4248
4249 const CHARACTER * psz2 = pszEnd;
4250
4251 while (true)
4252 {
4253
4254 if (unicode_index(scopedstrBlockEnd) != unicode_index(scopedstr2))
4255 {
4256
4257 break;
4258
4259 }
4260
4261 pszSub2 = (const CHARACTER *)unicode_decrement(scopedstrSub2, pszBlock);
4262
4263 if (::is_null(scopedstrSub2))
4264 {
4265
4266 // End of searching block parsing reached.
4267 // Every unicode character so far is identical.
4268 // Found matching string.
4269
4270 return psz;
4271
4272 }
4273
4274 psz2 = (const CHARACTER *)unicode_decrement(scopedstr2, psz);
4275
4276 if (is_null(scopedstr2))
4277 {
4278
4279 // Premature end of searched string
4280 // Didn't find matching block.
4281 // Return nullptr (not found).
4282
4283 return nullptr;
4284
4285 }
4286
4287 }
4288
4289 pszEnd = (const CHARACTER *)unicode_decrement(pszEnd, psz);
4290
4291 }
4292
4293 // End of searched string
4294 // Didn't find matching block.
4295 // Return nullptr (not found).
4296
4297 return nullptr;
4298
4299}
4300
4301
4302template < typename ITERATOR_TYPE >
4303inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4304{
4305
4306 auto psz = (const CHARACTER *)this->begin();
4307
4308 auto pszEnd = (const CHARACTER *)this->end();
4309
4310 unicode_decrement(pszEnd, psz);
4311
4312 auto pszBlock = (const CHARACTER *)scopedstr.begin();
4313
4314 auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
4315
4316 unicode_decrement(scopedstrBlockEnd, pszBlock);
4317
4318 if (::is_null(scopedstrBlockEnd))
4319 {
4320
4321 return pszEnd;
4322
4323 }
4324
4325 while (::is_set(pszEnd))
4326 {
4327
4328 //bool bFound = true;
4329
4330 const CHARACTER * pszSub2 = pszBlockEnd;
4331
4332 const CHARACTER * psz2 = pszEnd;
4333
4334 while (true)
4335 {
4336
4337 if (unicode_to_lower_case(unicode_index(scopedstrBlockEnd)) != unicode_to_lower_case(unicode_index(scopedstr2)))
4338 {
4339
4340 break;
4341
4342 }
4343
4344 pszSub2 = (const CHARACTER *)unicode_decrement(scopedstrSub2, pszBlock);
4345
4346 if (::is_null(scopedstrSub2))
4347 {
4348
4349 // End of searching block parsing reached.
4350 // Every unicode character so far is case-insensitive equivalent.
4351 // Found matching string.
4352
4353 return psz;
4354
4355 }
4356
4357 psz2 = (const CHARACTER *)unicode_decrement(scopedstr2, psz);
4358
4359 if (is_null(scopedstr2))
4360 {
4361
4362 // Premature end of searched string
4363 // Didn't find matching block.
4364 // Return nullptr (not found).
4365
4366 return nullptr;
4367
4368 }
4369
4370 }
4371
4372 pszEnd = (const CHARACTER *)unicode_decrement(pszEnd, psz);
4373
4374 }
4375
4376 // End of searched string
4377 // Didn't find matching block.
4378 // Return nullptr (not found).
4379
4380 return nullptr;
4381
4382}
4383
4384
4385
4387//template < typename ITERATOR_TYPE >
4388//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW
4389//{
4390//
4391// auto p = string_find_first_character_in({ this->begin() + start, size() - start }, scopedstrCharacters);
4392//
4393// return ::is_set(p) ? offset_of(p) : -1;
4394//
4395//}
4396
4397
4398
4400//template < typename ITERATOR_TYPE >
4401//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_character_in(const CHARACTER * pszCharacters) const RELEASENOTHROW
4402//{
4403//
4404// auto p = string_pbrk(this->begin() + start, pszCharacters);
4405//
4406// return ::is_set(p) ? offset_of(p) : -1;
4407//
4408//}
4409
4410
4411//template < typename ITERATOR_TYPE >
4412//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW
4413//{
4414//
4415// return find_first_character_in(scopedstrCharacters, start);
4416//
4417//}
4418//
4419//
4420//template < typename ITERATOR_TYPE >
4421//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW
4422//{
4423//
4424// return find_first_character_in(scopedstrCharacters, start, n);
4425//
4426//}
4427//
4428//
4429//template < typename ITERATOR_TYPE >
4430//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_character_in(const CHARACTER * pszCharacters) const RELEASENOTHROW
4431//{
4432//
4433// return find_one_of(scopedstrCharacters, pos);
4434//
4435//}
4436//
4437//
4445
4446
4447//template < typename ITERATOR_TYPE >
4448//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::find_first_of(CHARACTER ch, character_count count) const RELEASENOTHROW
4449//{
4450//
4451// return ::string_find_character(this->begin() + pos, ch, count);
4452//
4453//}
4454
4455
4456//template < typename ITERATOR_TYPE >
4457//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::span(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4458//{
4459//
4460// return find_first_not_of(scopedstr, pos, size());
4461//
4462//}
4463//
4464//
4465//template < typename ITERATOR_TYPE >
4466//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::span(const CHARACTER * psz) const
4467//RELEASENOTHROW
4468//{
4469//
4470// return ::string_find_first_not_of(, pos);
4471//
4472//}
4473//
4474//
4475//template < typename ITERATOR_TYPE >
4476//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::span(CHARACTER ca) const
4477//RELEASENOTHROW
4478//{
4479// character_count nLength = size();
4480//
4481// if (pos < 0 || pos >= nLength)
4482// return -1;
4483// const SCOPED_STRING & scopedstr = &this->begin()[pos];
4484// while (*psz != '\0' && *psz == ca)
4485// {
4486// psz++;
4487// }
4488// if (*psz == '\0')
4489// return -1;
4490// else
4491// return psz - this->begin();
4492//}
4493//
4494//template < typename ITERATOR_TYPE >
4495//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::span(const SCOPED_STRING & scopedstr) const
4496//RELEASENOTHROW
4497//{
4498// string_base < ITERATOR_TYPE > strChars(s, n);
4499//
4500// character_count nLength = size();
4501//
4502// if (pos < 0 || pos >= nLength)
4503// return -1;
4504// const SCOPED_STRING & scopedstr = &this->begin()[pos];
4505// while (*psz != '\0' && strChars.contains(*psz))
4506// {
4507// psz++;
4508// }
4509// if (*psz == '\0')
4510// return -1;
4511// else
4512// return psz - this->begin();
4513//}
4514
4515
4517//template < typename ITERATOR_TYPE >
4518//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_skip(CHARACTER ch) const RELEASENOTHROW
4519//{
4520//
4521// return BASE_RANGE::rear_skip_start(ch);
4522//
4523// //character_count nLength = size();
4524// //// nLength is in XCHARs
4525// //if (pos < 0)
4526// // pos = nLength - 1;
4527// //if (pos < 0 || pos >= nLength)
4528// //{
4529// // return(-1);
4530// //}
4531// //auto psz = this->begin();
4532// //while (pos >= 0 && psz[pos] != ca)
4533// //{
4534// // pos--;
4535// //}
4536// //return pos;
4537//}
4538
4539//template < typename ITERATOR_TYPE >
4540//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find_first_character_in(const CHARACTER * pszCharSet) const RELEASENOTHROW
4541//{
4542// return find_last_of(scopedstrCharSet, start, -1);
4543//}
4544//
4545//template < typename ITERATOR_TYPE >
4546//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find_first_character_in(const CHARACTER * pszCharSet) const RELEASENOTHROW
4547//{
4548// character_count nLength = size();
4549// // nLength is in XCHARs
4550// if (pos < 0)
4551// pos = nLength - 1;
4552// if (pos < 0 || pos >= nLength)
4553// {
4554// return(-1);
4555// }
4556// string_base < ITERATOR_TYPE > strChars(scopedstrCharSet, n);
4557// auto psz = this->begin();
4558// while (pos >= 0 && !strChars.contains(scopedstr[pos]))
4559// {
4560// pos--;
4561// }
4562// return pos;
4563//}
4564//
4565//template < typename ITERATOR_TYPE >
4566//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find_first_character_in(const SCOPED_STRING & scopedstr strCharSet) const RELEASENOTHROW
4567//{
4568// return find_last_of(strCharSet, pos, strCharSet.size());
4569//}
4570//
4571//
4573//template < typename ITERATOR_TYPE >
4574//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_skip(CHARACTER ch) const RELEASENOTHROW
4575//{
4576//
4577// return offset_of(BASE_RANGE::rear_skip_start_count(ch, start, count));
4578//
4579//}
4580// character_count nLength = size();
4581// // nLength is in XCHARs
4582// if (pos < 0)
4583// pos = nLength - 1;
4584// if (pos < 0 || pos >= nLength)
4585// {
4586// return(-1);
4587// }
4588// auto psz = this->begin();
4589// while (pos >= 0 && psz[pos] == ca)
4590// {
4591// pos--;
4592// }
4593// return pos;
4594//}
4595//
4596//template < typename ITERATOR_TYPE >
4597//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_skip_any_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW
4598//{
4599// return BASE_RANGE::rear_skip_any_character_in_start(scopedstrCharacters);
4600//}
4601//template < typename ITERATOR_TYPE >
4602//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_skip_any_character_in(const SCOPED_STRING & scopedstrCharacters) const RELEASENOTHROW
4603//{
4604// return offset_of(BASE_RANGE::rear_skip_any_character_in_start_count(scopedstrCharacters, start, count));
4605//}
4606//
4607//template < typename ITERATOR_TYPE >
4608//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_skip_any_character_in(const CHARACTER * pszCharSet) const RELEASENOTHROW
4609//{
4610// character_count nLength = size();
4611// // nLength is in XCHARs
4612// if (pos < 0)
4613// pos = nLength - 1;
4614// if (pos < 0 || pos >= nLength)
4615// {
4616// return(-1);
4617// }
4618// string_base < ITERATOR_TYPE > strChars(scopedstrCharSet, n);
4619// auto psz = this->begin();
4620// while (pos >= 0 && strChars.contains(scopedstr[pos]))
4621// {
4622// pos--;
4623// }
4624// return pos;
4625//}
4626//
4627//template < typename ITERATOR_TYPE >
4628//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_skip_any_character_in(const SCOPED_STRING & scopedstr strCharSet) const RELEASENOTHROW
4629//{
4630// return find_last_not_of(strCharSet, pos, strCharSet.size());
4631//}
4632
4633
4635//template < typename ITERATOR_TYPE >
4636//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find(CHARACTER ch, character_count count) const RELEASENOTHROW
4637//{
4638// // find last single character
4639// auto psz = string_rear_find_character({ this->begin(), size() + count + 1}, ch);
4640//
4641// // return -1 if not found, distance from beginning otherwise
4642// return ::is_set(scopedstr) ? character_count(scopedstr - this->begin()) : -1;
4643//
4644//}
4645//
4646
4647template < typename ITERATOR_TYPE >
4648typename const_string_range < ITERATOR_TYPE >::CHARACTER const_string_range < ITERATOR_TYPE >::last_char(character_count count) const
4649{
4650
4651 return *(this->end() + count);
4652}
4653
4654
4656//template < typename ITERATOR_TYPE >
4657//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
4658//{
4659// return BASE_RANGE::rear_find(scopedstr, ::comparison::comparison < CHARACTER >());
4660//}
4661
4662// manipulation
4663
4664
4666//template < typename ITERATOR_TYPE >
4667//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find(const CHARACTER * ch) const RELEASENOTHROW
4668//{
4669// // find last single character
4670// const SCOPED_STRING & scopedstr = string_find_string_reverse(this->begin(), ch, start);
4671//
4672// // return -1 if not found, distance from beginning otherwise
4673// return((scopedstr == nullptr) ? -1 : character_count(scopedstr - this->begin()));
4674//}
4675//
4677
4678// Convert the string_base < ITERATOR_TYPE > to uppercase
4679template < typename ITERATOR_TYPE >
4680string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_upper()
4681{
4682 character_count nLength = size();
4683 CHARACTER * pszBuffer = get_buffer(nLength);
4684 string_uppercase(scopedstrBuffer, nLength + 1);
4685 release_buffer(nLength);
4686
4687 return *this;
4688}
4689
4690// Convert the string_base < ITERATOR_TYPE > to lowercase
4691template < typename ITERATOR_TYPE >
4692string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_lower()
4693{
4694 character_count nLength = size();
4695 CHARACTER * pszBuffer = get_buffer(nLength);
4696 string_lowercase(scopedstrBuffer, nLength + 1);
4697 release_buffer(nLength);
4698
4699 return *this;
4700}
4701
4702// Reverse the string_base < ITERATOR_TYPE >
4703template < typename ITERATOR_TYPE >
4704string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::MakeReverse()
4705{
4706 character_count nLength = size();
4707 CHARACTER * pszBuffer = get_buffer(nLength);
4708 string_reverse(scopedstrBuffer);
4709 release_buffer(nLength);
4710
4711 return *this;
4712}
4713
4714// trimming
4715
4716// erase all trailing whitespace
4717template < typename ITERATOR_TYPE >
4718string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right()
4719{
4720
4721 return trim_right(" \t\r\n");
4722
4723
4724 //const CHARACTER * pszLast = nullptr;
4725 //const CHARACTER * pszMax = this->begin() + size();
4726 //auto psz = pszMax;
4727
4728 //if (scopedstr != nullptr)
4729 //{
4730
4731 // while (true)
4732 // {
4733
4734 // psz = unicode_prior(scopedstr, this->begin());
4735
4736 // if (scopedstr < this->begin())
4737 // {
4738
4739 // break;
4740
4741 // }
4742
4743 // if (!unicode_is_whitespace(scopedstr))
4744 // {
4745
4746 // pszLast = unicode_next(scopedstr);
4747
4748 // break;
4749
4750 // }
4751
4752 // }
4753
4754 //}
4755
4756 //if (scopedstrLast != nullptr && pszLast < pszMax)
4757 //{
4758
4759 // // truncate at trailing space start
4760
4761 // character_count iLast = character_count(scopedstrLast - this->begin());
4762
4763 // truncate(iLast);
4764
4765 //}
4766
4767 //return *this;
4768
4769}
4770
4771// erase all leading whitespace
4772template < typename ITERATOR_TYPE >
4773string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left()
4774{
4775 // find first non-space character
4776
4777 return trim_left(" \t\r\n");
4778
4779 //auto i = skip_whitespace();
4780
4781 //if (i > 0)
4782 //{
4783
4784 // erase_beginning(i);
4785
4786 //}
4787
4788 //return *this;
4789
4791
4793
4796
4798
4800
4803
4806
4808
4812
4814
4816
4817
4819
4821
4822
4827
4829
4831
4833
4835
4837
4839
4841}
4842
4843// erase all leading and trailing whitespace
4844template < typename ITERATOR_TYPE >
4845string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim()
4846{
4847 return(trim_right().trim_left());
4848}
4849
4850// erase all leading and trailing occurrences of character 'chTarget'
4851template < typename ITERATOR_TYPE >
4852string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(CHARACTER chTarget)
4853{
4854 return(trim_right(chTarget).trim_left(chTarget));
4855}
4856
4857// erase all leading and trailing occurrences of any of the characters in the string_base < ITERATOR_TYPE > 'pszTargets'
4858template < typename ITERATOR_TYPE >
4859string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(const SCOPED_STRING & scopedstrTargets)
4860{
4861 return trim_right(scopedstrTargets).trim_left(scopedstrTargets);
4862}
4863
4864// trimming anything (either side)
4865
4866// erase all trailing occurrences of character 'chTarget'
4867template < typename ITERATOR_TYPE >
4868string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(CHARACTER chTarget)
4869{
4870
4871 auto iterator = this->rear_skip(chTarget);
4872
4873 if (iterator)
4874 {
4875
4876 truncate(iterator);
4877
4878 }
4879
4880 return *this;
4881
4884
4885 //auto psz = this->begin();
4886 //const CHARACTER * pszLast = nullptr;
4887
4888 //while (*psz != 0)
4889 //{
4890 // if (*psz == chTarget)
4891 // {
4892 // if (scopedstrLast == nullptr)
4893 // {
4894 // pszLast = psz;
4895 // }
4896 // }
4897 // else
4898 // {
4899 // pszLast = nullptr;
4900 // }
4901
4902 // unicode_increment(psz);
4903
4904 //}
4905
4906 //if (scopedstrLast != nullptr)
4907 //{
4908 // // truncate at left-most matching character
4909 // character_count iLast = character_count(scopedstrLast - this->begin());
4910 // truncate(iLast);
4911 //}
4912
4913 //return *this;
4914
4915}
4916
4917
4918// erase all trailing occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
4919template < typename ITERATOR_TYPE >
4920string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(const SCOPED_STRING & scopedstrCharacters)
4921//template < pointer_castable < CHARACTER > PCHAR>
4922//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::trim_right(PCHAR szTargets)
4923{
4924
4925 auto p = this->rear_skip_any_character_in(scopedstrCharacters);
4926
4927 if (p < this->end())
4928 {
4929
4930 truncate(p);
4931
4932 }
4933
4934 return *this;
4935
4936 //auto pszTargets = scopedstrzTargets.begin();
4937
4939 //if ((scopedstrTargets == nullptr) || (*pszTargets == 0))
4940 //{
4941 // return *this;
4942 //}
4943
4946
4947 //auto psz = this->begin();
4948 //const CHARACTER * pszStart = psz;
4949 //const CHARACTER * pszLast = nullptr;
4950
4951 //while (!::is_null(scopedstr, 1024) && *psz != 0)
4952 //{
4953 // if (string_find_char(scopedstrTargets, *psz) != nullptr)
4954 // {
4955 // if (scopedstrLast == nullptr)
4956 // {
4957 // pszLast = psz;
4958 // }
4959 // }
4960 // else
4961 // {
4962 // pszLast = nullptr;
4963 // }
4964
4965 // unicode_increment(psz);
4966
4967 //}
4968
4969 //if (scopedstrLast != nullptr)
4970 //{
4971 // // truncate at left-most matching character
4972 // character_count iLast = character_count(scopedstrLast - pszStart);
4973 // truncate(iLast);
4974 //}
4975
4976 //return *this;
4977
4978}
4979
4980
4981// erase all leading occurrences of character 'chTarget'
4982template < typename ITERATOR_TYPE >
4983string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(CHARACTER chTarget)
4984{
4985
4986 auto p = this->skip(chTarget);
4987
4988 if (::is_set(p) && p > this->begin())
4989 {
4990
4991 erase_beginning(p);
4992
4993 }
4994
4996 //auto psz = this->begin();
4997
4998 //while (chTarget == *psz)
4999 //{
5000
5001 // unicode_increment(psz);
5002
5003 //}
5004
5005 //if (scopedstr != this->begin())
5006 //{
5007 // // fix up begin and length
5008 // character_count iFirst = character_count(scopedstr - this->begin());
5009 // CHARACTER * pszBuffer = get_buffer(size());
5010 // psz = pszBuffer + iFirst;
5011 // character_count nDataLength = size() - iFirst;
5012 // memory_transfer(scopedstrBuffer, psz, (nDataLength + 1) * sizeof(CHARACTER));
5013 // release_buffer(nDataLength);
5014 //}
5015
5016 return *this;
5017
5018}
5019
5020
5021// erase all leading occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
5022template < typename ITERATOR_TYPE >
5023string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(const SCOPED_STRING & scopedstrCharacters)
5024//template < pointer_castable < CHARACTER > PCHAR >
5025//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::trim_left(PCHAR szTargets)
5026{
5027
5028 auto p = this->skip_any_character_in(scopedstrCharacters).begin();
5029
5030 if (p > this->begin())
5031 {
5032
5033 this->erase_beginning(p);
5034
5035 }
5036
5037 return *this;
5038
5039 //const CHARACTER * pszTargets = szTargets;
5040
5042 //if ((scopedstrTargets == nullptr) || (*pszTargets == 0))
5043 //{
5044 // return *this;
5045 //}
5046
5047 //auto psz = this->begin();
5048 //while ((*psz != 0) && (string_find_char(scopedstrTargets, *psz) != nullptr))
5049 //{
5050 // unicode_increment(psz);
5051 //}
5052
5053 //if (scopedstr != this->begin())
5054 //{
5055 // // fix up begin and length
5056 // character_count iFirst = character_count(scopedstr - this->begin());
5057 // CHARACTER * pszBuffer = get_buffer(size());
5058 // psz = pszBuffer + iFirst;
5059 // character_count nDataLength = size() - iFirst;
5060 // memory_transfer(scopedstrBuffer, psz, (nDataLength + 1) * sizeof(CHARACTER));
5061 // release_buffer(nDataLength);
5062 //}
5063
5064 //return *this;
5065}
5066
5067
5068// erase all trailing whitespace
5069template < typename ITERATOR_TYPE >
5070string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed() const
5071{
5072
5073 string_base < ITERATOR_TYPE > scopedstr(*this);
5074
5075 scopedstr.trim_right();
5076
5077 return scopedstr;
5078
5079}
5080
5081
5082// erase all leading whitespace
5083template < typename ITERATOR_TYPE >
5084string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed() const
5085{
5086
5087 string_base < ITERATOR_TYPE > scopedstr(*this);
5088
5089 scopedstr.trim_left();
5090
5091 return scopedstr;
5092
5093}
5094
5095
5096// erase all leading and trailing whitespace
5097template < typename ITERATOR_TYPE >
5098string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed() const
5099{
5100
5101 string_base < ITERATOR_TYPE > scopedstr(*this);
5102
5103 scopedstr.trim();
5104
5105 return scopedstr;
5106
5107}
5108
5109
5110// erase all leading and trailing occurrences of character 'chTarget'
5111template < typename ITERATOR_TYPE >
5112string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(CHARACTER chTarget) const
5113{
5114
5115 string_base < ITERATOR_TYPE > scopedstr(*this);
5116
5117 scopedstr.trim(chTarget);
5118
5119 return scopedstr;
5120
5121}
5122
5123
5124// erase all leading and trailing occurrences of any of the characters in the string_base < ITERATOR_TYPE > 'pszTargets'
5125template < typename ITERATOR_TYPE >
5126string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(const SCOPED_STRING & scopedstrCharacters) const
5127{
5128
5129 auto scopedstr(*this);
5130
5131 scopedstr.trim(scopedstrCharacters);
5132
5133 return ::transfer(scopedstr);
5134
5135}
5136
5137
5138// trimming anything (either side)
5139
5140// erase all trailing occurrences of character 'chTarget'
5141template < typename ITERATOR_TYPE >
5142string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(CHARACTER chTarget) const
5143{
5144
5145 auto scopedstr(*this);
5146
5147 scopedstr.trim_right(chTarget);
5148
5149 return ::transfer(scopedstr);
5150
5151}
5152
5153
5154// erase all trailing occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
5155template < typename ITERATOR_TYPE >
5156string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(const SCOPED_STRING & scopedstrCharacters) const
5157{
5158
5159 auto scopedstr(*this);
5160
5161 scopedstr.trim_right(scopedstrCharacters);
5162
5163 return ::transfer(scopedstr);
5164
5165}
5166
5167
5168// erase all leading occurrences of character 'chTarget'
5169template < typename ITERATOR_TYPE >
5170string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(CHARACTER chTarget) const
5171{
5172
5173 string_base < ITERATOR_TYPE > scopedstr(*this);
5174
5175 scopedstr.trim_left(chTarget);
5176
5177 return scopedstr;
5178
5179}
5180
5181
5182// erase all leading occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
5183template < typename ITERATOR_TYPE >
5184string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(const SCOPED_STRING & scopedstrCharacters) const
5185{
5186
5187 auto scopedstr(*this);
5188
5189 scopedstr.trim_left(scopedstrCharacters);
5190
5191 return ::transfer(scopedstr);
5192
5193}
5194
5195
5196template < typename ITERATOR_TYPE >
5197const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(character_count start) const
5198{
5199
5200 return subrange(start, -1);
5201
5202}
5203
5204
5205template < typename ITERATOR_TYPE >
5206template < prototype_integral START, prototype_integral COUNT >
5207const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(START start, COUNT count) const
5208{
5209
5210 character_count length = this->size();
5211
5212 if (start < 0)
5213 {
5214
5215 start = 0;
5216
5217 }
5218 else if ((::character_count)start >= length)
5219 {
5220
5221 return {};
5222
5223 }
5224
5225 character_count end;
5226
5227 if (count < 0)
5228 {
5229
5230 end = length + count + 1;
5231
5232 }
5233 else
5234 {
5235
5236 end = start + count;
5237
5238 }
5239
5240 if (end > length)
5241 {
5242
5243 end = length;
5244
5245 }
5246
5247 if (end <= (::character_count)start)
5248 {
5249
5250 return {};
5251
5252 }
5253
5254 return { this->begin() + start, (::character_count)(end - start) };
5255
5256}
5257
5258
5259template < typename ITERATOR_TYPE >
5260string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::substr(character_count start) const
5261{
5262
5263 return substr(start, -1);
5264
5265}
5266
5267
5268template < typename ITERATOR_TYPE >
5269template < prototype_integral START, prototype_integral COUNT >
5270string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::substr(START start, COUNT count) const
5271{
5272
5273 character_count length = this->size();
5274
5275 if (start < 0)
5276 {
5277
5278 start = 0;
5279
5280 }
5281 else if ((::character_count)start >= length)
5282 {
5283
5284 return {};
5285
5286 }
5287
5288 character_count end;
5289
5290 if (count < 0)
5291 {
5292
5293 end = length + count + 1;
5294
5295 }
5296 else
5297 {
5298
5299 end = start + count;
5300
5301 }
5302
5303 if (end > length)
5304 {
5305
5306 end = length;
5307
5308 }
5309
5310 if (end <= (::character_count) start)
5311 {
5312
5313 return {};
5314
5315 }
5316
5317 return { this->begin() + start, (::character_count) (end - start) };
5318
5319}
5320
5321
5322template < typename ITERATOR_TYPE >
5323void string_base < ITERATOR_TYPE >::clear()
5324{
5325
5326 empty();
5327
5328}
5329
5330
5331template < typename ITERATOR_TYPE >
5332string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right(character_count count) const
5333{
5334
5335 if (count < 0)
5336 {
5337
5338 count = 0;
5339
5340 }
5341
5342 character_count nLength = size();
5343
5344 if (count >= nLength)
5345 {
5346
5347 return *this;
5348
5349 }
5350
5351 return(string_base < ITERATOR_TYPE >(this->begin() + nLength - count, count));
5352
5353}
5354
5355
5356// Return the substring consisting of the leftmost 'count' characters
5357template < typename ITERATOR_TYPE >
5358string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left(character_count count) const
5359{
5360
5361 // count is in XCHARs
5362 if (count < 0)
5363 {
5364
5365 count = 0;
5366
5367 }
5368
5369 character_count nLength = size();
5370
5371 if (count >= nLength)
5372 {
5373
5374 return *this;
5375
5376 }
5377
5378 return(string_base < ITERATOR_TYPE >(this->begin(), count));
5379
5380}
5381
5382
5383// Return the substring consisting of the leftmost characters in the set 'pszCharSet'
5384template < typename ITERATOR_TYPE >
5385string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_including_any_character_in(const SCOPED_STRING & scopedstrCharacters) const
5386{
5387
5388 auto p = this->skip_any_character_in(scopedstrCharacters);
5389
5390 if (!p)
5391 {
5392
5393 return {};
5394
5395 }
5396 else
5397 {
5398
5399 return { p.begin(), this->end() - p.begin()};
5400
5401 }
5402
5403}
5404
5405
5406// Return the substring consisting of the leftmost characters not in the set 'pszCharSet'
5407template < typename ITERATOR_TYPE >
5408string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_skipping_any_character_in(const SCOPED_STRING & scopedstrCharacters) const
5409{
5410
5411 auto p = this->skip_any_character_in(scopedstrCharacters);
5412
5413 if (!p)
5414 {
5415
5416 return {};
5417
5418 }
5419 else
5420 {
5421
5422 return { p.begin(), this->end() - p.begin()};
5423
5424 }
5425
5426}
5427
5428
5429template < typename ITERATOR_TYPE >
5430string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf_arguments(const CHARACTER * pszFormat, va_list args)
5431{
5432
5433 ASSERT(is_string_ok(scopedstrFormat));
5434
5435 character_count nCurrentLength = this->size();
5436
5437 va_list argsForCount;
5438
5439 va_copy(argsForCount, args);
5440
5441 character_count nAppendLength = get_formatted_length(scopedstrFormat, argsForCount);
5442
5443 va_end(argsForCount);
5444
5445 CHARACTER * pszBuffer = get_buffer(nCurrentLength + nAppendLength, true);
5446
5447 _string_format(scopedstrBuffer + nCurrentLength, nAppendLength + 1, pszFormat, args);
5448
5449 release_buffer(nCurrentLength + nAppendLength);
5450
5451 return *this;
5452
5453}
5454
5455
5456template < typename ITERATOR_TYPE >
5457string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf_arguments(const CHARACTER * pszFormat, va_list args)
5458{
5459
5460 ASSERT(is_string_ok(scopedstrFormat));
5461
5462 if (scopedstrFormat == nullptr)
5463 {
5464
5465 throw_exception(error_bad_argument);
5466
5467 }
5468
5469 va_list ptr1;
5470
5471 va_copy(ptr1, args);
5472
5473 character_count nLength = get_formatted_length(scopedstrFormat, ptr1);
5474
5475 va_end(ptr1);
5476
5477 CHARACTER * pszBuffer = get_buffer(nLength);
5478
5479 va_list ptr2;
5480
5481 va_copy(ptr2, args);
5482
5483 _string_format(scopedstrBuffer, nLength + 1, pszFormat, ptr2);
5484
5485 va_end(ptr2);
5486
5487 release_buffer(nLength);
5488
5489 return *this;
5490
5491}
5492
5493
5494// set the string_base < ITERATOR_TYPE > to the value of environment ::payload 'pszVar'
5495// template < typename ITERATOR_TYPE >
5496// bool string_base < ITERATOR_TYPE >::xxxget_environment_variable(const CHARACTER* pszVar)
5497// {
5498
5499// ::u32 nLength = xxxget_environment_variable(scopedstrVar, nullptr, 0);
5500
5501// bool bRetVal = false;
5502
5503// if (nLength == 0)
5504// {
5505
5506// Empty();
5507
5508// }
5509// else
5510// {
5511
5512// CHARACTER* pszBuffer = get_buffer(nLength);
5513
5514// xxxget_environment_variable(scopedstrVar, pszBuffer, nLength);
5515
5516// release_buffer();
5517
5518// bRetVal = true;
5519
5520// }
5521
5522// return(bRetVal);
5523
5524// }
5525
5526
5527// template < typename ITERATOR_TYPE >
5528// bool string_base < ITERATOR_TYPE >::xxxgetenv(const CHARACTER* pszVar)
5529// {
5530
5531// return xxxget_environment_variable(scopedstrVar);
5532
5533// }
5534
5535
5536
5537template < typename ITERATOR_TYPE >
5538string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf(const CHARACTER * pszFormat, ...)
5539{
5540
5541 ASSERT(is_string_ok(scopedstrFormat));
5542
5543 va_list argList;
5544
5545 va_start(argList, pszFormat);
5546
5547 formatf_arguments(scopedstrFormat, argList);
5548
5549 va_end(argList);
5550
5551 return *this;
5552
5553}
5554
5555
5556// append formatted begin using format string_base < ITERATOR_TYPE > 'pszFormat'
5557template < typename ITERATOR_TYPE >
5558string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf(const CHARACTER * pszFormat, ...)
5559{
5560
5561 ASSERT(is_string_ok(scopedstrFormat));
5562
5563 va_list argList;
5564
5565 va_start(argList, pszFormat);
5566
5567 append_formatf_arguments(scopedstrFormat, argList);
5568
5569 va_end(argList);
5570
5571 return *this;
5572
5573}
5574
5575
5576template < typename ITERATOR_TYPE >
5577void string_base < ITERATOR_TYPE >::reserve(character_count res_arg)
5578{
5579 get_buffer(res_arg + 1);
5580}
5581
5582
5583
5584// Convert the string_base < ITERATOR_TYPE > to uppercase
5585template < typename ITERATOR_TYPE >
5586string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::uppered() const
5587{
5588
5589 return string_base < ITERATOR_TYPE >(*this).make_upper();
5590
5591}
5592
5593
5594// Convert the string_base < ITERATOR_TYPE > to lowercase
5595template < typename ITERATOR_TYPE >
5596string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::reversed() const
5597{
5598
5599 return string_base < ITERATOR_TYPE >(*this).MakeReverse();
5600
5601}
5602
5603
5604template < typename ITERATOR_TYPE >
5605string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst) const
5606{
5607
5608 return unichar_substr(iFirst, -1);
5609
5610}
5611
5612
5613template < typename ITERATOR_TYPE >
5614string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst, character_count count) const
5615{
5616
5617 const CHARACTER * pchStart = *this;
5618
5619 if (pchStart == nullptr)
5620 return "";
5621
5622 ::collection::count iUtf8Len = this->unichar_count();
5623
5624 if (iFirst < 0)
5625 iFirst = iUtf8Len + iFirst;
5626
5627 if (count < 0)
5628 count = iUtf8Len - iFirst + count + 1;
5629
5630 if (iFirst + count > iUtf8Len)
5631 count = iUtf8Len - iFirst;
5632
5633 if (count <= 0)
5634 return "";
5635
5636 ::collection::count ca = 0;
5637
5638 while (ca < iFirst && *pchStart != '\0')
5639 {
5640
5641 pchStart = unicode_increment(pchStart);
5642
5643 ca++;
5644
5645 }
5646
5647 if (*pchStart == '\0')
5648 return "";
5649
5650 const CHARACTER * pchEnd = pchStart;
5651
5652 ca = 0;
5653
5654 while (ca < count && *pchEnd != '\0')
5655 {
5656
5657 pchEnd = unicode_increment(pchEnd);
5658
5659 ca++;
5660
5661 }
5662
5663 return string_base < ITERATOR_TYPE >(pchStart, pchEnd - pchStart);
5664
5665
5666}
5667
5668//template < typename ITERATOR_TYPE >
5669//::collection::count string_base < ITERATOR_TYPE >::unichar_count() const
5670//{
5671//
5672// const CHARACTER* pch = *this;
5673//
5674// if (pch == nullptr)
5675// return 0;
5676//
5677// ::collection::count cCharCount = 0;
5678//
5679// while (pch != nullptr && *pch != '\0')
5680// {
5681//
5682// pch = __utf8_inc(pch);
5683//
5684// cCharCount++;
5685//
5686// }
5687//
5688// return cCharCount;
5689//
5690//}
5691
5692
5693template < typename ITERATOR_TYPE >
5694inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unichar_at(character_count iUnicharIndex) const
5695{
5696
5697 auto p = this->begin();
5698
5699 while (p < this->end() && iUnicharIndex > 0)
5700 {
5701
5702 auto iLen = unicode_len(p);
5703
5704 p += iLen;
5705
5706 }
5707
5708 return p;
5709
5710}
5711
5712
5713
5714template < typename ITERATOR_TYPE >
5715bool string_base < ITERATOR_TYPE >::eat_before(string_base < ITERATOR_TYPE > & strBefore, const SCOPED_STRING & scopedstrSeparator, bool bEatEverythingIfNotFound)
5716{
5717
5718 ASSERT(this != &strBefore);
5719
5720 if (this == &strBefore)
5721 {
5722
5723 return false;
5724
5725 }
5726
5727 auto pFind = this->find(scopedstrSeparator);
5728
5729 if (::is_null(pFind))
5730 {
5731
5732 if (bEatEverythingIfNotFound)
5733 {
5734
5735 strBefore = *this;
5736
5737 this->empty();
5738
5739 }
5740
5741 return false;
5742
5743 }
5744
5745 strBefore = (*this)(0, pFind);
5746
5747 *this = (*this)(pFind + scopedstrSeparator.size());
5748
5749 return true;
5750
5751}
5752
5753
5754
5755template < typename ITERATOR_TYPE >
5756bool string_base < ITERATOR_TYPE >::eat_before_let_separator(string_base < ITERATOR_TYPE > & strBefore, const SCOPED_STRING & scopedstrSeparator, bool bEatEverythingIfNotFound)
5757{
5758
5759 ASSERT(this != &strBefore);
5760
5761 if (this == &strBefore)
5762 {
5763
5764 return false;
5765
5766 }
5767
5768 auto pFind = this->find(scopedstrSeparator);
5769
5770 if (::is_null(pFind))
5771 {
5772
5773 if (bEatEverythingIfNotFound)
5774 {
5775
5776 strBefore = *this;
5777
5778 *this = scopedstrSeparator;
5779
5780 }
5781
5782 return false;
5783
5784 }
5785
5786 strBefore = (*this)(0, pFind);
5787
5788 *this = (*this)(pFind);
5789
5790 return true;
5791
5792}
5793
5794
5795template < typename ITERATOR_TYPE >
5796void string_base < ITERATOR_TYPE >::add(CHARACTER ch)
5797{
5798
5799 operator += (ch);
5800
5801}
5802
5803
5804//template < typename ITERATOR_TYPE >
5805//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::operator = (const ::string_stream& scopedstr)
5806//{
5807//
5808// return this->operator =(scopedstr.operator const SCOPED_STRING & scopedstr ());
5809//
5810//}
5811//
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827//template < typename ITERATOR_TYPE >
5828//inline bool string_base < ITERATOR_TYPE > ::begins(const SCOPED_STRING & scopedstr) const
5829//{
5830//
5831// return string_range_begins<CHARACTER>(*this,scopedstr);
5832//
5833//}
5834
5835
5836//template < typename ITERATOR_TYPE >
5837//inline bool string_base < ITERATOR_TYPE > ::ends(const SCOPED_STRING & scopedstr) const
5838//{
5839//
5840// return string_range_ends<CHARACTER>(*this, scopedstr);
5841//
5842//}
5843
5844
5845//template < typename ITERATOR_TYPE >
5846//inline bool string_base < ITERATOR_TYPE > ::begins(const SCOPED_STRING & scopedstr) const
5847//{
5848//
5849// return BASE_RANGE::begins(scopedstr, ::comparison::comparison < CHARACTER >());
5850//
5851//}
5852//
5853//
5854//
5855//template < typename ITERATOR_TYPE >
5856//inline bool string_base < ITERATOR_TYPE > ::ends(const SCOPED_STRING & scopedstr) const
5857//{
5858//
5859// return BASE_RANGE::ends(scopedstr, ::comparison::comparison < CHARACTER >());
5860//
5861//}
5862
5863
5864
5865template < typename ITERATOR_TYPE >
5866inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_begins(const SCOPED_STRING & scopedstr) const
5867{
5868
5869 return this->begins(scopedstr, ::comparison::case_insensitive < CHARACTER >());
5870
5871}
5872
5873
5874
5875template < typename ITERATOR_TYPE >
5876inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_ends(const SCOPED_STRING & scopedstr) const
5877{
5878
5879 return this->ends(scopedstr, ::comparison::case_insensitive < CHARACTER >());
5880
5881}
5882
5883
5884template < typename ITERATOR_TYPE >
5885inline bool string_base < ITERATOR_TYPE > ::begins_eat(const SCOPED_STRING & scopedstrPrefix)
5886{
5887
5888 if (!this->begins(scopedstrPrefix))
5889 {
5890
5891 return false;
5892
5893 }
5894
5895 assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
5896
5897 return true;
5898
5899}
5900
5901
5902template < typename ITERATOR_TYPE >
5903inline bool string_base < ITERATOR_TYPE > ::ends_eat(const SCOPED_STRING & scopedstrSuffix)
5904{
5905
5906 if (!this->ends(scopedstrSuffix))
5907 {
5908
5909 return false;
5910
5911 }
5912
5913 assign(this->begin(), size() - scopedstrSuffix.size());
5914
5915 return true;
5916
5917}
5918
5919
5920template < typename ITERATOR_TYPE >
5921inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eat(const SCOPED_STRING & scopedstrPrefix)
5922{
5923
5924 if (!this->case_insensitive_begins(scopedstrPrefix))
5925 {
5926
5927 return false;
5928
5929 }
5930
5931 assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
5932
5933 return true;
5934
5935}
5936
5937
5938template < typename ITERATOR_TYPE >
5939inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eat(const SCOPED_STRING & scopedstrSuffix)
5940{
5941
5942 if (!this->case_insensitive_ends(scopedstrSuffix))
5943 {
5944
5945 return false;
5946
5947 }
5948
5949 assign(this->begin(), size() - scopedstrSuffix.size());
5950
5951 return true;
5952
5953}
5954
5955
5956template < typename ITERATOR_TYPE >
5957inline bool string_base < ITERATOR_TYPE > ::begins_replace(const SCOPED_STRING & scopedstrNewPrefix, const SCOPED_STRING & scopedstrPrefix)
5958{
5959
5960 if(!begins_eat(scopedstrPrefix))
5961 {
5962
5963 return false;
5964
5965 }
5966
5967 *this = scopedstrNewPrefix + *this;
5968
5969 return true;
5970
5971}
5972
5973
5974template < typename ITERATOR_TYPE >
5975inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_replace(const SCOPED_STRING & scopedstrNewPrefix, const SCOPED_STRING & scopedstrPrefix)
5976{
5977
5978 if(!this->case_insensitive_begins_eat(scopedstrPrefix))
5979 {
5980
5981 return false;
5982
5983 }
5984
5985 *this = scopedstrNewPrefix + *this;
5986
5987 return true;
5988
5989}
5990
5991
5992template < typename ITERATOR_TYPE >
5993inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_prefix(const SCOPED_STRING & scopedstrPrefix)
5994{
5995
5996 if (!this->begins(scopedstrPrefix))
5997 {
5998
5999 operator =(scopedstrPrefix + *this);
6000
6001 }
6002
6003 return *this;
6004
6005}
6006
6007
6008template < typename ITERATOR_TYPE >
6009inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_prefix(const SCOPED_STRING & scopedstrPrefix)
6010{
6011
6012 if (!this->case_insensitive_begins(scopedstrPrefix))
6013 {
6014
6015 operator =(scopedstrPrefix + *this);
6016
6017 }
6018
6019 return *this;
6020
6021}
6022
6023
6024template < typename ITERATOR_TYPE >
6025inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_suffix(const SCOPED_STRING & scopedstrSuffix)
6026{
6027
6028 if (!this->ends(scopedstrSuffix))
6029 {
6030
6031 operator =(*this + scopedstrSuffix);
6032
6033 }
6034
6035 return *this;
6036
6037}
6038
6039
6040template < typename ITERATOR_TYPE >
6041inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_suffix(const SCOPED_STRING & scopedstrSuffix)
6042{
6043
6044 if (!this->case_insensitive_ends(scopedstrSuffix))
6045 {
6046
6047 operator =(*this + scopedstrSuffix);
6048
6049 }
6050
6051 return *this;
6052
6053}
6054
6055
6056
6057template < typename ITERATOR_TYPE >
6058inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_prefixed(const SCOPED_STRING & scopedstrPrefix) const
6059{
6060
6061 if (!this->begins(scopedstrPrefix))
6062 {
6063
6064 return scopedstrPrefix + *this;
6065
6066 }
6067
6068 return *this;
6069
6070}
6071
6072
6073template < typename ITERATOR_TYPE >
6074inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_prefixed(const SCOPED_STRING & scopedstrPrefix) const
6075{
6076
6077 if (!this->case_insensitive_begins(scopedstrPrefix))
6078 {
6079
6080 return scopedstrPrefix + *this;
6081
6082 }
6083
6084 return *this;
6085
6086}
6087
6088
6089template < typename ITERATOR_TYPE >
6090inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_suffixed(const SCOPED_STRING & scopedstrSuffix) const
6091{
6092
6093 if (!this->ends(scopedstrSuffix))
6094 {
6095
6096 return *this + scopedstrSuffix;
6097
6098 }
6099
6100 return *this;
6101
6102}
6103
6104
6105template < typename ITERATOR_TYPE >
6106inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_suffixed(const SCOPED_STRING & scopedstrSuffix) const
6107{
6108
6109 if (!this->case_insensitive_ends(scopedstrSuffix))
6110 {
6111
6112 return *this + scopedstrSuffix;
6113
6114 }
6115
6116 return *this;
6117
6118}
6119
6120//template < typename ITERATOR_TYPE >
6121//inline bool string_base < ITERATOR_TYPE > ::begins(const CHARACTER * pszPrefix) const
6122//{
6123//
6124// auto psz = this->begin();
6125//
6126// while (*psz && *pszPrefix)
6127// {
6128//
6129// if (*psz != *pszPrefix)
6130// {
6131//
6132// return false;
6133//
6134// }
6135//
6136// psz++;
6137//
6138// pszPrefix++;
6139//
6140// }
6141//
6142// return !*pszPrefix;
6143//
6144//}
6145//
6146
6147//template < typename ITERATOR_TYPE >
6148//inline bool string_base < ITERATOR_TYPE > ::begins(const SCOPED_STRING & scopedstrPrefix) const
6149//{
6150//
6151// auto psz = this->begin();
6152//
6153// auto pszPrefix = scopedstrPrefix.begin();
6154//
6155// auto pszPrefixEnd = scopedstrPrefix.end();
6156//
6157// while (*psz && pszPrefix < pszPrefixEnd)
6158// {
6159//
6160// if (*psz != *pszPrefix)
6161// {
6162//
6163// return false;
6164//
6165// }
6166//
6167// psz++;
6168//
6169// pszPrefix++;
6170//
6171// }
6172//
6173// return pszPrefix == pszPrefixEnd;
6174//
6175//}
6176
6177
6178//template < typename ITERATOR_TYPE >
6179//inline bool string_base < ITERATOR_TYPE > ::ends(const SCOPED_STRING & scopedstrSuffix) const
6180//{
6181//
6182// return string_ends(this->begin(), size(), scopedstrSuffix, scopedstrSuffix.size());
6183//
6184//}
6185
6186
6187//template < typename ITERATOR_TYPE >
6188//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins(const SCOPED_STRING & scopedstrPrefix) const
6189//{
6190//
6191// auto psz = this->begin();
6192//
6193// auto pszPrefix = scopedstrPrefix.begin();
6194//
6195// auto pszPrefixEnd = scopedstrPrefix.end();
6196//
6197// while (*psz && pszPrefix < pszPrefixEnd)
6198// {
6199//
6200// if (character_tolower(*psz) != character_tolower(*pszPrefix))
6201// {
6202//
6203// return false;
6204//
6205// }
6206//
6207// psz++;
6208//
6209// pszPrefix++;
6210//
6211// }
6212//
6213// return pszPrefix == pszPrefixEnd;
6214//
6215//}
6216
6217
6218//template < typename ITERATOR_TYPE >
6219//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends(const SCOPED_STRING & scopedstrSuffix) const
6220//{
6221//
6222// return case_insensitive_string_ends(this->begin(), size(), scopedstrSuffix, scopedstrSuffix.size());
6223//
6224//}
6225
6226
6227//template < typename ITERATOR_TYPE >
6228//inline bool string_base < ITERATOR_TYPE > ::begins_eat(const SCOPED_STRING & scopedstrPrefix)
6229//{
6230//
6231// character_count lenPrefix;
6232//
6233// if (!_string_begins(this->begin(), size(), scopedstrPrefix, lenPrefix))
6234// {
6235//
6236// return false;
6237//
6238// }
6239//
6240// assign(this->begin() + lenPrefix, size() - lenPrefix);
6241//
6242// return true;
6243//
6244//}
6245//
6246
6247//template < typename ITERATOR_TYPE >
6248//inline bool string_base < ITERATOR_TYPE > ::ends_eat(const SCOPED_STRING & scopedstrSuffix)
6249//{
6250//
6251// character_count lenSuffix;
6252//
6253// if (!_string_ends(this->begin(), size(), scopedstrSuffix, lenSuffix))
6254// {
6255//
6256// return false;
6257//
6258// }
6259//
6260// truncate(size() - lenSuffix);
6261//
6262// return true;
6263//
6264//}
6265
6266
6267//template < typename ITERATOR_TYPE >
6268//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eat(const SCOPED_STRING & scopedstrPrefix)
6269//{
6270//
6271// character_count lenPrefix;
6272//
6273// if (!case_insensitive__string_begins(this->begin(), size(), scopedstrPrefix, lenPrefix))
6274// {
6275//
6276// return false;
6277//
6278// }
6279//
6280// assign(this->begin() + lenPrefix, size() - lenPrefix);
6281//
6282// return true;
6283//
6284//}
6285
6286
6287//template < typename ITERATOR_TYPE >
6288//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eat(const SCOPED_STRING & scopedstrSuffix)
6289//{
6290//
6291// character_count lenSuffix;
6292//
6293// if (!case_insensitive__string_ends(this->begin(), size(), scopedstrSuffix, lenSuffix))
6294// {
6295//
6296// return false;
6297//
6298// }
6299//
6300// truncate(size() - lenSuffix);
6301//
6302// return true;
6303//
6304//}
6305
6306
6307template < typename ITERATOR_TYPE >
6308inline bool string_base < ITERATOR_TYPE > ::begins_bitten(string_base & strBitten, const SCOPED_STRING & scopedstrPrefix) const
6309{
6310
6311 if (!this->begins(scopedstrPrefix))
6312 {
6313
6314 return false;
6315
6316 }
6317
6318 strBitten.assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
6319
6320 return true;
6321
6322}
6323
6324
6325template < typename ITERATOR_TYPE >
6326inline bool string_base < ITERATOR_TYPE > ::ends_bitten(string_base & strBitten, const SCOPED_STRING & scopedstrSuffix) const
6327{
6328
6329 if (!this->ends(scopedstrSuffix))
6330 {
6331
6332 return false;
6333
6334 }
6335
6336 strBitten.assign(this->begin(), size() - scopedstrSuffix.size());
6337
6338 return true;
6339
6340}
6341
6342
6343template < typename ITERATOR_TYPE >
6344inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_bitten(string_base & strBitten, const SCOPED_STRING & scopedstrPrefix) const
6345{
6346
6347 if (!this->case_insensitive_begins(scopedstrPrefix))
6348 {
6349
6350 return false;
6351
6352 }
6353
6354 strBitten.assign(this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size());
6355
6356 return true;
6357
6358}
6359
6360
6361template < typename ITERATOR_TYPE >
6362inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_bitten(string_base & strBitten, const SCOPED_STRING & scopedstrSuffix) const
6363{
6364
6365 if (!this->case_insensitive_ends(scopedstrSuffix))
6366 {
6367
6368 return false;
6369
6370 }
6371
6372 strBitten.assign(this->begin(), size() - scopedstrSuffix.size());
6373
6374 return true;
6375
6376}
6377
6378
6379template < typename ITERATOR_TYPE >
6380inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::begins_bitten(const SCOPED_STRING & scopedstrPrefix) const
6381{
6382
6383 if (!this->begins(scopedstrPrefix))
6384 {
6385
6386 return *this;
6387
6388 }
6389
6390 return { this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size() };
6391
6392}
6393
6394
6395template < typename ITERATOR_TYPE >
6396inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::ends_bitten(const SCOPED_STRING & scopedstrSuffix) const
6397{
6398
6399 if (!this->ends(scopedstrSuffix))
6400 {
6401
6402 return *this;
6403
6404 }
6405
6406 return { this->begin(), size() - scopedstrSuffix.size()};
6407
6408}
6409
6410
6411template < typename ITERATOR_TYPE >
6412inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_bitten(const SCOPED_STRING & scopedstrPrefix) const
6413{
6414
6415 if (!this->case_insensitive_begins(scopedstrPrefix))
6416 {
6417
6418 return *this;
6419
6420 }
6421
6422 return { this->begin() + scopedstrPrefix.size(), size() - scopedstrPrefix.size()};
6423
6424}
6425
6426
6427template < typename ITERATOR_TYPE >
6428inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_bitten(const SCOPED_STRING & scopedstrSuffix) const
6429{
6430
6431 if (!this->case_insensitive_ends(scopedstrSuffix))
6432 {
6433
6434 return *this;
6435
6436 }
6437
6438 return { this->begin(), size() - scopedstrSuffix.size()};
6439
6440}
6441
6442
6443
6444template < typename ITERATOR_TYPE >
6445inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eaten(string_base & strEaten, const SCOPED_STRING & scopedstrPrefix) const
6446{
6447
6448 if (!this->case_insensitive_begins(scopedstrPrefix))
6449 {
6450
6451 return false;
6452
6453 }
6454
6455 strEaten.assign(this->begin(), scopedstrPrefix.size());
6456
6457 return true;
6458
6459}
6460
6461
6462template < typename ITERATOR_TYPE >
6463inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eaten(string_base & strEaten, const SCOPED_STRING & scopedstrSuffix) const
6464{
6465
6466 if (!this->case_insensitive_ends(scopedstrSuffix))
6467 {
6468
6469 return false;
6470
6471 }
6472
6473 strEaten.assign(this->begin() + length() - scopedstrSuffix.size(), scopedstrSuffix.size());
6474
6475 return true;
6476
6477}
6478
6479
6480template < typename ITERATOR_TYPE >
6481inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_eaten(const SCOPED_STRING & scopedstrPrefix) const
6482{
6483
6484 if (!this->case_insensitive_begins(scopedstrPrefix))
6485 {
6486
6487 return {};
6488
6489 }
6490
6491 return { this->begin(), scopedstrPrefix.size() };
6492
6493}
6494
6495
6496template < typename ITERATOR_TYPE >
6497inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_eaten(const SCOPED_STRING & scopedstrSuffix) const
6498{
6499
6500 if (!this->case_insensitive_ends(scopedstrSuffix))
6501 {
6502
6503 return {};
6504
6505 }
6506
6507 return { this->begin() + length() - scopedstrSuffix.size(), scopedstrSuffix.size() };
6508
6509}
6510
6511
6512template < typename ITERATOR_TYPE >
6513// replace all occurrences of string_base 'pszOld' with string_base 'pszNew'
6514template < typename EQUALITY >
6515inline ::collection::count string_base < ITERATOR_TYPE > ::_replace_with(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start, EQUALITY equality)
6516{
6517
6518 // nSourceLen is in XCHARs
6519 character_count nReplacedLen = scopedstrOld.size();
6520
6521 if (nReplacedLen == 0)
6522 {
6523
6524 return 0;
6525
6526 }
6527
6528 // nReplacementLen is in XCHARs
6529 character_count nReplacementLen = scopedstrNew.size();
6530
6531 // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
6532 auto count = (*this)(start)._occurrence_count_of(scopedstrOld, equality);
6533
6534 // if any changes were made, make them
6535 if (count <= 0)
6536 {
6537
6538 return 0;
6539
6540 }
6541
6542 // if the buffer is too small, just
6543 // allocate a ___new buffer(slow but sure)
6544
6545 character_count nNewLength = this->size() + (nReplacementLen - nReplacedLen) * count;
6546
6547 string_base < ITERATOR_TYPE > str;
6548
6549 CHARACTER * pszBuffer = str.get_buffer(nNewLength);
6550
6551 CHARACTER * pLastNewEnd = pszBuffer;
6552
6553 RANGE rangeOld = *this;
6554
6555 memory_copy(pLastNewEnd, rangeOld.begin(), start * sizeof(CHARACTER));
6556
6557 rangeOld.begin() += start;
6558
6559 pLastNewEnd += start;
6560
6561 CHARACTER * pszTarget;
6562
6563 while ((scopedstrTarget = (CHARACTER *)rangeOld.find(scopedstrOld, equality)) != nullptr)
6564 {
6565
6566 auto offset = pszTarget - rangeOld.begin();
6567
6568 memory_copy(pLastNewEnd,rangeOld.begin(), offset * sizeof(CHARACTER));
6569
6570 pLastNewEnd += offset;
6571
6572 memory_copy(pLastNewEnd, scopedstrNew.begin(), nReplacementLen * sizeof(CHARACTER));
6573
6574 rangeOld.m_begin = pszTarget + nReplacedLen;
6575
6576 pLastNewEnd += nReplacementLen;
6577
6578 }
6579
6580 memory_copy(pLastNewEnd,rangeOld.begin(), (rangeOld.end() - rangeOld.begin()) * sizeof(CHARACTER));
6581
6582 str.release_buffer(nNewLength);
6583
6584 *this = ::transfer(str);
6585
6586 return count;
6587
6588}
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599//template < typename ITERATOR_TYPE >
6600//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_begins(const SCOPED_STRING & scopedstrPrefix)
6601//{
6602//
6603// if (!begins(scopedstrPrefix))
6604// {
6605//
6606// operator =(string_base(scopedstrPrefix) + *this);
6607//
6608// }
6609//
6610// return *this;
6611//
6612//}
6613
6614
6615//template < typename ITERATOR_TYPE >
6616//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_begins(const SCOPED_STRING & scopedstr)
6617//{
6618//
6619// if (!case_insensitive_begins(scopedstr))
6620// {
6621//
6622// operator =(string_base(scopedstr) + *this);
6623//
6624// }
6625//
6626// return *this;
6627//
6628//}
6629
6630
6631//template < typename ITERATOR_TYPE >
6632//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_ends(const SCOPED_STRING & scopedstrSuffix)
6633//{
6634//
6635// if (!ends(scopedstrSuffix))
6636// {
6637//
6638// operator =(*this + scopedstrSuffix);
6639//
6640// }
6641//
6642// return *this;
6643//
6644//}
6645
6646
6647//template < typename ITERATOR_TYPE >
6648//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_ends(const SCOPED_STRING & scopedstrSuffix)
6649//{
6650//
6651// if (!case_insensitive_ends(scopedstrSuffix))
6652// {
6653//
6654// operator =(*this + scopedstrSuffix);
6655//
6656// }
6657//
6658// return *this;
6659//
6660//}
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674template < prototype_character CHARACTER >
6675void CopyCharsOverlapped(CHARACTER * pchDest, const CHARACTER * pchSrc, character_count nChars) noexcept
6676{
6677
6678 memory_transfer(pchDest, pchSrc, nChars * sizeof(CHARACTER));
6679
6680}
6681
6682
6683template < prototype_character CHARACTER >
6684void CopyCharsOverlapped(CHARACTER * pchDest, size_t nDestLen, const CHARACTER * pchSrc, character_count nChars) noexcept
6685{
6686
6687 memory_transfer(pchDest, pchSrc, nChars * sizeof(CHARACTER));
6688
6689}
6690
6691
6692
6693template < typename STRING >
6694inline STRING & string_concatenate(STRING & scopedstr, const typename STRING::CHARACTER * psz1, character_count nLength1, const typename STRING::CHARACTER * psz2, character_count nLength2)
6695{
6696
6697 character_count nNewLength = nLength1 + nLength2;
6698
6699 typename STRING::CHARACTER * pszBuffer = scopedstr.get_buffer(nNewLength);
6700
6701 string_count_copy(scopedstrBuffer, psz1, nLength1);
6702
6703 string_count_copy(scopedstrBuffer + nLength1, psz2, nLength2);
6704
6705 scopedstr.release_buffer(nNewLength);
6706
6707 return scopedstr;
6708
6709}
6710
6711
6712template < typename STRING >
6713inline bool string_ends_eat(STRING & ansistr, const STRING & scopedstrSuffix)
6714{
6715
6716 auto lenSuffix = scopedstrSuffix.length();
6717
6718 if (lenSuffix > ansistr.length())
6719 {
6720
6721 return false;
6722
6723 }
6724
6725 if (STRING::string_count_compare(ansistr.reverse_ptr_at(lenSuffix), scopedstrSuffix, lenSuffix) != 0)
6726 {
6727
6728 return false;
6729
6730 }
6731
6732 ansistr.reverse_truncate(lenSuffix);
6733
6734 return true;
6735
6736}
6737
6738//
6739//
6740//
6741//inline ::string operator +(const ::scoped_string & scopedstr, const SCOPED_STRING & scopedstr);
6742//template < prototype_atom ATOM >
6743//inline ::string operator +(const ::scoped_string & scopedstr, const ATOM & atom);
6748//template < prototype_payload PAYLOAD >
6749//inline ::string operator +(const ::scoped_string & scopedstr, const PAYLOAD & payload);
6754//
6755
6756
6757
6758
6759//template < typename ITERATOR_TYPE >
6760//inline bool string_base < ITERATOR_TYPE >::equals(const SCOPED_STRING & scopedstr) const noexcept
6761//{
6762//
6763// return ::scoped_string_base < const CHARACTER * >(*this).equals(scopedstr, ::comparison::comparison < CHARACTER >());
6764//
6765//}
6766//
6767//
6768//template < typename ITERATOR_TYPE >
6769//inline bool string_base < ITERATOR_TYPE >::case_insensitive_equals(const SCOPED_STRING & scopedstr) const noexcept
6770//{
6771//
6772// return ::scoped_string_base < const CHARACTER * >(*this).equals(scopedstr, ::comparison::case_insensitive< CHARACTER >());
6773//
6774//}
6775
6776
6778//inline character_count string::find(::ansi_character ch) const RELEASENOTHROW
6779//{
6780//
6781// const_char_pointer psz = strchr(m_psz, ch);
6782//
6783// return psz == nullptr ? -1 : psz - m_psz;
6784//
6785//}
6786//
6787
6789//inline character_count string::find(::ansi_character ch) const RELEASENOTHROW
6790//{
6791//
6792// const_char_pointer psz = strchr(&m_psz[start], ch);
6793//
6794// return psz == nullptr ? -1 : psz - m_psz;
6795//
6796//}
6797
6798
6799::i32 get_mem_free_available_kb();
6800
6801
6802template < prototype_character CHARACTER >
6803::wd32_character unicode_iterator < CHARACTER > ::operator *() { return unicode_index(m_psz); }
6804
6805
6806template < prototype_character CHARACTER >
6807unicode_iterator < CHARACTER > & unicode_iterator < CHARACTER > ::operator ++()
6808{
6809
6810 unicode_increment(m_psz);
6811
6812 return *this;
6813
6814}
6815
6816
6817template < prototype_character CHARACTER >
6818unicode_iterator < CHARACTER > unicode_iterator < CHARACTER > ::operator ++(::i32)
6819{
6820
6821 auto psz = m_psz;
6822
6823 unicode_increment(m_psz);
6824
6825 return psz;
6826
6827}
6828
6829
6830
6831template < typename ITERATOR_TYPE >
6832inline string_base < ITERATOR_TYPE > operator +(const scoped_string_base < ITERATOR_TYPE > & scopedstr, const inline_number_string & inlinenumberstring)
6833{
6834
6835 string_base < ITERATOR_TYPE > str(scopedstr);
6836
6837 string_base < ITERATOR_TYPE > strNumber(inlinenumberstring);
6838
6839 str.append(strNumber);
6840
6841 return ::transfer(scopedstr);
6842
6843}
6844
6845template < character_count n >
6846inline const_string_range_static_array < const_char_pointer ,2 > operator +(const ::i8 (&s)[n], const inline_number_string& inlinenumberstring)
6847{
6848
6849 return { ::as_string_literal<::i8, n>(s), inlinenumberstring };
6850
6851}
6852
6853
6854//template < character_count m_sizeMaximumLength >
6855//inline ::string operator +(const ::scoped_string & scopedstr, const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring)
6856//{
6857//
6858// return str + ::string(inlinestring);
6859//
6860//}
6861//
6862//
6863//template < ::collection::count c >
6864//inline ::string operator +(const ::scoped_string & scopedstr, const ::i8(&sz)[c])
6865//{
6866//
6867// return str + ::string(sz);
6868//
6869//}
6870
6871
6872
6873
6874
6875
6876
6877//template < ::collection::count c, character_count m_sizeMaximumLength >
6878//inline ::string operator +(const ::i8(&sz)[c], const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring)
6879//{
6880//
6881// return ::transfer(::string(sz) + ::string(inlinestring));
6882//
6883//}
6884//
6885//
6886//
6887//template < ::collection::count c, character_count m_sizeMaximumLength >
6888//inline ::string operator +(const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring, const ::i8(&sz)[c])
6889//{
6890//
6891// return ::transfer(::string(inlinestring) + ::string(sz));
6892//
6893//}
6894
6895
6896//inline ::string operator + (const ::scoped_string & scopedstr, ::i8 ch)
6897//{
6898//
6899// return str + ::string(ch);
6900//
6901//}
6902
6903
6904template < typename ITERATOR_TYPE >
6905inline string_base < ITERATOR_TYPE >::string_base(const ::atom& atom) :
6906 string_base(atom.as_string())
6907{
6908
6909
6910}
6911
6912
6913template < typename ITERATOR_TYPE >
6914string_base < ITERATOR_TYPE >::string_base(const ::payload & payload) :
6915 string_base(payload.as_string())
6916{
6917
6918
6919}
6920
6921
6922template < typename ITERATOR_TYPE >
6923inline string_base < ITERATOR_TYPE >::string_base(const property & property) :
6924 string_base(property.as_string())
6925{
6926
6927
6928}
6929
6930
6931
6932
6933
6934
6935
6936template < typename ITERATOR_TYPE >
6937inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const scoped_ansi_string & ansistr) { assign_range(ansistr); return *this; }
6938
6939template < typename ITERATOR_TYPE >
6940inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const scoped_wd16_string & wd16str) { assign_range(wd16str); return *this; }
6941
6942template < typename ITERATOR_TYPE >
6943inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const scoped_wd32_string & wd32str) { assign_range(wd32str); return *this; }
Definition atom.h:237
Definition _template_after_initial_concepts.h:15
const_iterator find_first(CHARACTER chSeparator, ::character_count start=0) const RELEASENOTHROW
character_count _find_first_character_in(const CHARACTER * blockCharacters, character_count iStart = ...
Definition _impl_string_base.h:2856
const_iterator unicode_find(const SCOPED_STRING &scopedstr) const RELEASENOTHROW
Find the first occurrence of scopedstr, starting at start position and up to count characters from st...
Definition _impl_string_base.h:2867
Definition payload.h:54
Definition property.h:81
Definition range.h:223
Definition string_base.h:90
void construct2(const ::character_range< const CHARACTER * > &range)
Definition _impl_string_base.h:438
Definition std_iterator.h:49