acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
_impl_string_base.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
11#include "string_base.h"
12#include "acme/prototype/string/_impl_string_base_allocation.h"
13
14
15template < prototype_character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
16inline ::std::strong_ordering _sz_compare(const CHARACTER * pA, const CHARACTER * pB, ORDERING ordering) noexcept
17{
18
19 while (true)
20 {
21
22 auto order = ordering.order(*pA, *pB);
23
24 if (order != 0 || !*pA || !*pB)
25 {
26
27 return order;
28
29 }
30
31 pA++;
32
33 pB++;
34
35 }
36
37}
38
39
40template < prototype_character CHARACTER >
41constexpr ::std::strong_ordering _sz_compare(const CHARACTER * pA, const CHARACTER * pB) noexcept
42{
43
44 return _sz_compare(pA, pB, ::comparison::comparison<CHARACTER>());
45
46}
47
48
49template < prototype_character CHARACTER >
50constexpr ::std::strong_ordering case_insensitive__sz_compare(const CHARACTER * pA, const CHARACTER * pB) noexcept
51{
52
53 return _sz_compare(pA, pB, ::comparison::case_insensitive < CHARACTER >());
54
55}
56
57
58template < prototype_character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
59inline ::std::strong_ordering _sz_count_compare(const CHARACTER * pA, const CHARACTER * pB, character_count sizeB, ORDERING ordering) noexcept
60{
61
62 auto pBEnd = pB + sizeB;
63
64 while (true)
65 {
66
67 if (pB >= pBEnd)
68 {
69
70 return *pA <=> 0;
71
72 }
73
74 auto order = ordering.order(*pA, *pB);
75
76 if (order != 0 || !*pA)
77 {
78
79 return order;
80
81 }
82
83 pA++;
84
85 pB++;
86
87 }
88
89}
90
91
92template < prototype_character CHARACTER >
93constexpr ::std::strong_ordering _sz_count_compare(const CHARACTER * pA, const CHARACTER * pB, character_count sizeB) noexcept
94{
95
96 return _sz_count_compare(pA, pB, sizeB, ::comparison::comparison<CHARACTER>());
97
98}
99
100
101template < prototype_character CHARACTER >
102constexpr ::std::strong_ordering case_insensitive__sz_count_compare(const CHARACTER * pA, const CHARACTER * pB, character_count sizeB) noexcept
103{
104
105 return _sz_count_compare(pA, pB, sizeB, ::comparison::case_insensitive < CHARACTER >());
106
107}
108
109
110template < prototype_character CHARACTER, ::comparison::ordering < CHARACTER > ORDERING >
111inline ::std::strong_ordering _count_sz_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB, ORDERING ordering) noexcept
112{
113
114 auto pAEnd = pA + sizeA;
115
116 while (true)
117 {
118
119 if (pA >= pAEnd)
120 {
121
122 return ordering.order({}, *pB);
123
124 }
125
126 auto order = ordering.order(*pA, *pB);
127
128 if (order != 0 || !*pB)
129 {
130
131 return order;
132
133 }
134
135 pA++;
136
137 pB++;
138
139 }
140
141}
142
143
144template < prototype_character CHARACTER >
145constexpr ::std::strong_ordering _count_sz_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB) noexcept
146{
147
148 return _count_sz_compare(pA, sizeA, pB, ::comparison::comparison<CHARACTER>());
149
150}
151
152
153template < prototype_character CHARACTER >
154constexpr ::std::strong_ordering case_insensitive__count_sz_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB) noexcept
155{
156
157 return _count_sz_compare(pA, sizeA, pB, ::comparison::case_insensitive < CHARACTER >());
158
159}
160
161
162
163//template < typename ITERATOR_TYPE >
164//inline ::std::strong_ordering case_insensitive__string_compare(const CHARACTER * pszA, character_count sizeA, const_char_pointer pszB, character_count sizeB) noexcept
165//{
166//
167// character_count lenCompare = minimum(sizeA, sizeB);
168//
169// auto ordering = case_insensitive_string_count_compare(scopedstrA, pszB, lenCompare);
170//
171// if (ordering != 0)
172// {
173//
174// return ordering;
175//
176// }
177//
178// return sizeA <=> sizeB;
179//
180//}
181
182
183template < typename ITERATOR_TYPE >
184inline ::std::strong_ordering _scopedstr_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
185{
186
187 character_count len = minimum(scopedstrA.size(), scopedstrB.size());
188
189 auto order = string_count_collate(scopedstrA.begin(), scopedstrB.begin(), len);
190
191 if (order != 0)
192 {
193
194 return order;
195
196 }
197
198 return scopedstrA.size() <=> scopedstrB.size();
199
200}
201
202
203template < typename ITERATOR_TYPE >
204inline ::std::strong_ordering _case_insensitive_scopedstr_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
205{
206
207 character_count len = minimum(scopedstrA.size(), scopedstrB.size());
208
209 auto order = case_insensitive_string_count_collate(scopedstrA.begin(), scopedstrB.begin(), len);
210
211 if (order != 0)
212 {
213
214 return order;
215
216 }
217
218 return scopedstrA.size() <=> scopedstrB.size();
219
220}
221
222
223//template < typename ITERATOR_TYPE >
224//inline ::i32 string_compare(const CHARACTER * pszA, character_count sizeA, const_char_pointer pszB, character_count sizeB) noexcept
225//{
226//
227// ::i32 iCompare;
228//
229// if (string_compare_prefix(iCompare, pszA, pszB))
230// {
231//
232// return iCompare;
233//
234// }
235//
236// return _string_compare(scopedstrA, sizeA, pszB, sizeB);
237//
238//}
239
240
241//template < typename ITERATOR_TYPE >
242//inline ::i32 case_insensitive_string_order(const array_scopedstr<CHARACTER> & scopedstrA, ) noexcept
243//{
244//
245// ::i32 iCompare;
246//
247// if (string_compare_prefix(iCompare, pszA, pszB))
248// {
249//
250// return iCompare;
251//
252// }
253//
254// return case_insensitive__string_compare(scopedstrA, sizeA, pszB, sizeB);
255//
256//}
257
258
259template < typename ITERATOR_TYPE >
260inline ::std::strong_ordering range_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
261{
262
263 //::std::strong_ordering order(::std::strong_ordering::less);
264
265 //if (scopedstrA._initialize_order(order, scopedstrA, scopedstrB))
266 //{
267
268 // return order;
269
270 //}
271
272 return _string_collate(::string_base < ITERATOR_TYPE >(scopedstrA).c_str(), ::string_base < ITERATOR_TYPE >(scopedstrB).c_str());
273
274}
275
276
277template < typename ITERATOR_TYPE >
278inline ::std::strong_ordering case_insensitive_range_collate(::scoped_string_base < ITERATOR_TYPE > scopedstrA, ::scoped_string_base < ITERATOR_TYPE > scopedstrB) noexcept
279{
280
281 //::std::strong_ordering order(::std::strong_ordering::less);
282
283 //if (scopedstrA._initialize_order(order, scopedstrA, scopedstrB))
284 //{
285
286 // return order;
287
288 //}
289
290 return _case_insensitive_string_collate(::string_base < ITERATOR_TYPE >(scopedstrA).c_str(), ::string_base < ITERATOR_TYPE >(scopedstrB).c_str());
291
292}
293
294
295template < prototype_character CHARACTER >
296inline ::std::strong_ordering _sz_count_collate(const CHARACTER * pszA, const CHARACTER * pszB, character_count sizeB) noexcept
297{
298
299 return range_collate<const CHARACTER>(pszA, { pszB, sizeB });
300
301}
302
303
304template < prototype_character CHARACTER >
305inline ::std::strong_ordering _case_insensitive_sz_count_collate(const CHARACTER * pszA, const CHARACTER * pszB, character_count sizeB) noexcept
306{
307
308 return case_insensitive_range_collate<const CHARACTER>(pszA, { pszB, sizeB });
309
310}
311
312
313inline ::std::strong_ordering _count_sz_collate(const_char_pointer pszA, character_count sizeA, const_char_pointer pszB) noexcept
314{
315
316 return range_collate<const_char_pointer >({ pszA, sizeA }, pszB);
317
318}
319
320
321inline ::std::strong_ordering _case_insensitive_count_sz_collate(const_char_pointer pszA, character_count sizeA, const_char_pointer pszB) noexcept
322{
323
324 return case_insensitive_range_collate<const_char_pointer >({ pszA, sizeA }, pszB);
325
326}
327
328
329CLASS_DECL_ACME ::string string_formatf(const_char_pointer pszFormat, ...);
330
331
332
333
334
335CLASS_DECL_ACME void foo123();
336
337
338//template < typename ITERATOR_TYPE >
339//inline void string_base < ITERATOR_TYPE >::construct1(const ITERATOR_TYPE p, character_count length)
340//{
341//
342// if (::is_null(p) || length <= 0)
343// {
344//
345// default_construct();
346//
347// return;
348//
349// }
350//
351// create_string(length);
352//
353// memory_copy((void *) this->m_begin, p, length * sizeof(CHARACTER));
354//
355// *(CHARACTER*)this->m_end = (CHARACTER)0;
356//
357//}
358
359
360//template < typename ITERATOR_TYPE >
361//template < ::i32 t_size >
362//inline string_base < ITERATOR_TYPE >::string_base(const const_string_range_static_array < ITERATOR_TYPE, t_size >& a) :
363// ::const_string_range < ITERATOR_TYPE >(no_initialize_t{})
364//{
365//
366// auto new_len = a.size();
367//
368// auto p = construct_string(new_len);
369//
370// a.block_concatenate_to(p);
371//
372// ASSERT(p <= this->m_end);
373//
374// *p = CHARACTER{};
375//
376//}
377
378
379//template < typename ITERATOR_TYPE >
380//template < ::i32 t_size >
381//string_base< ITERATOR_TYPE>& string_base< ITERATOR_TYPE>::append(const const_string_range_static_array < const CHARACTER *, t_size >& a)
382//{
383//
384// auto old_len = this->size();
385//
386// auto add_len = a.size();
387//
388// auto new_len = old_len + add_len;
389//
390// auto p = get_buffer<true>(new_len);
391//
392// p += old_len;
393//
394// a.block_concatenate_to(p);
395//
396// ASSERT(p <= this->m_end);
397//
398// *(CHARACTER*)this->m_end = {};
399//
400// return *this;
401//
402//}
403
404
405//template < typename ITERATOR_TYPE >
406//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
407//string_base< ITERATOR_TYPE>& string_base< ITERATOR_TYPE>::append(const const_string_range_static_array < const OTHER_CHARACTER *, t_size >& a)
408//{
409//
410// auto old_len = this->size();
411//
412// character_count iaLen[t_size];
413//
414// character_count* plen = iaLen;
415//
416// auto add_len = a.__utf_length(this->begin(), plen);
417//
418// auto new_len = old_len + add_len;
419//
420// auto p = get_buffer<true>(new_len);
421//
422// p += old_len;
423//
424// plen = iaLen;
425//
426// a.__utf_concatenate_to(p, plen);
427//
428// ASSERT(p <= this->m_end);
429//
430// p[new_len] = {};
431//
432// return *this;
433//
434//}
435
436
437template < typename ITERATOR_TYPE >
438inline void string_base < ITERATOR_TYPE >::construct2(const ::character_range < const CHARACTER * > & range)
439{
440
441 this->m_begin = range.m_begin;
442
443 this->m_end = range.m_end;
444
445 this->m_erange = range.m_erange;
446
447 this->m_pbasedata = range.m_pbasedata;
448
449 if (this->m_pbasedata)
450 {
451
453
454 this->m_pbasedata->base_data_increment_reference_count();
455
456 }
457
458}
459
460
461//template < typename ITERATOR_TYPE >
462//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
463//inline void string_base < ITERATOR_TYPE >::construct5(const OTHER_CHARACTER * p, character_count len)
464//{
465//
466// if (::is_null(p) || len <= 0)
467// {
468//
469// default_construct();
470//
471// return;
472//
473// }
474//
475// auto dstlen = utf_to_utf_length(this->begin(), p, len);
476//
477// create_string(dstlen);
478//
479// utf_to_utf((CHARACTER *)this->m_begin, p, len);
480//
481// *(CHARACTER*)this->m_end = (CHARACTER)0;
482//
483//}
484//
485
486//template < typename ITERATOR_TYPE >
487//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
488//inline string_base < ITERATOR_TYPE >::string_base(const const_string_range_static_array < const OTHER_CHARACTER *, t_size > & a)
489//{
490//
491// character_count iaLen[t_size];
492//
493// character_count * plen = iaLen;
494//
495// auto len = a.__utf_length(this->begin(), plen);
496//
497// create_string(len);
498//
499// auto p = (CHARACTER * ) this->m_begin;
500//
501// plen = iaLen;
502//
503// a.__utf_concatenate_to(p, plen);
504//
505// *p = {};
506//
507//}
508
509
510//template < typename ITERATOR_TYPE >
511//void string_base< ITERATOR_TYPE >::construct1(const string_base& str)
512//{
513//
514// this->m_begin = str.m_begin;
515// this->m_end = str.m_end;
516// this->m_erange = str.m_erange;
517//
518// auto pbasedata = string_base::NATURAL_META_DATA::from_data(this->m_begin);
519//
520// pbasedata->natural_increment_reference_count();
521//
522//}
523
524
525//template < typename ITERATOR_TYPE >
526//template < typename RANGE >
527//void string_base< ITERATOR_TYPE >::construct10(const RANGE& range)/* requires
528//::std::is_base_of_v < ::character_range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE >
529//&& !
530//(::std::is_base_of_v < string_base < ITERATOR_TYPE >, RANGE >
531// || ::std::is_same_v < string_base < ITERATOR_TYPE >, RANGE >)*/
532//{
533//
534// if (range.m_erange & e_range_string)
535// {
536//
537// this->construct1(*(const string_base*)&range);
538//
539// }
540// else
541// {
542//
543// this->construct5(range.data(), range.size());
544//
545// }
546//
547//}
548
549
550//template < typename ITERATOR_TYPE >
551//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
552//inline void string_base < ITERATOR_TYPE >::construct20(const ::character_range < const OTHER_CHARACTER* > & range)
553//{
554//
555// character_count len = __utf_to_utf_length(this->m_begin, range.m_begin, range.size());
556//
557// auto p = create_string(len);
558//
559// auto plen = &len;
560//
561// range.__utf_concatenate_to(p, plen);
562//
563// *p = {};
564//
565//}
566
567
568//template < typename ITERATOR_TYPE >
569//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
570//inline void string_base < ITERATOR_TYPE >::construct20(const OTHER_CHARACTER * start, character_count length, enum_range erange)
571//{
572//
573// if constexpr (sizeof(CHARACTER) == sizeof(CHARACTER2))
574// {
575//
576// if(erange & e_range_string)
577// {
578//
579// auto pbasedata = string_base::NATURAL_META_DATA::from_data(start);
580//
581// pbasedata->natural_increment_reference_count();
582//
583// this->m_begin = start;
584// this->m_end = start + length;
585// this->m_erange = erange;
586//
587// }
588// else
589// {
590//
591// this->construct1(start, length);
592//
593// }
594//
595// }
596// else
597// {
598//
599// this->construct5(start, length);
600//
601// }
602//
603//}
604
605
606//template < typename ITERATOR_TYPE >
607//template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
608//inline string_base < ITERATOR_TYPE >::string_base(OTHER_CHARACTER chSrc, character_count repeat) :
609// string_base(nullptr)
610//{
611//
612// if (repeat <= 0)
613// {
614//
615// default_construct();
617// return;
618//
619// }
620//
621// auto lenUnit = utf_to_utf_length(this->begin(), &chSrc, 1);
622//
623// auto len = lenUnit * repeat;
624//
625// create_string(len);
626//
627// CHARACTER sz[8];
628//
629// utf_to_utf(sz, &chSrc, 1);
630//
631// auto pTarget = (CHARACTER*) this->m_begin;
632//
633// while (repeat > 0)
634// {
635//
636// auto pSource = sz;
637//
638// for (::i32 j = 0; j < lenUnit; j++, pSource++)
639// {
640//
641// *pTarget++ = *pSource;
642//
643// }
644//
645// repeat--;
646//
647// }
648//
649// *(CHARACTER *)this->m_end = (CHARACTER)0;
650//
651//}
652
653
654//template < typename ITERATOR_TYPE >
655//inline string_base < ITERATOR_TYPE >::string_base(::ansi_character ansich, character_count repeat)
656//{
657//
658// assign(ansich, repeat);
659//
660//}
661//
662//
663//template < typename ITERATOR_TYPE >
664//inline string_base < ITERATOR_TYPE >::string_base(::wd16_character wd16ch, character_count repeat)
665//{
666//
667// assign(wd16ch, repeat);
668//
669//}
670//
671//
672//template < typename ITERATOR_TYPE >
673//inline string_base < ITERATOR_TYPE >::string_base(::wd32_character wd32ch, character_count repeat)
674//{
675//
676// assign(wd32ch, repeat);
677//
678//}
679
680
681template < typename ITERATOR_TYPE >
682inline character_count const_string_range < ITERATOR_TYPE >::unichar_count() const
683{
684
685 return ::unichar_count(this->begin());
686
687}
688
689
690//template < typename ITERATOR_TYPE >
691//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const natural_ansistring & ansistrSrc)
692//{
693//
694// return assign(*this, ansistrSrc);
695//
696//}
697
698
699//template < typename ITERATOR_TYPE >
700//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const natural_wd16string & wd16strSrc)
701//{
702//
703// return assign(*this, wd16strSrc);
704//
705//}
706
707
708//template < typename ITERATOR_TYPE >
709//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const natural_wd32string & wd32strSrc)
710//{
711//
712// return assign(*this, wd32strSrc.begin());
713//
714//}
715
716
717//template < typename ITERATOR_TYPE >
718//template < prototype_character CHARACTER2 >
719//string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const ::scoped_string_base < const CHARACTER2 * > & scopedstr)
720//{
721//
722// assign(scopedstr);
723//
724// return *this;
725//
726//}
727
728
729
730//template < typename ITERATOR_TYPE >
731//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const string_base & str)
732//{
733//
734// assign(scopedstr);
735//
736// return *this;
737//
738//}
739
740
741//template < typename ITERATOR_TYPE >
742//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const wd16_string & wd16str)
743//{
744//
745// return assign(*this, wd16str.begin());
746//
747//}
748
749
750//template < typename ITERATOR_TYPE >
751//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const wd32_string & wd32str)
752//{
753//
754// return assign(*this, wd32str.begin());
755//
756//}
757
758
759//template < typename ITERATOR_TYPE >
760//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const_char_pointer pansichar)
761//{
762//
763// return assign(*this, pansichar);
764//
765//}
766//
767//
768//template < typename ITERATOR_TYPE >
769//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const ::wd16_character * pwd16char)
770//{
771//
772// return assign(*this, pwd16char);
773//
774//}
775//
776//
777//template < typename ITERATOR_TYPE >
778//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(const ::wd32_character * pwd32char)
779//{
780//
781// return assign(*this, pwd32char);
782//
783//}
784//
785//
786//template < typename ITERATOR_TYPE >
787//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(::ansi_character ansich)
788//{
789//
790// return assign(*this, ansich);
791//
792//}
793//
794//
795//template < typename ITERATOR_TYPE >
796//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(::wd16_character wd16ch)
797//{
798//
799// return assign(*this, wd16ch);
800//
801//}
802//
803//
804//template < typename ITERATOR_TYPE >
805//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator=(::wd32_character wd32ch)
806//{
807//
808// return assign(*this, wd32ch);
809//
810//}
811//
812//
813//template < typename ITERATOR_TYPE >
814//template < ::i32 t_nSize >
815//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator =(const static_string<CHARACTER, t_nSize > & ansistrSrc)
816//{
817//
818// assign(ansistrSrc);
819//
820// return *this;
821//
822//}
823
824//template < typename ITERATOR_TYPE >
825//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const string_base & str)
826//{
827//
828// return append(scopedstr);
829//
830//}
831
832
833//template < typename ITERATOR_TYPE >
834//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const ::const_ansi_range & scopedstr)
835//{
836//
837// return append(scopedstr);
838//
839//}
840
841
842//template < typename ITERATOR_TYPE >
843//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const const_wd16_range & wd16scopedstr)
844//{
845//
846// return append(wd16scopedstr);
847//
848//}
849//
850//
851//template < typename ITERATOR_TYPE >
852//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const const_wd32_range & wd32scopedstr)
853//{
854//
855// return append(wd32scopedstr);
856//
857//}
858
859
860//template < typename ITERATOR_TYPE >
861//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const inline_number_string & inlinenumberstring)
862//{
863//
864// return append(inlinenumberstring);
865//
866//}
867
868
869
870//template < typename ITERATOR_TYPE >
871//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const_char_pointer pszSrc)
872//{
873//
874// return append(scopedstrSrc);
875//
876//}
877//
878//
879//template < typename ITERATOR_TYPE >
880//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const ::wd16_character * pszSrc)
881//{
882//
883// return append(scopedstrSrc);
884//
885//}
886//
887//
888//template < typename ITERATOR_TYPE >
889//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const ::wd32_character * pszSrc)
890//{
891//
892// return append(scopedstrSrc);
893//
894//}
895//
896//
897//template < typename ITERATOR_TYPE >
898//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(::ansi_character ansich)
899//{
900//
901// return append(ansich);
902//
903//}
904//
905//
906//template < typename ITERATOR_TYPE >
907//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(::wd16_character wd16ch)
908//{
909//
910// return append(wd16ch);
911//
912//}
913//
914//
915//template < typename ITERATOR_TYPE >
916//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(::wd32_character wd32ch)
917//{
918//
919// return append(wd32ch);
920//
921//}
922
923
924//template < typename ITERATOR_TYPE >
925//template < ::i32 t_nSize >
926//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator +=(const static_string<CHARACTER, t_nSize > & ansistrSrc)
927//{
928//
929// return append(ansistrSrc);
930//
931//}
932
933
934//template < typename ITERATOR_TYPE >
935//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd16_character wd16ch) const
936//{
937//
938// string_base < ITERATOR_TYPE > ansistr;
939//
940// ansistr.append(wd16ch);
941//
942// return ansistr;
943//
944//}
945//
946//
947//template < typename ITERATOR_TYPE >
948//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd32_character wd32ch) const
949//{
950//
951// string_base < ITERATOR_TYPE > ansistr;
952//
953// ansistr.append(wd32ch);
954//
955// return ansistr;
956//
957//}
958
959
960//template < typename ITERATOR_TYPE >
961//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_char_pointer psz) const
962//{
963//
964// auto scopedstr(*this);
965//
966// scopedstr += psz;
967//
968// return ::transfer(scopedstr);
969//
970//}
971//
972//
973//template < typename ITERATOR_TYPE >
974//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const ::wd16_character * pwsz) const
975//{
976//
977// auto scopedstr(*this);
978//
979// scopedstr += pwsz;
980//
981// return ::transfer(scopedstr);
982//
983//}
984//
985//
986//template < typename ITERATOR_TYPE >
987//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const ::wd32_character * pwsz) const
988//{
989//
990// auto scopedstr(*this);
991//
992// scopedstr += pwsz;
993//
994// return ::transfer(scopedstr);
995//
996//}
997
998
999//template < typename ITERATOR_TYPE >
1000//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_ansi_range ansiscopedstr) const
1001//{
1002//
1003// auto scopedstr(*this);
1004//
1005// scopedstr += ansiscopedstr;
1006//
1007// return ::transfer(scopedstr);
1008//
1009//}
1010//
1011//
1012//template < typename ITERATOR_TYPE >
1013//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_wd16_range scopedstr) const
1014//{
1015//
1016// auto scopedstr(*this);
1017//
1018// scopedstr += scopedstr;
1019//
1020// return ::transfer(scopedstr);
1021//
1022//}
1023//
1024//
1025//template < typename ITERATOR_TYPE >
1026//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const_wd32_range scopedstr) const
1027//{
1028//
1029// auto scopedstr(*this);
1030//
1031// scopedstr += scopedstr;
1032//
1033// return ::transfer(scopedstr);
1034//
1035//}
1036
1037
1038
1039//template < typename ITERATOR_TYPE >
1040//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(const inline_number_string & inlinenumberstring) const
1041//{
1042//
1043// auto scopedstr(*this);
1044//
1045// scopedstr.append(inlinenumberstring);
1046//
1047// return ::transfer(scopedstr);
1048//
1049//}
1050//
1051//
1052//template < typename ITERATOR_TYPE >
1053//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::ansi_character ansich) const
1054//{
1055//
1056// auto scopedstr(*this);
1057//
1058// scopedstr += ansich;
1059//
1060// return ::transfer(scopedstr);
1061//
1062//}
1063//
1064//
1065//template < typename ITERATOR_TYPE >
1066//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd16_character wd16ch) const
1067//{
1068//
1069// auto scopedstr(*this);
1070//
1071// ansistr += wd16ch;
1072//
1073// return ::transfer(scopedstr);
1074//
1075//}
1076//
1077//
1078//
1079//template < typename ITERATOR_TYPE >
1080//inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::operator +(::wd32_character wd32ch) const
1081//{
1082//
1083// auto scopedstr(*this);
1084//
1085// scopedstr += wd32ch;
1086//
1087// return ::transfer(scopedstr);
1088//
1089//}
1090//
1091
1092
1093//template < typename ITERATOR_TYPE >
1094//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const string_base & str)
1095//{
1096//
1097// NATURAL_POINTER::operator=(str);
1098//
1099// return *this;
1100//
1101//}
1102
1103
1104//template < typename ITERATOR_TYPE >
1105//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(string_base && scopedstr)
1106//{
1107//
1108// NATURAL_POINTER::operator=(::transfer(scopedstr));
1109//
1110// return *this;
1111//
1112//}
1113
1114
1115//template < typename ITERATOR_TYPE >
1116//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const ansi_string & strSrc)
1117//{
1118//
1119// return assign(*this, strSrc.begin());
1120//
1121//}
1122//
1123//
1124//template < typename ITERATOR_TYPE >
1125//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd16_string & strSrc)
1126//{
1127//
1128// return assign(*this, strSrc.begin());
1129//
1130//}
1131//
1132//
1133//template < typename ITERATOR_TYPE >
1134//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd32_string & strSrc)
1135//{
1136//
1137// return assign(*this, strSrc.begin());
1138//
1139//}
1140//
1141
1142
1143
1144
1145//template < typename ITERATOR_TYPE >
1146//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd16_string & widestrSrc, character_count count)
1147//{
1148//
1149// return assign(*this, widestrSrc.begin() + pos, count);
1150//
1151//}
1152//
1153//
1154//template < typename ITERATOR_TYPE >
1155//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const wd32_string & widestrSrc, character_count count)
1156//{
1157//
1158// return assign(*this, widestrSrc.begin() + pos, count);
1159//
1160//}
1161
1162//
1163//template < typename ITERATOR_TYPE >
1164//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const_char_pointer pszSrc)
1165//{
1166//
1167// return assign(*this, pszSrc);
1168//
1169//}
1170//
1171
1172
1173//template < typename ITERATOR_TYPE >
1174//template < prototype_character CHARACTER2 >
1175//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE > ::start_count_length(character_count & start, character_count & count, const CHARACTER2 * pszSource)
1176//{
1177//
1178// character_count len = -1;
1179//
1180// if (start < 0)
1181// {
1182//
1183// start = 0;
1184//
1185// }
1186//
1187// if (count < 0)
1188// {
1189//
1190// len = string_safe_length(scopedstrSource);
1191//
1192// count += (len - start) + 1;
1193//
1194// if (count < 0)
1195// {
1196//
1197// count = 0;
1198//
1199// }
1200//
1201// }
1202//
1203// if (len < 0)
1204// {
1205//
1206// len = string_safe_length(scopedstrSource, start + count);
1207//
1208// if (len < 0)
1209// {
1210//
1211// return start + count;
1212//
1213// }
1214//
1215// }
1216//
1217// if (count + start > len)
1218// {
1219//
1220// count = len - start;
1221//
1222// }
1223//
1224// return len;
1225//
1226//}
1227
1228
1229//template < typename ITERATOR_TYPE >
1230//inline void string_range < ITERATOR_TYPE >::start_count(character_count & start, character_count & count, character_count len)
1231//{
1232//
1233// if (start < 0)
1234// {
1235//
1236// start = 0;
1237//
1238// }
1239//
1240// if (count < 0)
1241// {
1242//
1243// count += (len - start) + 1;
1244//
1245// if (count < 0)
1246// {
1247//
1248// count = 0;
1249//
1250// }
1251//
1252// }
1253//
1254// if (count + start > len)
1255// {
1256//
1257// count = len - start;
1258//
1259// }
1260//
1261//}
1262
1263
1264//template < typename ITERATOR_TYPE >
1265//template < prototype_character CHARACTER2 >
1266//inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::assign(const CHARACTER2 * pszSource)
1267//{
1268//
1269// start_count_length(start, count, pszSource);
1270//
1271// return _assign(scopedstrSource, start, count);
1272//
1273//}
1274
1275
1276
1277
1278
1279template < typename ITERATOR_TYPE >
1280inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_left(character_count count) const
1281{
1282
1283 return { this->begin(), this->unichar_at(count) };
1284
1285}
1286
1287
1288
1289template < typename ITERATOR_TYPE >
1290inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iFirst) const
1291{
1292
1293 return { this->unichar_at(iFirst), this->end() };
1294
1295}
1296
1297
1298template < typename ITERATOR_TYPE >
1299inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::unichar_mid(character_count iStart, character_count iCount) const
1300{
1301
1302 return { this->unichar_at(iStart), this->unichar_at(iStart + iCount) };
1303
1304}
1305
1306
1307template < prototype_character CHARACTER >
1308inline bool operator>(const CHARACTER * psz, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1309{
1310
1311 return string_compare(scopedstr, string_safe_length(scopedstr), scopedstr.begin(), scopedstr.size()) > 0;
1312
1313}
1314
1315
1316template < prototype_character CHARACTER >
1317inline bool operator > (CHARACTER ch, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1318{
1319
1320 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) > 0;
1321
1322}
1323
1324
1325template < prototype_character CHARACTER >
1326inline bool operator > (::wide_character ch, const typename ::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1327{
1328
1329 return wide_string(ch) > scopedstr;
1330
1331}
1332
1333
1334template < prototype_character CHARACTER >
1335inline bool operator>(::i32 i, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1336{
1337
1338 return ::string_base<CHARACTER>(i) > scopedstr;
1339
1340}
1341
1342
1343template < prototype_character CHARACTER >
1344inline bool operator<(const CHARACTER * psz, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1345{
1346
1347 return string_compare(scopedstr, string_save_length(scopedstr), scopedstr.begin(), scopedstr.size()) < 0;
1348
1349}
1350
1351
1352template < prototype_character CHARACTER >
1353inline bool operator<(CHARACTER ch, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1354{
1355
1356 return string_compare(&ch, 1, scopedstr.begin(), scopedstr.size()) < 0;
1357
1358}
1359
1360
1361template < prototype_character CHARACTER >
1362inline bool operator<(::i32 i, const typename::GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr)
1363{
1364
1365 return ::string_base <CHARACTER>(i) < scopedstr;
1366
1367}
1368
1369
1370template < typename ITERATOR_TYPE >
1371inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::lower() const
1372{
1373
1374 return string_base < ITERATOR_TYPE >(*this).make_lower();
1375
1376}
1377
1378
1379template < typename ITERATOR_TYPE >
1380inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::upper() const
1381{
1382
1383 return string_base < ITERATOR_TYPE >(*this).make_upper();
1384
1385}
1386
1387
1388template < prototype_character CHARACTER >
1389inline const CHARACTER * FormatArgument(const typename GET_BLOCK_TYPE<CHARACTER>::TYPE & scopedstr) noexcept
1390{
1391
1392 return scopedstr.begin();
1393
1394}
1395
1396
1397//template < typename ITERATOR_TYPE >
1398//inline string_base < ITERATOR_TYPE >::string_base(const SCOPED_STRING & scopedstr) :
1399// string_base((const_char_pointer )scopedstr.data(), (character_count)scopedstr.size())
1400//{
1401//
1402//
1403//}
1404
1405
1406//template < typename ITERATOR_TYPE >
1407//inline string_base < ITERATOR_TYPE >::string_base(const ansi_string & ansistr)
1408//{
1409//
1410// assign(ansistr.begin());
1411//
1412//}
1413//
1414//
1415//template < typename ITERATOR_TYPE >
1416//inline string_base < ITERATOR_TYPE >::string_base(const wd16_string & wd16str)
1417//{
1418//
1419// assign(wd16str.begin());
1420//
1421//}
1422//
1423//
1424//template < typename ITERATOR_TYPE >
1425//inline string_base < ITERATOR_TYPE >::string_base(const wd32_string & wd32str)
1426//{
1427//
1428// assign(wd32str.begin());
1429//
1430//}
1431
1432
1433//template < typename ITERATOR_TYPE >
1434//inline string_base < ITERATOR_TYPE >::string_base(const simple_ansistring & ansistr) :
1435// string_base(ansistr.begin())
1436//{
1437//
1438//}
1439//
1440//
1441//template < typename ITERATOR_TYPE >
1442//inline string_base < ITERATOR_TYPE >::string_base(const simple_wd16string & wd16str) :
1443// string_base(wd16str.begin())
1444//{
1445//
1446//}
1447//
1448//
1449//template < typename ITERATOR_TYPE >
1450//inline string_base < ITERATOR_TYPE >::string_base(const simple_wd32string & wd32str) :
1451// string_base(wd32str.begin())
1452//{
1453//
1454//}
1455
1456
1457template < typename ITERATOR_TYPE >
1458template < prototype_array A_STRING_ARRAY >
1459bool const_string_range < ITERATOR_TYPE >::contains_any(const A_STRING_ARRAY & stra) const
1460{
1461
1462 for (auto & scopedstr : stra)
1463 {
1464
1465 if (contains(scopedstr))
1466 {
1467
1468 return true;
1469
1470 }
1471
1472 }
1473
1474 return false;
1475
1476}
1477
1478
1479template < typename ITERATOR_TYPE >
1480template < prototype_array A_STRING_ARRAY >
1481bool const_string_range < ITERATOR_TYPE >::contains_all(const A_STRING_ARRAY & stra) const
1482{
1483
1484 for (auto & scopedstr : stra)
1485 {
1486
1487 if (!contains(scopedstr))
1488 {
1489
1490 return false;
1491
1492 }
1493
1494 }
1495
1496 return true;
1497
1498}
1499
1500
1501
1502
1503template < typename ITERATOR_TYPE >
1504template < prototype_array A_STRING_ARRAY >
1505bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_at_least_one_of(const A_STRING_ARRAY & stra) const
1506{
1507
1508 for (auto & scopedstr : stra)
1509 {
1510
1511 if (case_insensitive_contains(scopedstr))
1512 {
1513
1514 return true;
1515
1516 }
1517
1518 }
1519
1520 return false;
1521
1522}
1523
1524
1525template < typename ITERATOR_TYPE >
1526template < prototype_array A_STRING_ARRAY >
1527bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains_all(const A_STRING_ARRAY & stra) const
1528{
1529
1530 for (auto & scopedstr : stra)
1531 {
1532
1533 if (!case_insensitive_contains(scopedstr))
1534 {
1535
1536 return false;
1537
1538 }
1539
1540 }
1541
1542 return true;
1543
1544}
1545
1546
1547template < typename ITERATOR_TYPE >
1548template < prototype_array A_STRING_ARRAY >
1549bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_at_least_one_of(const A_STRING_ARRAY & stra) const
1550{
1551
1552 for (auto & scopedstr : stra)
1553 {
1554
1555 if (unicode_case_insensitive_contains(scopedstr))
1556 {
1557
1558 return true;
1559
1560 }
1561
1562 }
1563
1564 return false;
1565
1566}
1567
1568
1569template < typename ITERATOR_TYPE >
1570template < prototype_array A_STRING_ARRAY >
1571bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains_all(const A_STRING_ARRAY & stra) const
1572{
1573
1574 for (auto & scopedstr : stra)
1575 {
1576
1577 if (!unicode_case_insensitive_contains(scopedstr))
1578 {
1579
1580 return false;
1581
1582 }
1583
1584 }
1585
1586 return true;
1587
1588}
1589
1590
1591
1592template < typename ITERATOR_TYPE >
1593string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::Tokenize(const SCOPED_STRING & scopedstrTokens, character_count & start) const
1594{
1595 ASSERT(start >= 0);
1596
1597 if (start < 0)
1598 throw_exception(error_bad_argument);
1599
1600 if (scopedstrTokens.is_empty())
1601 {
1602 if (start < this->size())
1603 {
1604 return(string_base < ITERATOR_TYPE >(this->begin() + start));
1605 }
1606 }
1607 else
1608 {
1609 const CHARACTER * pszPlace = this->begin() + start;
1610 const CHARACTER * pszEnd = this->begin() + this->size();
1611 if (pszPlace < pszEnd)
1612 {
1613 character_count nIncluding = string_skip_any_character_in(pszPlace,
1614 scopedstrTokens);
1615
1616 if ((pszPlace + nIncluding) < pszEnd)
1617 {
1618 pszPlace += nIncluding;
1619 character_count nExcluding = string_find_first_character_in(pszPlace, scopedstrTokens);
1620
1621 character_count iFrom = start + nIncluding;
1622 character_count nUntil = nExcluding;
1623 start = iFrom + nUntil + 1;
1624
1625 return this->substr(iFrom, nUntil);
1626
1627 }
1628
1629 }
1630
1631 }
1632
1633 // return is_empty string_base < ITERATOR_TYPE >, done tokenizing
1634 start = -1;
1635
1636 return(string_base < ITERATOR_TYPE >());
1637
1638}
1639
1640
1641
1642
1643template < typename ITERATOR_TYPE >
1644string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::intersection(const SCOPED_STRING & scopedstrFind) const
1645{
1646
1647 string_base < ITERATOR_TYPE > scopedstr;
1648
1649 for (character_count i = 0; i < this->size(); i++)
1650 {
1651
1652 auto ch = this->operator[](i);
1653
1654 if (scopedstrFind.contains(ch))
1655 {
1656
1657 scopedstr += ch;
1658
1659 }
1660
1661
1662 }
1663
1664 return scopedstr;
1665
1666}
1667
1668
1669template < typename ITERATOR_TYPE >
1670inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::concatenate_with_separator(const SCOPED_STRING & scopedstrSeparator, const SCOPED_STRING & scopedstr)
1671{
1672
1673 if (this->has_character())
1674 {
1675
1676 if (scopedstr.has_character())
1677 {
1678
1679 this->append(scopedstrSeparator + scopedstr);
1680
1681 }
1682
1683 }
1684 else if (scopedstr.has_character())
1685 {
1686
1687 this->assign(scopedstr);
1688
1689 }
1690
1691 return *this;
1692
1693}
1694
1695
1696
1697template < typename ITERATOR_TYPE >
1698inline void string_base < ITERATOR_TYPE >::get_string(CHARACTER * psz) const noexcept
1699{
1700
1701 string_count_copy(psz, this->begin(), this->length());
1702
1703}
1704
1705
1706template < typename ITERATOR_TYPE >
1707string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::release_buffer(character_count characterCount)
1708{
1709
1710 if (characterCount < 0)
1711 {
1712
1713 characterCount = string_safe_length(this->begin()) + characterCount + 1;
1714
1715 }
1716
1717 //this->NATURAL_POINTER::metadata()->set_character_count(characterCount);
1718
1719 this->m_end = this->m_begin + characterCount;
1720
1721 *(CHARACTER *)this->m_end = (CHARACTER) 0;
1722
1723 return *this;
1724
1725}
1726
1727
1728//template < typename ITERATOR_TYPE >
1729//inline character_count string_base < ITERATOR_TYPE >::storage_character_count() const { return this->NATURAL_POINTER::metadata()->storage_character_count(); }
1730
1731
1732// template < typename ITERATOR_TYPE >
1733// inline memsize string_base < ITERATOR_TYPE >::character_count_in_bytes() const { return this->size() * sizeof(CHARACTER); }
1734//
1735//
1736// template < typename ITERATOR_TYPE >
1737// inline memsize string_base < ITERATOR_TYPE >::null_terminated_character_count_in_bytes() const { return (this->size() +1)* sizeof(CHARACTER); }
1738
1739
1740template < typename ITERATOR_TYPE >
1741void string_base < ITERATOR_TYPE >::resize(character_count n, CHARACTER c)
1742{
1743
1744 character_count nOldSize = this->length();
1745
1746 if (n < nOldSize)
1747 {
1748
1749 this->truncate(n);
1750
1751 }
1752 else
1753 {
1754
1755 auto psz = this->get_buffer<true>(n);
1756
1757 flood_characters(psz + nOldSize, c, n - nOldSize);
1758
1759 this->release_buffer(n);
1760
1761 }
1762
1763}
1764
1765
1766template < typename ITERATOR_TYPE >
1767inline typename string_base < ITERATOR_TYPE >::this_iterator string_base < ITERATOR_TYPE >::truncate_on_find_character(CHARACTER ch)
1768{
1769
1770 auto p = this->find_first_character(ch);
1771
1772 if (::is_null(p))
1773 {
1774
1775 return nullptr;
1776
1777 }
1778
1779 return truncate(p);
1780
1781}
1782
1783
1784template < typename ITERATOR_TYPE >
1785inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::truncate(this_iterator p)
1786{
1787
1788 if(p <= this->begin())
1789 {
1790
1791 empty();
1792
1793 }
1794 else if(p < this->end())
1795 {
1796
1797 auto pbasedata = this->m_pbasedata;
1798
1799 if (pbasedata->base_data_is_shared())
1800 {
1801
1802 this->assign(this->m_begin, p);
1803
1804 }
1805 else
1806 {
1807
1808 auto characterCount = p - this->begin();
1809
1810 //pbasedata->set_character_count(characterCount);
1811
1812 this->m_end = this->m_begin + characterCount;
1813
1814 *(CHARACTER *)this->m_end = (CHARACTER) 0;
1815
1816 }
1817
1818 }
1819
1820 return this->end();
1821
1822}
1823
1824
1825template < typename ITERATOR_TYPE >
1826inline typename string_base < ITERATOR_TYPE >::this_iterator & string_base < ITERATOR_TYPE >::erase_beginning(this_iterator p)
1827{
1828
1829 //p = minimum_maximum(p, , size());
1830
1831 assign(p, this->m_end - p);
1832
1833 return this->m_begin;
1834
1835}
1836
1837
1838
1839template < typename ITERATOR_TYPE >
1840inline void string_base < ITERATOR_TYPE >::set_at(character_count iChar, CHARACTER ch)
1841{
1842
1843 defer_set_size<true>(maximum(this->size(), iChar + 1));
1844
1845 //auto p = this->NATURAL_POINTER::metadata();
1846
1847 //if (iChar >= p->character_count())
1848 //{
1849
1850 // throw ::exception(error_index_out_of_bounds);
1851
1852 //}
1853
1854 //if (p->base_data_is_shared())
1855 //{
1856
1857 // fork_string(maximum(p->character_count(), iChar + 1), true);
1858
1859 //}
1860
1861 ((CHARACTER *)this->m_begin)[iChar] = ch;
1862
1863}
1864
1865template < typename ITERATOR_TYPE >
1866bool const_string_range < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr) const
1867{
1868
1869 return ::is_set(find(scopedstr));
1870
1871}
1872
1873
1874template < typename ITERATOR_TYPE >
1875bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr) const
1876{
1877
1878 return ::is_set(case_insensitive_find(scopedstr));
1879
1880}
1881
1882
1883//template < typename ITERATOR_TYPE >
1884//bool string_base < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
1885//{
1886//
1887// auto pFind = find(scopedstr, start, count, ppszEnd);
1888//
1889// if (::is_null(pFind))
1890// {
1891//
1892// return false;
1893//
1894// }
1895//
1896// if (ppszBeg)
1897// {
1898//
1899// *ppszBeg = psz + iFind;
1900//
1901// }
1902//
1903// return true;
1904//
1905//}
1906//
1907//
1908//template < typename ITERATOR_TYPE >
1909//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
1910//{
1911//
1912// auto pFind = case_insensitive_find(scopedstr, start, count, ppszEnd);
1913//
1914// if (::is_null(pFind))
1915// {
1916//
1917// return false;
1918//
1919// }
1920//
1921// if (ppszBeg)
1922// {
1923//
1924// *ppszBeg = psz + iFind;
1925//
1926// }
1927//
1928// return true;
1929//
1930//}
1931
1932
1933//template < typename ITERATOR_TYPE >
1934//bool string_base < ITERATOR_TYPE >::contains(CHARACTER ch) const
1935//{
1936//
1937// return find(ch, start, count) >= 0;
1938//
1939//}
1940
1941
1942//template < typename ITERATOR_TYPE >
1943//bool string_base < ITERATOR_TYPE >::contains(::wide_character wch) const
1944//{
1945//
1946// return find_w(unicode_to_utf8(wch), start, count) >= 0;
1947//
1948//}
1949
1950
1951//template < typename ITERATOR_TYPE >
1952//bool string_base < ITERATOR_TYPE >::contains(::i32 i) const // utf8 CHARACTER index
1953//{
1954//
1955// return find_w(unicode_to_utf8(i), start, count) >= 0;
1956//
1957//}
1958
1959
1960//template < typename ITERATOR_TYPE >
1961//bool string_base < ITERATOR_TYPE >::contains(const CHARACTER* psz) const
1962//{
1963//
1964// return find(scopedstr, start, count) >= 0;
1965//
1966//}
1967
1968
1969//template < typename ITERATOR_TYPE >
1970//bool string_base < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr) const
1971//{
1972//
1973// return find(scopedstr, start, count) >= 0;
1974//
1975//}
1976
1977
1978//template < typename ITERATOR_TYPE >
1979//bool string_base < ITERATOR_TYPE >::contains(CHARACTER ch) const
1980//{
1981//
1982// return find(ch, start, count) >= 0;
1983//
1984//}
1985//
1986//
1987//template < typename ITERATOR_TYPE >
1988//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(CHARACTER ch) const
1989//{
1990//
1991// return case_insensitive_find(ch, start, count) >= 0;
1992//
1993//}
1994
1995//template < typename ITERATOR_TYPE >
1996//bool string_base < ITERATOR_TYPE >::contains(CHARACTER ch, const CHARACTER ** ppszBeg) const
1997//{
1998//
1999// auto find = this->find(ch, start, count);
2000//
2001// if (find < 0)
2002// {
2003//
2004// return false;
2005//
2006// }
2007//
2008// if (::is_set(ppszBeg))
2009// {
2010//
2011// *ppszBeg = this->begin() + find;
2012//
2013// }
2014//
2015// return true;
2016//
2017//}
2018
2019
2020//template < typename ITERATOR_TYPE >
2021//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(CHARACTER ch, const CHARACTER ** ppszBeg) const
2022//{
2023//
2024// auto find = case_insensitive_find(ch, start, count);
2025//
2026// if (find < 0)
2027// {
2028//
2029// return false;
2030//
2031// }
2032//
2033// if (::is_set(ppszBeg))
2034// {
2035//
2036// *ppszBeg = this->begin() + find;
2037//
2038// }
2039//
2040// return true;
2041//
2042//}
2043//
2044//
2045//
2046//template < typename ITERATOR_TYPE >
2047//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(::wide_character wch) const
2048//{
2049//
2050// return unicode_case_insensitive_find(unicode_to_utf8(wch), start, count) >= 0;
2051//
2052//}
2053
2054
2055//template < typename ITERATOR_TYPE >
2056//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(::i32 i) const// utf8 CHARACTER index
2057//{
2058//
2059// return unicode_case_insensitive_find(unicode_to_utf8(i), start, count) >= 0;
2060//
2061//}
2062
2063//
2064//template < typename ITERATOR_TYPE >
2065//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const CHARACTER* psz) const
2066//{
2067//
2068// return case_insensitive_find(scopedstr, start, count) >= 0;
2069//
2070//}
2071
2072
2073//template < typename ITERATOR_TYPE >
2074//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr) const
2075//{
2076//
2077// return case_insensitive_find(scopedstr, start, count) >= 0;
2078//
2079//}
2080
2081
2082template < typename ITERATOR_TYPE >
2083bool const_string_range < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2084{
2085
2086 auto pFind = this->find(scopedstr);
2087
2088 if (::is_null(pFind))
2089 {
2090
2091 return false;
2092
2093 }
2094
2095 if (::is_set(ppszBeg))
2096 {
2097
2098 *ppszBeg = pFind;
2099
2100 }
2101
2102 if (::is_set(ppszEnd))
2103 {
2104
2105 *ppszEnd = pFind + scopedstr.size();
2106
2107 }
2108
2109 return true;
2110
2111}
2112
2113
2114template < typename ITERATOR_TYPE >
2115bool const_string_range < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2116{
2117
2118 auto pFind = this->case_insensitive_find(scopedstr);
2119
2120 if (::is_null(pFind))
2121 {
2122
2123 return false;
2124
2125 }
2126
2127 if (::is_set(ppszBeg))
2128 {
2129
2130 *ppszBeg = pFind;
2131
2132 }
2133
2134 if (::is_set(ppszEnd))
2135 {
2136
2137 *ppszEnd = pFind + scopedstr.size();
2138
2139 }
2140
2141 return true;
2142
2143}
2144
2145
2146template < typename ITERATOR_TYPE >
2147bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2148{
2149
2150 auto pFind = this->unicode_case_insensitive_find(scopedstr);
2151
2152 if (::is_null(pFind))
2153 {
2154
2155 return false;
2156
2157 }
2158
2159 if (::is_set(ppszBeg))
2160 {
2161
2162 *ppszBeg = pFind;
2163
2164 }
2165
2166 if (::is_set(ppszEnd))
2167 {
2168
2169 *ppszEnd = pFind + scopedstr.size();
2170
2171 }
2172
2173 return true;
2174
2175}
2176
2177
2178//template < typename ITERATOR_TYPE >
2179//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(CHARACTER ch, const CHARACTER ** ppszBeg) const
2180//{
2181//
2182// auto find = unicode_case_insensitive_find(ch, start, count);
2183//
2184// if (find < 0)
2185// {
2186//
2187// return false;
2188//
2189// }
2190//
2191// if (::is_set(ppszBeg))
2192// {
2193//
2194// *ppszBeg = this->begin() + find;
2195//
2196// }
2197//
2198// return true;
2199//
2200//}
2201
2202//template < typename ITERATOR_TYPE >
2203//bool string_base < ITERATOR_TYPE >::contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2204//{
2205//
2206// auto find = this->find(scopedstr, start, count, ppszEnd);
2207//
2208// if (find < 0)
2209// {
2210//
2211// return false;
2212//
2213// }
2214//
2215// if (::is_set(ppszBeg))
2216// {
2217//
2218// *ppszBeg = this->begin() + find;
2219//
2220// }
2221//
2222// return true;
2223//
2224//}
2225
2226
2227//template < typename ITERATOR_TYPE >
2228//bool string_base < ITERATOR_TYPE >::case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2229//{
2230//
2231// auto find = case_insensitive_find(scopedstr, start, count, ppszEnd);
2232//
2233// if (find < 0)
2234// {
2235//
2236// return false;
2237//
2238// }
2239//
2240// if (::is_set(ppszBeg))
2241// {
2242//
2243// *ppszBeg = this->begin() + find;
2244//
2245// }
2246//
2247// return true;
2248//
2249//}
2250
2251
2252//template < typename ITERATOR_TYPE >
2253//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr, const CHARACTER ** ppszBeg, const CHARACTER ** ppszEnd) const
2254//{
2255//
2256// auto find = unicode_case_insensitive_find(scopedstr, start, count, ppszEnd);
2257//
2258// if (find < 0)
2259// {
2260//
2261// return false;
2262//
2263// }
2264//
2265// if (::is_set(ppszBeg))
2266// {
2267//
2268// *ppszBeg = this->begin() + find;
2269//
2270// }
2271//
2272// return true;
2273//
2274//}
2275
2276//template < typename ITERATOR_TYPE >
2277//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(CHARACTER wch) const
2278//{
2279//
2280// return unicode_case_insensitive_find(wch, start, count) >= 0;
2281//
2282//}
2283
2284//
2285//template < typename ITERATOR_TYPE >
2286//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(::i32 i) const// utf8 CHARACTER index
2287//{
2288//
2289// return unicode_case_insensitive_find(unicode_to_utf8(i), start, count) >= 0;
2290//
2291//}
2292
2293
2294template < typename ITERATOR_TYPE >
2295bool const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr) const
2296{
2297
2298 return ::is_set(unicode_case_insensitive_find(scopedstr));
2299
2300}
2301
2302
2303//template < typename ITERATOR_TYPE >
2304//bool string_base < ITERATOR_TYPE >::unicode_case_insensitive_contains(const SCOPED_STRING & scopedstr) const
2305//{
2306//
2307// return unicode_case_insensitive_find(scopedstr, start, count) >= 0;
2308//
2309//}
2310
2311
2312//template < typename ITERATOR_TYPE >
2313//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::erase(character_count start, character_count character_count)
2314//{
2315//
2316// if (start < 0)
2317// {
2318//
2319// character_count = 0;
2320//
2321// }
2322//
2323// if (character_count < 0)
2324// {
2325//
2326// character_count = this->size();
2327//
2328// }
2329//
2330// Delete(start, character_count);
2331//
2332// return *this;
2333//
2334//}
2335
2336
2337template < typename ITERATOR_TYPE >
2338string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::index_erase(character_count iIndex, character_count count)
2339{
2340
2341 character_count nLength = this->size();
2342
2343 if (iIndex < 0)
2344 {
2345
2346 iIndex = 0;
2347
2348 }
2349
2350 if (count < 0)
2351 {
2352
2353 count = nLength;
2354
2355 }
2356
2357 if (count + iIndex > nLength)
2358 {
2359
2360 count = nLength - iIndex;
2361
2362 }
2363
2364 if (count < 0)
2365 {
2366
2367 return *this;
2368
2369 }
2370
2371 if (count + iIndex > nLength)
2372 {
2373
2374 count = nLength - iIndex;
2375
2376 }
2377
2378 if (count > 0)
2379 {
2380
2381 character_count nNewLength = nLength - count;
2382
2383 character_count nCopy = nLength - (iIndex + count) + 1;
2384
2385 CHARACTER * pszBuffer = get_buffer<true>();
2386
2387 memory_transfer(pszBuffer + iIndex, pszBuffer + iIndex + count, (size_t)nCopy);
2388
2389 release_buffer(nNewLength);
2390
2391 }
2392
2393 return *this;
2394
2395}
2396
2397
2398template < typename ITERATOR_TYPE >
2399inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i, CHARACTER ch)
2400{
2401
2402 if (i < 0)
2403 {
2404
2405 i = 0;
2406
2407 }
2408
2409 if (i > this->size())
2410 {
2411
2412 i = this->size();
2413
2414 }
2415
2416 character_count nNewLength = this->size() + 1;
2417
2418 CHARACTER * pszBuffer = get_buffer<true>(nNewLength);
2419
2420 memory_transfer(pszBuffer + i + 1, pszBuffer + i, nNewLength - i);
2421
2422 pszBuffer[i] = ch;
2423
2424 release_buffer(nNewLength);
2425
2426 return nNewLength;
2427
2428}
2429
2430
2431template < typename ITERATOR_TYPE >
2432inline ::collection::count string_base < ITERATOR_TYPE >::insert(character_count i, const string_base & str)
2433{
2434
2435 if (i < 0)
2436 {
2437
2438 i = 0;
2439
2440 }
2441
2442 if (i > this->size())
2443 {
2444
2445 i = this->size();
2446
2447 }
2448
2449 character_count nInsertLength = str.size();
2450
2451 character_count nNewLength = this->size();
2452
2453 if (nInsertLength > 0)
2454 {
2455
2456 nNewLength += nInsertLength;
2457
2458 CHARACTER * pszBuffer = get_buffer<true>(nNewLength);
2459
2460 memory_transfer(pszBuffer + i + nInsertLength, pszBuffer + i, (nNewLength - i - nInsertLength + 1) * sizeof(CHARACTER));
2461
2462 memory_copy(pszBuffer + i, str.begin(), nInsertLength * sizeof(CHARACTER));
2463
2464 release_buffer(nNewLength);
2465
2466 }
2467
2468 return nNewLength;
2469
2470}
2471
2472
2473template < typename ITERATOR_TYPE >
2474inline ::collection::count string_base < ITERATOR_TYPE >::replace_with(CHARACTER charNew, CHARACTER charOld, character_count start)
2475{
2476
2477 character_count count = 0;
2478
2479 // ::i16-circuit the nop case
2480 if (charOld != charNew)
2481 {
2482 // otherwise modify each character that matches in the string_base < ITERATOR_TYPE >
2483 bool bCopied = false;
2484 CHARACTER * pszBuffer = const_cast<CHARACTER *>(this->begin() + start); // We don't actually write to pszBuffer until we've called get_buffer().
2485
2486 character_count nLength = this->size();
2487 character_count iChar = 0;
2488 while (iChar < nLength)
2489 {
2490 // replace instances of the specified character only
2491 if (pszBuffer[iChar] == charOld)
2492 {
2493 if (!bCopied)
2494 {
2495 bCopied = true;
2496 pszBuffer = get_buffer<true>(nLength);
2497 }
2498 pszBuffer[iChar] = charNew;
2499 count++;
2500 }
2501 iChar = character_count((pszBuffer + iChar + 1) - pszBuffer);
2502 }
2503 if (bCopied)
2504 {
2505 release_buffer(nLength);
2506 }
2507 }
2508
2509 return count;
2510}
2511
2512
2513
2514template < typename ITERATOR_TYPE >
2515//template < raw_pointer_castable < CHARACTER > PCHARNEW, raw_pointer_castable < CHARACTER > PCHAROLD >
2516::collection::count string_base < ITERATOR_TYPE >::replace_with_count(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start)
2517{
2518 // can't have is_empty or nullptr pszOld
2519
2520
2521 ::collection::count c = 0;
2522
2523 // nSourceLen is in XCHARs
2524 character_count nSourceLen = scopedstrOld.size();
2525 if (nSourceLen == 0)
2526 return(0);
2527 // nReplacementLen is in XCHARs
2528 character_count nReplacementLen = scopedstrNew.size();
2529
2530 // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
2531 character_count count = 0;
2532
2533 {
2534
2535 const CHARACTER * pszStart = this->begin() + start;
2536 // const CHARACTER * pszEnd = pszStart+this->size();
2537 const CHARACTER * pszTarget;
2538
2539 while ((pszTarget = string_find_string(pszStart, scopedstrOld)) != nullptr)
2540 {
2541
2542 count++;
2543
2544 pszStart = pszTarget + nSourceLen;
2545
2546 c++;
2547
2548 }
2549
2550 }
2551
2552 // if any changes were made, make them
2553 if (count > 0)
2554 {
2555 // if the buffer is too small, just
2556 // allocate a ___new buffer(slow but sure)
2557 character_count nOldLength = this->size();
2558 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
2559
2560 CHARACTER * pszBuffer = get_buffer<true>(maximum(nNewLength, nOldLength));
2561
2562 const CHARACTER * pszStart = pszBuffer + start;
2563 const CHARACTER * pszEnd = pszBuffer + nOldLength;
2564
2565 // loop again to actually do the work
2566 while (pszStart < pszEnd)
2567 {
2568
2569 CHARACTER * pszTarget;
2570
2571 while ((pszTarget = (CHARACTER *)string_find_string(pszStart, scopedstrOld)) != nullptr)
2572 {
2573
2574 character_count nBalance = nOldLength - character_count(pszTarget - pszBuffer + nSourceLen);
2575
2576 memory_transfer((void *)(pszTarget + nReplacementLen), pszTarget + nSourceLen, nBalance * sizeof(CHARACTER));
2577
2578 ::memory_copy((void *)pszTarget, scopedstrNew, nReplacementLen * sizeof(CHARACTER));
2579
2580 pszStart = pszTarget + nReplacementLen;
2581
2582 pszTarget[nReplacementLen + nBalance] = 0;
2583
2584 nOldLength += (nReplacementLen - nSourceLen);
2585
2586 }
2587
2588 pszStart += string_safe_length(pszStart) + 1;
2589
2590 }
2591
2592 ASSERT(pszBuffer[nNewLength] == 0);
2593
2594 release_buffer(nNewLength);
2595
2596 }
2597
2598 return c;
2599
2600}
2601
2602
2603template < typename ITERATOR_TYPE >
2604//template < raw_pointer_castable < CHARACTER > PCHARNEW, raw_pointer_castable < CHARACTER > PCHAROLD >
2605::collection::count string_base < ITERATOR_TYPE >::replace_with_ci_count(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start)
2606{
2607 // can't have is_empty or nullptr pszOld
2608
2609
2610 ::collection::count c = 0;
2611
2612 // nSourceLen is in XCHARs
2613 character_count nSourceLen = scopedstrOld.size();
2614 if (nSourceLen == 0)
2615 return(0);
2616 // nReplacementLen is in XCHARs
2617 character_count nReplacementLen = scopedstrOld.size();
2618
2619 // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
2620 character_count count = 0;
2621 {
2622 const CHARACTER * pszStart = this->begin() + start;
2623 // const CHARACTER * pszEnd = pszStart+this->size();
2624 const CHARACTER * pszTarget;
2625 while ((pszTarget = case_insensitive_string_find_string(pszStart, scopedstrOld)) != nullptr)
2626 {
2627 count++;
2628 pszStart = pszTarget + nSourceLen;
2629 c++;
2630 }
2631 }
2632
2633 // if any changes were made, make them
2634 if (count > 0)
2635 {
2636 // if the buffer is too small, just
2637 // allocate a ___new buffer(slow but sure)
2638 character_count nOldLength = this->size();
2639 character_count nNewLength = nOldLength + (nReplacementLen - nSourceLen) * count;
2640
2641 CHARACTER * pszBuffer = get_buffer<true>(maximum(nNewLength, nOldLength));
2642
2643 CHARACTER * pszStart = pszBuffer + start;
2644 CHARACTER * pszEnd = pszBuffer + nOldLength;
2645
2646 // loop again to actually do the work
2647 while (pszStart < pszEnd)
2648 {
2649
2650 CHARACTER * pszTarget;
2651
2652 while ((pszTarget = (CHARACTER *)case_insensitive_string_find_string(pszStart, scopedstrOld)) != nullptr)
2653 {
2654
2655 character_count nBalance = nOldLength - character_count(pszTarget - pszBuffer + nSourceLen);
2656
2657 memory_transfer(pszTarget + nReplacementLen, pszTarget + nSourceLen, nBalance * sizeof(CHARACTER));
2658
2659 ::memory_copy(pszTarget, scopedstrNew, nReplacementLen * sizeof(CHARACTER));
2660
2661 pszStart = pszTarget + nReplacementLen;
2662
2663 pszTarget[nReplacementLen + nBalance] = 0;
2664
2665 nOldLength += (nReplacementLen - nSourceLen);
2666
2667 }
2668
2669 pszStart += string_safe_length(pszStart) + 1;
2670
2671 }
2672
2673 ASSERT(pszBuffer[nNewLength] == 0);
2674
2675 release_buffer(nNewLength);
2676
2677 }
2678
2679 return c;
2680
2681}
2682
2683
2684template < typename ITERATOR_TYPE >
2685string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::replace(const_iterator pszStart, const_iterator pszEnd, const SCOPED_STRING & scopedstr)
2686{
2687
2688 auto finalLen = this->size() + scopedstr.size() - (pszEnd - pszStart);
2689
2690 string str;
2691
2692 auto psz = str.get_buffer(finalLen);
2693
2694 memory_copy(psz, this->begin(), pszStart - this->begin());
2695
2696 memory_copy(psz + (pszStart - this->begin()), scopedstr.begin(), scopedstr.size());
2697
2698 memory_copy(psz + (pszStart - this->begin()) + scopedstr.size(), pszEnd, this->end() - pszEnd);
2699
2700 str.release_buffer(finalLen);
2701
2702 *this = ::transfer(str);
2703
2704 return *this;
2705
2706}
2707
2708
2709template < typename ITERATOR_TYPE >
2710inline ::collection::count string_base < ITERATOR_TYPE >::erase_character(CHARACTER chRemove)
2711{
2712
2713 character_count nLength = this->size();
2714
2715 CHARACTER * pszBuffer = get_buffer<true>(nLength);
2716
2717 CHARACTER * pszSource = pszBuffer;
2718
2719 CHARACTER * pszDest = pszBuffer;
2720
2721 CHARACTER * pszEnd = pszBuffer + nLength;
2722
2723 while (pszSource < pszEnd)
2724 {
2725 CHARACTER * pszNewSource = pszSource + 1;
2726 if (*pszSource != chRemove)
2727 {
2728 // copy the source to the destination. Remember to copy all bytes of an MBCS character
2729 // copy the source to the destination. Remember to copy all bytes of an MBCS character
2730 size_t NewSourceGap = (pszNewSource - pszSource);
2731 CHARACTER * pszNewDest = pszDest + NewSourceGap;
2732 size_t i = 0;
2733 for (i = 0; pszDest != pszNewDest && i < NewSourceGap; i++)
2734 {
2735 *pszDest = *pszSource;
2736 pszSource++;
2737 pszDest++;
2738 }
2739 }
2740 pszSource = pszNewSource;
2742 *pszDest = 0;
2743 character_count count = character_count(pszSource - pszDest);
2744 release_buffer(nLength - count);
2745
2746 return(count);
2747
2748}
2749
2750
2751template < typename ITERATOR_TYPE >
2752inline ::collection::count string_base < ITERATOR_TYPE >::erase_any_character_in(const SCOPED_STRING & scopedstrCharacters)
2753{
2754
2755 character_count nLength = this->size();
2756
2757 CHARACTER * pszBuffer = get_buffer<true>(nLength);
2758
2759 CHARACTER * pszSource = pszBuffer;
2760
2761 CHARACTER * pszDest = pszBuffer;
2762
2763 CHARACTER * pszEnd = pszBuffer + nLength;
2764
2765 while (pszSource < pszEnd)
2766 {
2767 CHARACTER * pszNewSource = pszSource + 1;
2768 if (!scopedstrCharacters.contains(*pszSource))
2769 {
2770 // copy the source to the destination. Remember to copy all bytes of an MBCS character
2771 // copy the source to the destination. Remember to copy all bytes of an MBCS character
2772 size_t NewSourceGap = (pszNewSource - pszSource);
2773 CHARACTER * pszNewDest = pszDest + NewSourceGap;
2774 size_t i = 0;
2775 for (i = 0; pszDest != pszNewDest && i < NewSourceGap; i++)
2776 {
2777 *pszDest = *pszSource;
2778 pszSource++;
2779 pszDest++;
2780 }
2781 }
2782 pszSource = pszNewSource;
2783 }
2784 *pszDest = 0;
2785 character_count count = character_count(pszSource - pszDest);
2786 release_buffer(nLength - count);
2787
2788 return(count);
2789
2790
2791}
2792
2793// find the first occurrence of character 'ch', starting at character_count 'start'
2794template < typename ITERATOR_TYPE >
2795inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::find(CHARACTER ch) const RELEASENOTHROW
2796{
2797
2798 return this->find_first(ch);
2799
2800}
2801
2802
2803// find the first occurrence of character 'ch', starting at character_count 'start'
2804template < typename ITERATOR_TYPE >
2805inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::case_insensitive_find(CHARACTER ch) const RELEASENOTHROW
2806{
2807 // start is in XCHARs
2808 //ASSERT(start >= 0);
2809
2810 // nLength is in XCHARs
2811 //character_count nLength = this->size();
2812// if (start < 0 || start >= nLength)
2813// {
2814// return(-1);
2815// }
2816
2817//if(nLength <= 0)
2818//{
2819//
2820// return -1;
2821//
2822//}
2823//
2824// if (count < 0)
2825// count = nLength;
2826//
2827// if (count + start > nLength)
2828// count = nLength - start;
2829//
2830// if (count < 0)
2831// return -1;
2832
2833 auto psz = this->begin();
2834
2835 while(psz < this->end())
2836 {
2837
2838 if (character_tolower(*psz) == character_tolower(ch))
2839 {
2840
2841 return psz;
2842
2843 }
2844
2845 psz++;
2846
2847 }
2848
2849 return nullptr;
2850
2851}
2852
2853
2854
2855template < typename ITERATOR_TYPE >
2856inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::find_first(CHARACTER ch, ::character_count start) const RELEASENOTHROW
2857{
2858
2859 return ::string_find_character(this->begin() + start, this->end(), ch);
2860
2861}
2862
2863
2864
2865// find the first occurrence of string_base < ITERATOR_TYPE > 'scopedstr', starting at character_count 'start'
2866template < typename ITERATOR_TYPE >
2867inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2868{
2869
2870 const_iterator p;
2871
2872 auto rangeScope = *this;
2873
2874 if (this->_initialize_find(p, scopedstr, rangeScope))
2875 {
2876
2877 return p;
2878
2879 }
2880
2881 auto psz = (const CHARACTER * ) p;
2882
2883 auto pszBlock = (const CHARACTER * ) scopedstr.begin();
2884
2885 auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
2886
2887 for (; psz < rangeScope.m_end; psz++)
2888 {
2889
2890 auto psz2 = psz;
2891
2892 auto pszBlock2 = pszBlock;
2893
2894 ::i32 len1;
2895
2896 ::i32 len2;
2897
2898 do
2899 {
2900
2901 if (unicode_index_length(psz2, len1) != unicode_index_length(pszBlock2, len2))
2902 {
2903
2904 break;
2905
2906 }
2907
2908 psz2 += len1;
2909
2910 pszBlock2 += len2;
2911
2912 }
2913 while (pszBlock2 < pszBlockEnd);
2914
2915 if (pszBlock2 >= pszBlockEnd)
2916 {
2917
2918 //if (ppszTail)
2919 //{
2920
2921 // *ppszTail = pszBlock2;
2922
2923 //}
2924
2925 return psz;
2926
2927 }
2928
2929 psz = ::unicode_next(psz);
2930
2931 }
2932
2933 return nullptr;
2934
2935}
2936
2937
2938// find the first occurrence of string_base < ITERATOR_TYPE > 'scopedstr', starting at character_count 'start'
2939template < typename ITERATOR_TYPE >
2940inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
2941{
2942
2943 const_iterator p;
2944
2945 auto rangeScope = *this;
2946
2947 if (this->_initialize_find(p, scopedstr, rangeScope))
2948 {
2949
2950 return p;
2951
2952 }
2953
2954 auto psz = (const CHARACTER *)p;
2955
2956// auto pszBlock = (const CHARACTER *)scopedstr.begin();
2957//
2958// auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
2959
2960 for (; psz < rangeScope.m_end; psz++)
2961 {
2962
2963 bool bFound = true;
2964
2965 const CHARACTER * psz2 = psz;
2966
2967 const CHARACTER * pszSub2 = scopedstr;
2968
2969 ::i32 len1;
2970
2971 ::i32 len2;
2972
2973 while (*psz2 != '\0' && *pszSub2 != '\0')
2974 {
2975
2976 if (unicode_to_lower_case(unicode_index_length(psz2, len1)) !=
2977 unicode_to_lower_case(unicode_index_length(pszSub2, len2)))
2978 {
2979
2980 bFound = false;
2981
2982 break;
2983
2984 }
2985
2986 psz2 += len1;
2987
2988 psz2 += len2;
2989
2990 }
2991
2992 if (bFound)
2993 {
2994
2995 if (*pszSub2 == '\0')
2996 {
2997
2998 /* if (ppszTail)
2999 {
3000
3001 *ppszTail = psz2;
3002
3003 }*/
3004
3005 return psz;
3006
3007 }
3008 else
3009 {
3010
3011 return nullptr;
3012
3013 }
3014
3015 }
3016
3017 //psz++;
3018
3019 }
3020
3021 return nullptr;
3022
3023}
3024
3025
3026//template < typename ITERATOR_TYPE >
3027//inline typename string_range < ITERATOR_TYPE >::const_iterator string_range < ITERATOR_TYPE >::rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
3028//{
3029//
3030// return rear_find(scopedstr, ::comparison::comparison < CHARACTER >());
3031//
3032//}
3033
3034
3035template < typename ITERATOR_TYPE >
3036string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator += (const SCOPED_STRING & scopedstr)
3037{
3038
3039 append(scopedstr);
3040
3041 return *this;
3042
3043}
3044
3045
3046inline string & operator <<(string & str, const_char_pointer psz)
3047{
3048
3049 str += psz;
3050
3051 return str;
3052
3053}
3054
3055
3056template < prototype_integral INTEGRAL >
3057inline string & operator <<(string & str, INTEGRAL i)
3058{
3059
3060 str += ::as_string(i);
3061
3062 return str;
3063
3064}
3065
3066
3067template < typename ITERATOR_TYPE >
3068inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
3069{
3070
3071 auto psz = (const CHARACTER *)this->begin();
3072
3073 auto pszEnd = (const CHARACTER *)this->end();
3074
3075 pszEnd = unicode_prior(pszEnd, psz);
3076
3077 auto pszBlock = (const CHARACTER *)scopedstr.begin();
3078
3079 auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
3080
3081 pszBlockEnd = unicode_prior(pszBlockEnd, pszBlock);
3082
3083 if (::is_null(pszBlockEnd))
3084 {
3085
3086 return pszEnd;
3087
3088 }
3089
3090 while(::is_set(pszEnd))
3091 {
3092
3093 //bool bFound = true;
3094
3095 const CHARACTER * pszSub2 = pszBlockEnd;
3096
3097 const CHARACTER * psz2 = pszEnd;
3098
3099 while (true)
3100 {
3101
3102 if (unicode_index(pszBlockEnd) != unicode_index(psz2))
3103 {
3104
3105 break;
3106
3107 }
3108
3109 pszSub2 = (const CHARACTER *)unicode_prior(pszSub2, pszBlock);
3110
3111 if (::is_null(pszSub2))
3112 {
3113
3114 // End of searching block parsing reached.
3115 // Every unicode character so far is identical.
3116 // Found matching string.
3117
3118 return psz;
3119
3120 }
3121
3122 psz2 = (const CHARACTER *)unicode_prior(psz2, psz);
3123
3124 if (is_null(psz2))
3125 {
3126
3127 // Premature end of searched string
3128 // Didn't find matching block.
3129 // Return nullptr (not found).
3130
3131 return nullptr;
3132
3133 }
3134
3135 }
3136
3137 pszEnd = (const CHARACTER *)unicode_prior(pszEnd, psz);
3138
3139 }
3140
3141 // End of searched string
3142 // Didn't find matching block.
3143 // Return nullptr (not found).
3144
3145 return nullptr;
3146
3147}
3148
3149
3150template < typename ITERATOR_TYPE >
3151inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unicode_case_insensitive_rear_find(const SCOPED_STRING & scopedstr) const RELEASENOTHROW
3152{
3153
3154 auto psz = (const CHARACTER *)this->begin();
3155
3156 auto pszEnd = (const CHARACTER *)this->end();
3157
3158 pszEnd = unicode_prior(pszEnd, psz);
3159
3160 auto pszBlock = (const CHARACTER *)scopedstr.begin();
3161
3162 auto pszBlockEnd = (const CHARACTER *)scopedstr.end();
3163
3164 pszBlockEnd = unicode_prior(pszBlockEnd, pszBlock);
3165
3166 if (::is_null(pszBlockEnd))
3167 {
3168
3169 return pszEnd;
3170
3171 }
3172
3173 while (::is_set(pszEnd))
3174 {
3175
3176 //bool bFound = true;
3177
3178 const CHARACTER * pszSub2 = pszBlockEnd;
3179
3180 const CHARACTER * psz2 = pszEnd;
3181
3182 while (true)
3183 {
3184
3185 if (unicode_to_lower_case(unicode_index(pszBlockEnd)) != unicode_to_lower_case(unicode_index(psz2)))
3186 {
3187
3188 break;
3189
3190 }
3191
3192 pszSub2 = (const CHARACTER *)unicode_prior(pszSub2, pszBlock);
3193
3194 if (::is_null(pszSub2))
3195 {
3196
3197 // End of searching block parsing reached.
3198 // Every unicode character so far is case-insensitive equivalent.
3199 // Found matching string.
3200
3201 return psz;
3202
3203 }
3204
3205 psz2 = (const CHARACTER *)unicode_prior(psz2, psz);
3206
3207 if (is_null(psz2))
3208 {
3209
3210 // Premature end of searched string
3211 // Didn't find matching block.
3212 // Return nullptr (not found).
3213
3214 return nullptr;
3215
3216 }
3217
3218 }
3219
3220 pszEnd = (const CHARACTER *)unicode_prior(pszEnd, psz);
3221
3222 }
3223
3224 // End of searched string
3225 // Didn't find matching block.
3226 // Return nullptr (not found).
3227
3228 return nullptr;
3229
3230}
3231
3232
3233template < typename ITERATOR_TYPE >
3234typename const_string_range < ITERATOR_TYPE >::CHARACTER const_string_range < ITERATOR_TYPE >::last_char(character_count count) const
3235{
3236
3237 return *(this->end() + count);
3238}
3239
3240
3241
3242// Convert the string_base < ITERATOR_TYPE > to uppercase
3243template < typename ITERATOR_TYPE >
3244string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_upper()
3245{
3246 character_count nLength = this->size();
3247 CHARACTER * pszBuffer = get_buffer<true>(nLength);
3248 string_uppercase(pszBuffer, nLength + 1);
3249 release_buffer(nLength);
3250
3251 return *this;
3252}
3253
3254// Convert the string_base < ITERATOR_TYPE > to lowercase
3255template < typename ITERATOR_TYPE >
3256string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::make_lower()
3257{
3258 character_count nLength = this->size();
3259 CHARACTER * pszBuffer = get_buffer<true>(nLength);
3260 string_lowercase(pszBuffer, nLength + 1);
3261 release_buffer(nLength);
3262
3263 return *this;
3264}
3265
3266// Reverse the string_base < ITERATOR_TYPE >
3267template < typename ITERATOR_TYPE >
3268string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::MakeReverse()
3269{
3270 character_count nLength = this->size();
3271 CHARACTER * pszBuffer = get_buffer<true>(nLength);
3272 string_reverse(pszBuffer);
3273 release_buffer(nLength);
3274
3275 return *this;
3276}
3277
3278// trimming
3279
3280// erase all trailing whitespace
3281template < typename ITERATOR_TYPE >
3282string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right()
3283{
3284
3285 return trim_right(" \t\r\n");
3286
3287
3288 //const CHARACTER * pszLast = nullptr;
3289 //const CHARACTER * pszMax = this->begin() + this->size();
3290 //auto psz = pszMax;
3291
3292 //if (scopedstr != nullptr)
3293 //{
3294
3295 // while (true)
3296 // {
3297
3298 // psz = unicode_prior(scopedstr, this->begin());
3299
3300 // if (scopedstr < this->begin())
3301 // {
3302
3303 // break;
3304
3305 // }
3306
3307 // if (!unicode_is_whitespace(scopedstr))
3308 // {
3309
3310 // pszLast = unicode_next(scopedstr);
3311
3312 // break;
3313
3314 // }
3315
3316 // }
3317
3318 //}
3319
3320 //if (scopedstrLast != nullptr && pszLast < pszMax)
3321 //{
3322
3323 // // truncate at trailing space start
3324
3325 // character_count iLast = character_count(scopedstrLast - this->begin());
3326
3327 // truncate(iLast);
3328
3329 //}
3330
3331 //return *this;
3332
3333}
3334
3335// erase all leading whitespace
3336template < typename ITERATOR_TYPE >
3337string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left()
3338{
3339 // find first non-space character
3340
3341 return trim_left(" \t\r\n");
3342
3343 //auto i = skip_whitespace();
3344
3345 //if (i > 0)
3346 //{
3347
3348 // erase_beginning(i);
3349
3350 //}
3351
3352 //return *this;
3353
3355
3357
3360
3362
3364
3367
3370
3372
3376
3378
3380
3381
3383
3385
3386
3391
3393
3395
3397
3399
3401
3403
3405}
3406
3407// erase all leading and trailing whitespace
3408template < typename ITERATOR_TYPE >
3409string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim()
3410{
3411 return(trim_right().trim_left());
3412}
3413
3414// erase all leading and trailing occurrences of character 'chTarget'
3415template < typename ITERATOR_TYPE >
3416string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(CHARACTER chTarget)
3417{
3418 return(trim_right(chTarget).trim_left(chTarget));
3419}
3420
3421// erase all leading and trailing occurrences of any of the characters in the string_base < ITERATOR_TYPE > 'pszTargets'
3422template < typename ITERATOR_TYPE >
3423string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim(const SCOPED_STRING & scopedstrTargets)
3424{
3425 return trim_right(scopedstrTargets).trim_left(scopedstrTargets);
3426}
3427
3428// trimming anything (either side)
3429
3430// erase all trailing occurrences of character 'chTarget'
3431template < typename ITERATOR_TYPE >
3432string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(CHARACTER chTarget)
3433{
3434
3435 auto iterator = this->rear_skip(chTarget);
3436
3437 if (iterator)
3438 {
3439
3440 truncate(iterator);
3441
3442 }
3443
3444 return *this;
3445
3448
3449 //auto psz = this->begin();
3450 //const CHARACTER * pszLast = nullptr;
3451
3452 //while (*psz != 0)
3453 //{
3454 // if (*psz == chTarget)
3455 // {
3456 // if (scopedstrLast == nullptr)
3457 // {
3458 // pszLast = psz;
3459 // }
3460 // }
3461 // else
3462 // {
3463 // pszLast = nullptr;
3464 // }
3465
3466 // unicode_increment(psz);
3467
3468 //}
3469
3470 //if (scopedstrLast != nullptr)
3471 //{
3472 // // truncate at left-most matching character
3473 // character_count iLast = character_count(scopedstrLast - this->begin());
3474 // truncate(iLast);
3475 //}
3476
3477 //return *this;
3478
3479}
3480
3481
3482// erase all trailing occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
3483template < typename ITERATOR_TYPE >
3484string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_right(const SCOPED_STRING & scopedstrCharacters)
3485//template < pointer_castable < CHARACTER > PCHAR>
3486//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::trim_right(PCHAR szTargets)
3487{
3488
3489 auto p = this->rear_skip_any_character_in(scopedstrCharacters);
3490
3491 if (p < this->end())
3492 {
3493
3494 truncate(p);
3495
3496 }
3497
3498 return *this;
3499
3500 //auto pszTargets = scopedstrzTargets.begin();
3501
3503 //if ((scopedstrTargets == nullptr) || (*pszTargets == 0))
3504 //{
3505 // return *this;
3506 //}
3507
3510
3511 //auto psz = this->begin();
3512 //const CHARACTER * pszStart = psz;
3513 //const CHARACTER * pszLast = nullptr;
3514
3515 //while (!::is_null(scopedstr, 1024) && *psz != 0)
3516 //{
3517 // if (string_find_char(scopedstrTargets, *psz) != nullptr)
3518 // {
3519 // if (scopedstrLast == nullptr)
3520 // {
3521 // pszLast = psz;
3522 // }
3523 // }
3524 // else
3525 // {
3526 // pszLast = nullptr;
3527 // }
3528
3529 // unicode_increment(psz);
3530
3531 //}
3532
3533 //if (scopedstrLast != nullptr)
3534 //{
3535 // // truncate at left-most matching character
3536 // character_count iLast = character_count(scopedstrLast - pszStart);
3537 // truncate(iLast);
3538 //}
3539
3540 //return *this;
3541
3542}
3543
3544
3545// erase all leading occurrences of character 'chTarget'
3546template < typename ITERATOR_TYPE >
3547string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(CHARACTER chTarget)
3548{
3549
3550 auto p = this->skip(chTarget);
3551
3552 if (::is_set(p) && p > this->begin())
3553 {
3554
3555 erase_beginning(p);
3556
3557 }
3558
3560 //auto psz = this->begin();
3561
3562 //while (chTarget == *psz)
3563 //{
3564
3565 // unicode_increment(psz);
3566
3567 //}
3568
3569 //if (scopedstr != this->begin())
3570 //{
3571 // // fix up begin and length
3572 // character_count iFirst = character_count(scopedstr - this->begin());
3573 // CHARACTER * pszBuffer = get_buffer<true>(size());
3574 // psz = pszBuffer + iFirst;
3575 // character_count nDataLength = this->size() - iFirst;
3576 // memory_transfer(scopedstrBuffer, psz, (nDataLength + 1) * sizeof(CHARACTER));
3577 // release_buffer(nDataLength);
3578 //}
3579
3580 return *this;
3581
3582}
3583
3584
3585// erase all leading occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
3586template < typename ITERATOR_TYPE >
3587string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::trim_left(const SCOPED_STRING & scopedstrCharacters)
3588//template < pointer_castable < CHARACTER > PCHAR >
3589//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::trim_left(PCHAR szTargets)
3590{
3591
3592 auto p = this->skip_any_character_in(scopedstrCharacters);
3593
3594 if (p > this->begin())
3595 {
3596
3597 this->erase_beginning(p);
3598
3599 }
3600
3601 return *this;
3602
3603 //const CHARACTER * pszTargets = szTargets;
3604
3606 //if ((scopedstrTargets == nullptr) || (*pszTargets == 0))
3607 //{
3608 // return *this;
3609 //}
3610
3611 //auto psz = this->begin();
3612 //while ((*psz != 0) && (string_find_char(scopedstrTargets, *psz) != nullptr))
3613 //{
3614 // unicode_increment(psz);
3615 //}
3616
3617 //if (scopedstr != this->begin())
3618 //{
3619 // // fix up begin and length
3620 // character_count iFirst = character_count(scopedstr - this->begin());
3621 // CHARACTER * pszBuffer = get_buffer<true>(size());
3622 // psz = pszBuffer + iFirst;
3623 // character_count nDataLength = this->size() - iFirst;
3624 // memory_transfer(scopedstrBuffer, psz, (nDataLength + 1) * sizeof(CHARACTER));
3625 // release_buffer(nDataLength);
3626 //}
3627
3628 //return *this;
3629}
3630
3631
3632// erase all trailing whitespace
3633template < typename ITERATOR_TYPE >
3634string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed() const
3635{
3636
3637 string_base < ITERATOR_TYPE > scopedstr(*this);
3638
3639 scopedstr.trim_right();
3640
3641 return scopedstr;
3642
3643}
3644
3645
3646// erase all leading whitespace
3647template < typename ITERATOR_TYPE >
3648string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed() const
3649{
3650
3651 string_base < ITERATOR_TYPE > scopedstr(*this);
3652
3653 scopedstr.trim_left();
3654
3655 return scopedstr;
3656
3657}
3658
3659
3660// erase all leading and trailing whitespace
3661template < typename ITERATOR_TYPE >
3662string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed() const
3663{
3664
3665 string_base < ITERATOR_TYPE > scopedstr(*this);
3666
3667 scopedstr.trim();
3668
3669 return scopedstr;
3670
3671}
3672
3673
3674// erase all leading and trailing occurrences of character 'chTarget'
3675template < typename ITERATOR_TYPE >
3676string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(CHARACTER chTarget) const
3677{
3678
3679 string_base < ITERATOR_TYPE > scopedstr(*this);
3680
3681 scopedstr.trim(chTarget);
3682
3683 return scopedstr;
3684
3685}
3686
3687
3688// erase all leading and trailing occurrences of any of the characters in the string_base < ITERATOR_TYPE > 'pszTargets'
3689template < typename ITERATOR_TYPE >
3690string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::trimmed(const SCOPED_STRING & scopedstrCharacters) const
3691{
3692
3693 auto scopedstr(*this);
3694
3695 scopedstr.trim(scopedstrCharacters);
3696
3697 return ::transfer(scopedstr);
3698
3699}
3700
3701
3702// trimming anything (either side)
3703
3704// erase all trailing occurrences of character 'chTarget'
3705template < typename ITERATOR_TYPE >
3706string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(CHARACTER chTarget) const
3707{
3708
3709 auto scopedstr(*this);
3710
3711 scopedstr.trim_right(chTarget);
3712
3713 return ::transfer(scopedstr);
3714
3715}
3716
3717
3718// erase all trailing occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
3719template < typename ITERATOR_TYPE >
3720string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::right_trimmed(const SCOPED_STRING & scopedstrCharacters) const
3721{
3722
3723 auto scopedstr(*this);
3724
3725 scopedstr.trim_right(scopedstrCharacters);
3726
3727 return ::transfer(scopedstr);
3728
3729}
3730
3731
3732// erase all leading occurrences of character 'chTarget'
3733template < typename ITERATOR_TYPE >
3734string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(CHARACTER chTarget) const
3735{
3736
3737 string_base < ITERATOR_TYPE > scopedstr(*this);
3738
3739 scopedstr.trim_left(chTarget);
3740
3741 return scopedstr;
3742
3743}
3744
3745
3746// erase all leading occurrences of any of the characters in string_base < ITERATOR_TYPE > 'pszTargets'
3747template < typename ITERATOR_TYPE >
3748string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::left_trimmed(const SCOPED_STRING & scopedstrCharacters) const
3749{
3750
3751 auto scopedstr(*this);
3752
3753 scopedstr.trim_left(scopedstrCharacters);
3754
3755 return ::transfer(scopedstr);
3756
3757}
3758
3759
3760template < typename ITERATOR_TYPE >
3761const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(character_count start) const
3762{
3763
3764 return subrange(start, -1);
3765
3766}
3767
3768
3769template < typename ITERATOR_TYPE >
3770template < prototype_integral START, prototype_integral COUNT >
3771const_string_range < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE >::subrange(START start, COUNT count) const
3772{
3773
3774 character_count length = this->size();
3775
3776 if (start < 0)
3777 {
3778
3779 start = 0;
3780
3781 }
3782 else if ((::character_count)start >= length)
3783 {
3784
3785 return {};
3786
3787 }
3788
3789 character_count end;
3790
3791 if (count < 0)
3792 {
3793
3794 end = length + count + 1;
3795
3796 }
3797 else
3798 {
3799
3800 end = start + count;
3801
3802 }
3803
3804 if (end > length)
3805 {
3806
3807 end = length;
3808
3809 }
3810
3811 if (end <= (::character_count)start)
3812 {
3813
3814 return {};
3815
3816 }
3817
3818 return { this->begin() + start, (::character_count)(end - start) };
3819
3820}
3821
3822
3823//template < typename ITERATOR_TYPE >
3824//template < prototype_integral START >
3825//typename string_base < ITERATOR_TYPE >::BASE_RANGE string_base < ITERATOR_TYPE >::substr(START start) const
3826//{
3827//
3828// return substr(start, -1);
3829//
3830//}
3831
3832
3833//template < typename ITERATOR_TYPE >
3834//template < prototype_integral START, prototype_integral COUNT >
3835//typename string_base < ITERATOR_TYPE >::BASE_RANGE string_base < ITERATOR_TYPE >::substr(START start, COUNT count) const
3836//{
3837//
3838// /* character_count length = this->size();
3839//
3840// if (start < 0)
3841// {
3842//
3843// start = 0;
3844//
3845// }
3846// else if ((::character_count)start >= length)
3847// {
3848//
3849// return {};
3850//
3851// }
3852//
3853// character_count end;
3854//
3855// if (count < 0)
3856// {
3857//
3858//
3859//
3860// }
3861//
3862// if (end > length)
3863// {
3864//
3865// end = length;
3866//
3867// }
3868//
3869// if (end <= (::character_count) start)
3870// {
3871//
3872// return {};
3873//
3874// }*/
3875//
3876// auto sizeThis = this->size();
3877//
3878// auto start = this->begin() + minimum(start, sizeThis);
3879//
3880// auto end = minimum(count < 0 ? length + count + 1 : start + count, sizeThis);
3881//
3882// return start == 0 && end == sizeThis
3883// ?
3884// *this :
3885// {
3886// this->m_begin + start,
3887// this->m_begin + end,
3888// !(*this->end) ? e_range_null_terminated : e_range_none
3889// };
3890//
3891//}
3892//
3893
3894template < typename ITERATOR_TYPE >
3895void string_base < ITERATOR_TYPE >::clear()
3896{
3897
3898 empty();
3899
3900}
3901
3902
3903
3904template < typename ITERATOR_TYPE >
3905string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf_arguments(const CHARACTER * pszFormat, va_list args)
3906{
3907
3908 ASSERT(is_string_ok(pszFormat));
3909
3910 character_count nCurrentLength = this->size();
3911
3912 va_list argsForCount;
3913
3914 va_copy(argsForCount, args);
3915
3916 character_count nAppendLength = get_formatted_length(pszFormat, argsForCount);
3917
3918 va_end(argsForCount);
3919
3920 auto p = get_buffer<true>(nCurrentLength + nAppendLength);
3921
3922 _string_format(p + nCurrentLength, nAppendLength + 1, pszFormat, args);
3923
3924 release_buffer(nCurrentLength + nAppendLength);
3925
3926 return *this;
3927
3928}
3929
3930
3931template < typename ITERATOR_TYPE >
3932string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf_arguments(const CHARACTER * pszFormat, va_list args)
3933{
3934
3935 ASSERT(is_string_ok(pszFormat));
3936
3937 if (pszFormat == nullptr)
3938 {
3939
3940 throw_exception(error_bad_argument);
3941
3942 }
3943
3944 va_list ptr1;
3945
3946 va_copy(ptr1, args);
3947
3948 character_count nLength = get_formatted_length(pszFormat, ptr1);
3949
3950 if (nLength < 0)
3951 {
3952
3953 throw ::exception(error_failed);
3954
3955 }
3956
3957 va_end(ptr1);
3958
3959 CHARACTER * pszBuffer = get_buffer(nLength);
3960
3961 va_list ptr2;
3962
3963 va_copy(ptr2, args);
3964
3965 _string_format(pszBuffer, nLength + 1, pszFormat, ptr2);
3966
3967 va_end(ptr2);
3968
3969 release_buffer(nLength);
3970
3971 return *this;
3972
3973}
3974
3975
3976template < typename ITERATOR_TYPE >
3977string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::format_arguments(const scoped_string & scopedstrFormat, std::format_args args)
3978 requires(::is_same<CHARACTER, ansi_character>)
3979{
3980 return this->operator=(::format_arguments(scopedstrFormat, args));
3981}
3982
3983
3984template < typename ITERATOR_TYPE >
3985string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::format_arguments(const scoped_wstring & scopedstrFormat, std::wformat_args args)
3986
3987requires(::is_same<CHARACTER, wide_character>)
3988{
3989 return this->operator=(::wformat_arguments(scopedstrFormat, args));
3990}
3991
3992
3993template < typename ITERATOR_TYPE >
3994template<typename... Args>
3995string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::runtime_format(const scoped_string & scopedstrFormat, Args&&... args)
3996requires(::is_same<CHARACTER, ansi_character>)
3997{
3998
3999 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
4000
4001 auto str = std::apply([&](auto&... unpacked) {
4002 return ::format_arguments(scopedstrFormat, std::make_format_args(unpacked...));
4003 }, tuple);
4004
4005 return this->operator=(::transfer(str));
4006
4007}
4008
4009
4010
4011
4012
4013template < typename ITERATOR_TYPE >
4014template<typename... Args>
4015string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::runtime_format(const scoped_wstring & scopedstrFormat, Args&&... args)
4016requires(::is_same<CHARACTER, wide_character>)
4017{
4018
4019 auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
4020
4021 auto wstr = std::apply([&](auto&... unpacked) {
4022 return ::wformat_arguments(scopedstrFormat, std::make_format_args(unpacked...));
4023 }, tuple);
4024
4025 return this->operator=(::transfer(wstr));
4026
4027}
4028
4029
4030
4031
4032template < typename ITERATOR_TYPE >
4033string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::formatf(const CHARACTER * pszFormat, ...)
4034{
4035
4036 ASSERT(is_string_ok(pszFormat));
4037
4038 va_list argList;
4039
4040 va_start(argList, pszFormat);
4041
4042 formatf_arguments(pszFormat, argList);
4043
4044 va_end(argList);
4045
4046 return *this;
4047
4048}
4049
4050
4051// append formatted begin using format string_base < ITERATOR_TYPE > 'pszFormat'
4052template < typename ITERATOR_TYPE >
4053string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::append_formatf(const CHARACTER * pszFormat, ...)
4054{
4055
4056 ASSERT(is_string_ok(pszFormat));
4057
4058 va_list argList;
4059
4060 va_start(argList, pszFormat);
4061
4062 append_formatf_arguments(pszFormat, argList);
4063
4064 va_end(argList);
4065
4066 return *this;
4067
4068}
4069
4070
4071template < typename ITERATOR_TYPE >
4072void string_base < ITERATOR_TYPE >::reserve(character_count res_arg)
4073{
4074 get_buffer<true>(res_arg + 1);
4075}
4076
4077
4078
4079// Convert the string_base < ITERATOR_TYPE > to uppercase
4080template < typename ITERATOR_TYPE >
4081string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::uppered() const
4082{
4083
4084 return string_base < ITERATOR_TYPE >(*this).make_upper();
4085
4086}
4087
4088
4089// Convert the string_base < ITERATOR_TYPE > to lowercase
4090template < typename ITERATOR_TYPE >
4091string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::reversed() const
4092{
4093
4094 return string_base < ITERATOR_TYPE >(*this).MakeReverse();
4095
4096}
4097
4098
4099template < typename ITERATOR_TYPE >
4100string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst) const
4101{
4102
4103 return unichar_substr(iFirst, -1);
4104
4105}
4106
4107
4108template < typename ITERATOR_TYPE >
4109string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE >::unichar_substr(character_count iFirst, character_count count) const
4110{
4111
4112 const CHARACTER * pchStart = *this;
4113
4114 if (pchStart == nullptr)
4115 return "";
4116
4117 ::collection::count iUtf8Len = this->unichar_count();
4118
4119 if (iFirst < 0)
4120 iFirst = iUtf8Len + iFirst;
4121
4122 if (count < 0)
4123 count = iUtf8Len - iFirst + count + 1;
4124
4125 if (iFirst + count > iUtf8Len)
4126 count = iUtf8Len - iFirst;
4127
4128 if (count <= 0)
4129 return "";
4130
4131 ::collection::count ca = 0;
4132
4133 while (ca < iFirst && *pchStart != '\0')
4134 {
4135
4136 pchStart = unicode_next(pchStart);
4137
4138 ca++;
4139
4140 }
4141
4142 if (*pchStart == '\0')
4143 return "";
4144
4145 const CHARACTER * pchEnd = pchStart;
4146
4147 ca = 0;
4148
4149 while (ca < count && *pchEnd != '\0')
4150 {
4151
4152 pchEnd = unicode_next(pchEnd);
4153
4154 ca++;
4155
4156 }
4157
4158 return string_base < ITERATOR_TYPE >(pchStart, pchEnd - pchStart);
4159
4160
4161}
4162
4163//template < typename ITERATOR_TYPE >
4164//::collection::count string_base < ITERATOR_TYPE >::unichar_count() const
4165//{
4166//
4167// const CHARACTER* pch = *this;
4168//
4169// if (pch == nullptr)
4170// return 0;
4171//
4172// ::collection::count cCharCount = 0;
4173//
4174// while (pch != nullptr && *pch != '\0')
4175// {
4176//
4177// pch = __utf8_inc(pch);
4178//
4179// cCharCount++;
4180//
4181// }
4182//
4183// return cCharCount;
4184//
4185//}
4186
4187
4188template < typename ITERATOR_TYPE >
4189inline typename const_string_range < ITERATOR_TYPE >::const_iterator const_string_range < ITERATOR_TYPE >::unichar_at(character_count iUnicharIndex) const
4190{
4191
4192 auto p = this->begin();
4193
4194 while (p < this->end() && iUnicharIndex > 0)
4195 {
4196
4197 auto iLen = unicode_len(p);
4198
4199 p += iLen;
4200
4201 }
4202
4203 return p;
4204
4205}
4206
4207
4208
4209template < typename ITERATOR_TYPE >
4210bool string_base < ITERATOR_TYPE >::eat_before(string_base < ITERATOR_TYPE > & strBefore, const SCOPED_STRING & scopedstrSeparator, bool bEatEverythingIfNotFound)
4211{
4212
4213 ASSERT(this != &strBefore);
4214
4215 if (this == &strBefore)
4216 {
4217
4218 return false;
4219
4220 }
4221
4222 auto pFind = this->find(scopedstrSeparator);
4223
4224 if (::is_null(pFind))
4225 {
4226
4227 if (bEatEverythingIfNotFound)
4228 {
4229
4230 strBefore = *this;
4231
4232 this->empty();
4233
4234 }
4235
4236 return false;
4237
4238 }
4239
4240 strBefore = (*this)(0, pFind);
4241
4242 *this = (*this)(pFind + scopedstrSeparator.size());
4243
4244 return true;
4245
4246}
4247
4248
4249
4250template < typename ITERATOR_TYPE >
4251bool string_base < ITERATOR_TYPE >::eat_before_let_separator(string_base < ITERATOR_TYPE > & strBefore, const SCOPED_STRING & scopedstrSeparator, bool bEatEverythingIfNotFound)
4252{
4253
4254 ASSERT(this != &strBefore);
4255
4256 if (this == &strBefore)
4257 {
4258
4259 return false;
4260
4261 }
4262
4263 auto pFind = this->find(scopedstrSeparator);
4264
4265 if (::is_null(pFind))
4266 {
4267
4268 if (bEatEverythingIfNotFound)
4269 {
4270
4271 strBefore = *this;
4272
4273 *this = scopedstrSeparator;
4274
4275 }
4276
4277 return false;
4278
4279 }
4280
4281 strBefore = (*this)(0, pFind);
4282
4283 *this = (*this)(pFind);
4284
4285 return true;
4286
4287}
4288
4289
4290template < typename ITERATOR_TYPE >
4291void string_base < ITERATOR_TYPE >::add(CHARACTER ch)
4292{
4293
4294 operator += (ch);
4295
4296}
4297
4298
4299//template < typename ITERATOR_TYPE >
4300//string_base < ITERATOR_TYPE >& string_base < ITERATOR_TYPE >::operator = (const ::string_stream& scopedstr)
4301//{
4302//
4303// return this->operator =(scopedstr.operator const SCOPED_STRING & scopedstr ());
4304//
4305//}
4306//
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322//template < typename ITERATOR_TYPE >
4323//inline bool string_base < ITERATOR_TYPE > ::begins(const SCOPED_STRING & scopedstr) const
4324//{
4325//
4326// return string_range_begins<CHARACTER>(*this,scopedstr);
4327//
4328//}
4329
4330
4331//template < typename ITERATOR_TYPE >
4332//inline bool string_base < ITERATOR_TYPE > ::ends(const SCOPED_STRING & scopedstr) const
4333//{
4334//
4335// return string_range_ends<CHARACTER>(*this, scopedstr);
4336//
4337//}
4338
4339
4340//template < typename ITERATOR_TYPE >
4341//inline bool string_base < ITERATOR_TYPE > ::begins(const SCOPED_STRING & scopedstr) const
4342//{
4343//
4344// return BASE_RANGE::begins(scopedstr, ::comparison::comparison < CHARACTER >());
4345//
4346//}
4347//
4348//
4349//
4350//template < typename ITERATOR_TYPE >
4351//inline bool string_base < ITERATOR_TYPE > ::ends(const SCOPED_STRING & scopedstr) const
4352//{
4353//
4354// return BASE_RANGE::ends(scopedstr, ::comparison::comparison < CHARACTER >());
4355//
4356//}
4357
4358
4359
4360template < typename ITERATOR_TYPE >
4361inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_begins(const SCOPED_STRING & scopedstr) const
4362{
4363
4364 return this->begins(scopedstr, ::comparison::case_insensitive < CHARACTER >());
4365
4366}
4367
4368
4369
4370template < typename ITERATOR_TYPE >
4371inline bool const_string_range < ITERATOR_TYPE > ::case_insensitive_ends(const SCOPED_STRING & scopedstr) const
4372{
4373
4374 return this->ends(scopedstr, ::comparison::case_insensitive < CHARACTER >());
4375
4376}
4377
4378
4379template < typename ITERATOR_TYPE >
4380inline bool string_base < ITERATOR_TYPE > ::begins_eat(const SCOPED_STRING & scopedstrPrefix)
4381{
4382
4383 if (!this->begins(scopedstrPrefix))
4384 {
4385
4386 return false;
4387
4388 }
4389
4390 assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4391
4392 return true;
4393
4394}
4395
4396
4397template < typename ITERATOR_TYPE >
4398inline bool string_base < ITERATOR_TYPE > ::ends_eat(const SCOPED_STRING & scopedstrSuffix)
4399{
4400
4401 if (!this->ends(scopedstrSuffix))
4402 {
4403
4404 return false;
4405
4406 }
4407
4408 assign(this->begin(), this->size() - scopedstrSuffix.size());
4409
4410 return true;
4411
4412}
4413
4414
4415template < typename ITERATOR_TYPE >
4416inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eat(const SCOPED_STRING & scopedstrPrefix)
4417{
4418
4419 if (!this->case_insensitive_begins(scopedstrPrefix))
4420 {
4421
4422 return false;
4423
4424 }
4425
4426 assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4427
4428 return true;
4429
4430}
4431
4432
4433template < typename ITERATOR_TYPE >
4434inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eat(const SCOPED_STRING & scopedstrSuffix)
4435{
4436
4437 if (!this->case_insensitive_ends(scopedstrSuffix))
4438 {
4439
4440 return false;
4441
4442 }
4443
4444 assign(this->begin(), this->size() - scopedstrSuffix.size());
4445
4446 return true;
4447
4448}
4449
4450
4451template < typename ITERATOR_TYPE >
4452inline bool string_base < ITERATOR_TYPE > ::begins_replace(const SCOPED_STRING & scopedstrNewPrefix, const SCOPED_STRING & scopedstrPrefix)
4453{
4454
4455 if(!begins_eat(scopedstrPrefix))
4456 {
4457
4458 return false;
4459
4460 }
4461
4462 *this = scopedstrNewPrefix + *this;
4463
4464 return true;
4465
4466}
4467
4468
4469template < typename ITERATOR_TYPE >
4470inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_replace(const SCOPED_STRING & scopedstrNewPrefix, const SCOPED_STRING & scopedstrPrefix)
4471{
4472
4473 if(!this->case_insensitive_begins_eat(scopedstrPrefix))
4474 {
4475
4476 return false;
4477
4478 }
4479
4480 *this = scopedstrNewPrefix + *this;
4481
4482 return true;
4483
4484}
4485
4486
4487template < typename ITERATOR_TYPE >
4488inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_prefix(const SCOPED_STRING & scopedstrPrefix)
4489{
4490
4491 if (!this->begins(scopedstrPrefix))
4492 {
4493
4494 operator =(scopedstrPrefix + *this);
4495
4496 }
4497
4498 return *this;
4499
4500}
4501
4502
4503template < typename ITERATOR_TYPE >
4504inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_prefix(const SCOPED_STRING & scopedstrPrefix)
4505{
4506
4507 if (!this->case_insensitive_begins(scopedstrPrefix))
4508 {
4509
4510 operator =(scopedstrPrefix + *this);
4511
4512 }
4513
4514 return *this;
4515
4516}
4517
4518
4519template < typename ITERATOR_TYPE >
4520inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::ensure_suffix(const SCOPED_STRING & scopedstrSuffix)
4521{
4522
4523 if (!this->ends(scopedstrSuffix))
4524 {
4525
4526 operator =(*this + scopedstrSuffix);
4527
4528 }
4529
4530 return *this;
4531
4532}
4533
4534
4535template < typename ITERATOR_TYPE >
4536inline string_base < ITERATOR_TYPE > & string_base < ITERATOR_TYPE > ::case_insensitive_ensure_suffix(const SCOPED_STRING & scopedstrSuffix)
4537{
4538
4539 if (!this->case_insensitive_ends(scopedstrSuffix))
4540 {
4541
4542 operator =(*this + scopedstrSuffix);
4543
4544 }
4545
4546 return *this;
4547
4548}
4549
4550
4551
4552template < typename ITERATOR_TYPE >
4553inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_prefixed(const SCOPED_STRING & scopedstrPrefix) const
4554{
4555
4556 if (!this->begins(scopedstrPrefix))
4557 {
4558
4559 return scopedstrPrefix + *this;
4560
4561 }
4562
4563 return *this;
4564
4565}
4566
4567
4568template < typename ITERATOR_TYPE >
4569inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_prefixed(const SCOPED_STRING & scopedstrPrefix) const
4570{
4571
4572 if (!this->case_insensitive_begins(scopedstrPrefix))
4573 {
4574
4575 return scopedstrPrefix + *this;
4576
4577 }
4578
4579 return *this;
4580
4581}
4582
4583
4584template < typename ITERATOR_TYPE >
4585inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::defer_suffixed(const SCOPED_STRING & scopedstrSuffix) const
4586{
4587
4588 if (!this->ends(scopedstrSuffix))
4589 {
4590
4591 return *this + scopedstrSuffix;
4592
4593 }
4594
4595 return *this;
4596
4597}
4598
4599
4600template < typename ITERATOR_TYPE >
4601inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_defer_suffixed(const SCOPED_STRING & scopedstrSuffix) const
4602{
4603
4604 if (!this->case_insensitive_ends(scopedstrSuffix))
4605 {
4606
4607 return *this + scopedstrSuffix;
4608
4609 }
4610
4611 return *this;
4612
4613}
4614
4615//template < typename ITERATOR_TYPE >
4616//inline bool string_base < ITERATOR_TYPE > ::begins(const CHARACTER * pszPrefix) const
4617//{
4618//
4619// auto psz = this->begin();
4620//
4621// while (*psz && *pszPrefix)
4622// {
4623//
4624// if (*psz != *pszPrefix)
4625// {
4626//
4627// return false;
4628//
4629// }
4630//
4631// psz++;
4632//
4633// pszPrefix++;
4634//
4635// }
4636//
4637// return !*pszPrefix;
4638//
4639//}
4640//
4641
4642//template < typename ITERATOR_TYPE >
4643//inline bool string_base < ITERATOR_TYPE > ::begins(const SCOPED_STRING & scopedstrPrefix) const
4644//{
4645//
4646// auto psz = this->begin();
4647//
4648// auto pszPrefix = scopedstrPrefix.begin();
4649//
4650// auto pszPrefixEnd = scopedstrPrefix.end();
4651//
4652// while (*psz && pszPrefix < pszPrefixEnd)
4653// {
4654//
4655// if (*psz != *pszPrefix)
4656// {
4657//
4658// return false;
4659//
4660// }
4661//
4662// psz++;
4663//
4664// pszPrefix++;
4665//
4666// }
4667//
4668// return pszPrefix == pszPrefixEnd;
4669//
4670//}
4671
4672
4673//template < typename ITERATOR_TYPE >
4674//inline bool string_base < ITERATOR_TYPE > ::ends(const SCOPED_STRING & scopedstrSuffix) const
4675//{
4676//
4677// return string_ends(this->begin(), this->size(), scopedstrSuffix, scopedstrSuffix.size());
4678//
4679//}
4680
4681
4682//template < typename ITERATOR_TYPE >
4683//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins(const SCOPED_STRING & scopedstrPrefix) const
4684//{
4685//
4686// auto psz = this->begin();
4687//
4688// auto pszPrefix = scopedstrPrefix.begin();
4689//
4690// auto pszPrefixEnd = scopedstrPrefix.end();
4691//
4692// while (*psz && pszPrefix < pszPrefixEnd)
4693// {
4694//
4695// if (character_tolower(*psz) != character_tolower(*pszPrefix))
4696// {
4697//
4698// return false;
4699//
4700// }
4701//
4702// psz++;
4703//
4704// pszPrefix++;
4705//
4706// }
4707//
4708// return pszPrefix == pszPrefixEnd;
4709//
4710//}
4711
4712
4713//template < typename ITERATOR_TYPE >
4714//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends(const SCOPED_STRING & scopedstrSuffix) const
4715//{
4716//
4717// return case_insensitive_string_ends(this->begin(), this->size(), scopedstrSuffix, scopedstrSuffix.size());
4718//
4719//}
4720
4721
4722//template < typename ITERATOR_TYPE >
4723//inline bool string_base < ITERATOR_TYPE > ::begins_eat(const SCOPED_STRING & scopedstrPrefix)
4724//{
4725//
4726// character_count lenPrefix;
4727//
4728// if (!_string_begins(this->begin(), this->size(), scopedstrPrefix, lenPrefix))
4729// {
4730//
4731// return false;
4732//
4733// }
4734//
4735// assign(this->begin() + lenPrefix, this->size() - lenPrefix);
4736//
4737// return true;
4738//
4739//}
4740//
4741
4742//template < typename ITERATOR_TYPE >
4743//inline bool string_base < ITERATOR_TYPE > ::ends_eat(const SCOPED_STRING & scopedstrSuffix)
4744//{
4745//
4746// character_count lenSuffix;
4747//
4748// if (!_string_ends(this->begin(), this->size(), scopedstrSuffix, lenSuffix))
4749// {
4750//
4751// return false;
4752//
4753// }
4754//
4755// truncate(this->size() - lenSuffix);
4756//
4757// return true;
4758//
4759//}
4760
4761
4762//template < typename ITERATOR_TYPE >
4763//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_eat(const SCOPED_STRING & scopedstrPrefix)
4764//{
4765//
4766// character_count lenPrefix;
4767//
4768// if (!case_insensitive__string_begins(this->begin(), this->size(), scopedstrPrefix, lenPrefix))
4769// {
4770//
4771// return false;
4772//
4773// }
4774//
4775// assign(this->begin() + lenPrefix, this->size() - lenPrefix);
4776//
4777// return true;
4778//
4779//}
4780
4781
4782//template < typename ITERATOR_TYPE >
4783//inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_eat(const SCOPED_STRING & scopedstrSuffix)
4784//{
4785//
4786// character_count lenSuffix;
4787//
4788// if (!case_insensitive__string_ends(this->begin(), this->size(), scopedstrSuffix, lenSuffix))
4789// {
4790//
4791// return false;
4792//
4793// }
4794//
4795// truncate(this->size() - lenSuffix);
4796//
4797// return true;
4798//
4799//}
4800
4801
4802template < typename ITERATOR_TYPE >
4803inline bool string_base < ITERATOR_TYPE > ::begins_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstrPrefix) const
4804{
4805
4806 if (!this->begins(scopedstrPrefix))
4807 {
4808
4809 return false;
4810
4811 }
4812
4813 strRemainder.assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4814
4815 return true;
4816
4817}
4818
4819
4820template < typename ITERATOR_TYPE >
4821inline bool string_base < ITERATOR_TYPE > ::ends_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstrSuffix) const
4822{
4823
4824 if (!this->ends(scopedstrSuffix))
4825 {
4826
4827 return false;
4828
4829 }
4830
4831 strRemainder.assign(this->begin(), this->size() - scopedstrSuffix.size());
4832
4833 return true;
4834
4835}
4836
4837
4838template < typename ITERATOR_TYPE >
4839inline bool string_base < ITERATOR_TYPE > ::case_insensitive_begins_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstrPrefix) const
4840{
4841
4842 if (!this->case_insensitive_begins(scopedstrPrefix))
4843 {
4844
4845 return false;
4846
4847 }
4848
4849 strRemainder.assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4850
4851 return true;
4852
4853}
4854
4855
4856template < typename ITERATOR_TYPE >
4857inline bool string_base < ITERATOR_TYPE > ::case_insensitive_ends_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstrSuffix) const
4858{
4859
4860 if (!this->case_insensitive_ends(scopedstrSuffix))
4861 {
4862
4863 return false;
4864
4865 }
4866
4867 strRemainder.assign(this->begin(), this->size() - scopedstrSuffix.size());
4868
4869 return true;
4870
4871}
4872
4873
4874template < typename ITERATOR_TYPE >
4875inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::begins_bitten(const SCOPED_STRING & scopedstrPrefix) const
4876{
4877
4878 if (!this->begins(scopedstrPrefix))
4879 {
4880
4881 return *this;
4882
4883 }
4884
4885 return { this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size() };
4886
4887}
4888
4889
4890template < typename ITERATOR_TYPE >
4891inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::ends_bitten(const SCOPED_STRING & scopedstrSuffix) const
4892{
4893
4894 if (!this->ends(scopedstrSuffix))
4895 {
4896
4897 return *this;
4898
4899 }
4900
4901 return { this->begin(), this->size() - scopedstrSuffix.size()};
4902
4903}
4904
4905
4906template < typename ITERATOR_TYPE >
4907inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_bitten(const SCOPED_STRING & scopedstrPrefix) const
4908{
4909
4910 if (!this->case_insensitive_begins(scopedstrPrefix))
4911 {
4912
4913 return *this;
4914
4915 }
4916
4917 return { this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size()};
4918
4919}
4920
4921
4922template < typename ITERATOR_TYPE >
4923inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_bitten(const SCOPED_STRING & scopedstrSuffix) const
4924{
4925
4926 if (!this->case_insensitive_ends(scopedstrSuffix))
4927 {
4928
4929 return *this;
4930
4931 }
4932
4933 return { this->begin(), this->size() - scopedstrSuffix.size()};
4934
4935}
4936
4937
4938
4939template < typename ITERATOR_TYPE >
4940inline bool string_base < ITERATOR_TYPE > ::begins_erase_get_erased(string_base & strErased, const SCOPED_STRING & scopedstrPrefix)
4941{
4942
4943 if (!this->case_insensitive_begins(scopedstrPrefix))
4944 {
4945
4946 return false;
4947
4948 }
4949
4950 strErased.assign(this->begin(), scopedstrPrefix.size());
4951
4952 assign(this->begin() + scopedstrPrefix.size(), this->size() - scopedstrPrefix.size());
4953
4954 return true;
4955
4956}
4957
4958
4959template < typename ITERATOR_TYPE >
4960inline bool string_base < ITERATOR_TYPE > ::ends_erase_get_erased(string_base & strErased, const SCOPED_STRING & scopedstrSuffix)
4961{
4962
4963 if (!this->case_insensitive_ends(scopedstrSuffix))
4964 {
4965
4966 return false;
4967
4968 }
4969
4970 strErased.assign(this->begin() + this->length() - scopedstrSuffix.size(), scopedstrSuffix.size());
4971
4972 assign(this->begin(), this->size() - scopedstrSuffix.size());
4973
4974 return true;
4975
4976}
4977
4978
4979template < typename ITERATOR_TYPE >
4980inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_begins_eaten(const SCOPED_STRING & scopedstrPrefix) const
4981{
4982
4983 if (!this->case_insensitive_begins(scopedstrPrefix))
4984 {
4985
4986 return {};
4987
4988 }
4989
4990 return { this->begin(), scopedstrPrefix.size() };
4991
4992}
4993
4994
4995template < typename ITERATOR_TYPE >
4996inline string_base < ITERATOR_TYPE > string_base < ITERATOR_TYPE > ::case_insensitive_ends_eaten(const SCOPED_STRING & scopedstrSuffix) const
4997{
4998
4999 if (!this->case_insensitive_ends(scopedstrSuffix))
5000 {
5001
5002 return {};
5003
5004 }
5005
5006 return { this->begin() + this->length() - scopedstrSuffix.size(), scopedstrSuffix.size() };
5007
5008}
5009
5010
5011template < typename ITERATOR_TYPE >
5012// replace all occurrences of string_base 'pszOld' with string_base 'pszNew'
5013template < typename EQUALITY >
5014inline ::collection::count string_base < ITERATOR_TYPE > ::_replace_with(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start, EQUALITY equality)
5015{
5016
5017 // nSourceLen is in XCHARs
5018 character_count nReplacedLen = scopedstrOld.size();
5019
5020 if (nReplacedLen == 0)
5021 {
5022
5023 return 0;
5024
5025 }
5026
5027 // nReplacementLen is in XCHARs
5028 character_count nReplacementLen = scopedstrNew.size();
5029
5030 // loop once to figure out the i32_size of the result string_base < ITERATOR_TYPE >
5031 auto count = (*this)(start)._occurrence_count_of(scopedstrOld, equality);
5032
5033 // if any changes were made, make them
5034 if (count <= 0)
5035 {
5036
5037 return 0;
5038
5039 }
5040
5041 // if the buffer is too small, just
5042 // allocate a ___new buffer(slow but sure)
5043
5044 character_count nNewLength = this->size() + (nReplacementLen - nReplacedLen) * count;
5045
5046 string_base < ITERATOR_TYPE > str;
5047
5048 CHARACTER * pszBuffer = str.get_buffer(nNewLength);
5049
5050 CHARACTER * pLastNewEnd = pszBuffer;
5051
5052 BASE_RANGE rangeOld = *this;
5053
5054 memory_copy(pLastNewEnd, rangeOld.begin(), start * sizeof(CHARACTER));
5055
5056 rangeOld.begin() += start;
5057
5058 pLastNewEnd += start;
5059
5060 CHARACTER * pszTarget;
5061
5062 while ((pszTarget = (CHARACTER *)rangeOld.find(scopedstrOld, equality)) != nullptr)
5063 {
5064
5065 auto offset = pszTarget - rangeOld.begin();
5066
5067 memory_copy(pLastNewEnd,rangeOld.begin(), offset * sizeof(CHARACTER));
5068
5069 pLastNewEnd += offset;
5070
5071 memory_copy(pLastNewEnd, scopedstrNew.begin(), nReplacementLen * sizeof(CHARACTER));
5072
5073 rangeOld.m_begin = pszTarget + nReplacedLen;
5074
5075 pLastNewEnd += nReplacementLen;
5076
5077 }
5078
5079 memory_copy(pLastNewEnd,rangeOld.begin(), (rangeOld.end() - rangeOld.begin()) * sizeof(CHARACTER));
5080
5081 str.release_buffer(nNewLength);
5082
5083 *this = ::transfer(str);
5084
5085 return count;
5086
5087}
5088
5089
5090
5091
5092
5093template < prototype_character CHARACTER >
5094void CopyCharsOverlapped(CHARACTER * pchDest, const CHARACTER * pchSrc, character_count nChars) noexcept
5095{
5096
5097 memory_transfer(pchDest, pchSrc, nChars * sizeof(CHARACTER));
5098
5099}
5100
5101
5102template < prototype_character CHARACTER >
5103void CopyCharsOverlapped(CHARACTER * pchDest, size_t nDestLen, const CHARACTER * pchSrc, character_count nChars) noexcept
5104{
5105
5106 memory_transfer(pchDest, pchSrc, nChars * sizeof(CHARACTER));
5107
5108}
5109
5110
5111
5112template < typename STRING >
5113inline STRING & string_concatenate(STRING & scopedstr, const typename STRING::CHARACTER * psz1, character_count nLength1, const typename STRING::CHARACTER * psz2, character_count nLength2)
5114{
5115
5116 character_count nNewLength = nLength1 + nLength2;
5117
5118 typename STRING::CHARACTER * pszBuffer = scopedstr.get_buffer(nNewLength);
5119
5120 string_count_copy(pszBuffer, psz1, nLength1);
5121
5122 string_count_copy(pszBuffer + nLength1, psz2, nLength2);
5123
5124 scopedstr.release_buffer(nNewLength);
5125
5126 return scopedstr;
5127
5128}
5129
5130
5131template < typename STRING >
5132inline bool string_ends_eat(STRING & ansistr, const STRING & scopedstrSuffix)
5133{
5134
5135 auto lenSuffix = scopedstrSuffix.length();
5136
5137 if (lenSuffix > ansistr.length())
5138 {
5139
5140 return false;
5141
5142 }
5143
5144 if (STRING::string_count_compare(ansistr.reverse_ptr_at(lenSuffix), scopedstrSuffix, lenSuffix) != 0)
5145 {
5146
5147 return false;
5148
5149 }
5150
5151 ansistr.reverse_truncate(lenSuffix);
5152
5153 return true;
5154
5155}
5156
5157
5158
5159::i32 get_mem_free_available_kb();
5160
5161
5162template < prototype_character CHARACTER >
5163::wd32_character unicode_iterator < CHARACTER > ::operator *() { return unicode_index(m_psz); }
5164
5165
5166template < prototype_character CHARACTER >
5167unicode_iterator < CHARACTER > & unicode_iterator < CHARACTER > ::operator ++()
5168{
5169
5170 unicode_increment(m_psz);
5171
5172 return *this;
5173
5174}
5175
5176
5177template < prototype_character CHARACTER >
5178unicode_iterator < CHARACTER > unicode_iterator < CHARACTER > ::operator ++(::i32)
5179{
5180
5181 auto psz = m_psz;
5182
5183 unicode_increment(m_psz);
5184
5185 return psz;
5186
5187}
5188
5189
5190
5191template < typename ITERATOR_TYPE >
5192inline string_base < ITERATOR_TYPE > operator +(const scoped_string_base < ITERATOR_TYPE > & scopedstr, const inline_number_string & inlinenumberstring)
5193{
5194
5195 string_base < ITERATOR_TYPE > str(scopedstr);
5196
5197 string_base < ITERATOR_TYPE > strNumber(inlinenumberstring);
5198
5199 str.append(strNumber);
5200
5201 return ::transfer(scopedstr);
5202
5203}
5204
5205
5206template < character_count n >
5207inline ::string_base < const_char_pointer >operator +(const ::i8 (&s)[n], const inline_number_string& inlinenumberstring)
5208{
5209
5210 return { ::as_string_literal<::i8, n>(s), inlinenumberstring };
5211
5212}
5213
5214
5215//template < character_count m_sizeMaximumLength >
5216//inline ::string operator +(const ::scoped_string & scopedstr, const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring)
5217//{
5218//
5219// return str + ::string(inlinestring);
5220//
5221//}
5222//
5223//
5224//template < ::collection::count c >
5225//inline ::string operator +(const ::scoped_string & scopedstr, const ::i8(&sz)[c])
5226//{
5227//
5228// return str + ::string(sz);
5229//
5230//}
5231
5232
5233
5234
5235
5236
5237
5238//template < ::collection::count c, character_count m_sizeMaximumLength >
5239//inline ::string operator +(const ::i8(&sz)[c], const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring)
5240//{
5241//
5242// return ::transfer(::string(sz) + ::string(inlinestring));
5243//
5244//}
5245//
5246//
5247//
5248//template < ::collection::count c, character_count m_sizeMaximumLength >
5249//inline ::string operator +(const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring, const ::i8(&sz)[c])
5250//{
5251//
5252// return ::transfer(::string(inlinestring) + ::string(sz));
5253//
5254//}
5255
5256
5257//inline ::string operator + (const ::scoped_string & scopedstr, ::i8 ch)
5258//{
5259//
5260// return str + ::string(ch);
5261//
5262//}
5263
5264
5265template < typename ITERATOR_TYPE >
5266inline string_base < ITERATOR_TYPE >::string_base(const ::atom& atom) :
5267 string_base(atom.as_string())
5268{
5269
5270
5271}
5272
5273
5274template < typename ITERATOR_TYPE >
5275string_base < ITERATOR_TYPE >::string_base(const ::payload & payload) :
5276 string_base(payload.as_string())
5277{
5278
5279
5280}
5281
5282
5283template < typename ITERATOR_TYPE >
5284inline string_base < ITERATOR_TYPE >::string_base(const property & property) :
5285 string_base(property.as_string())
5286{
5287
5288
5289}
5290
5291
5292
5293
5294//
5295//
5296//
5297//template < typename ITERATOR_TYPE >
5298//inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const scoped_ansi_string & ansistr) { assign_range(ansistr); return *this; }
5299//
5300//template < typename ITERATOR_TYPE >
5301//inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const scoped_wd16_string & wd16str) { assign_range(wd16str); return *this; }
5302//
5303//template < typename ITERATOR_TYPE >
5304//inline string_base< ITERATOR_TYPE > & string_base < ITERATOR_TYPE >::operator = (const scoped_wd32_string & wd32str) { assign_range(wd32str); return *this; }
5305//
5306
5307
5308template < typename ITERATOR_TYPE >
5309inline typename scoped_string_base < ITERATOR_TYPE >::STRING scoped_string_base < ITERATOR_TYPE > ::as_string() const
5310{
5311
5312 return *this;
5313
5314}
5315
5316
5317template < typename ITERATOR_TYPE >
5318inline typename scoped_string_base < ITERATOR_TYPE >::BASE_RANGE scoped_string_base < ITERATOR_TYPE > ::rear_word(CHARACTER ch) const
5319{
5320
5321 auto p = this->rear_find(ch);
5322
5323 if (!p)
5324 {
5325
5326 return {};
5327
5328 }
5329
5330 return {::unicode_next(p), this->m_end};
5331
5332}
5333
5334
5335template < typename ITERATOR_TYPE >
5336inline typename scoped_string_base < ITERATOR_TYPE >::BASE_RANGE scoped_string_base < ITERATOR_TYPE > ::rear_prefix(CHARACTER ch) const
5337{
5338
5339 auto p = this->rear_find(ch);
5340
5341 if (!p)
5342 {
5343
5344 return {};
5345
5346 }
5347
5348 return {this->m_begin, p};
5349
5350}
5351
5352
5353#include "acme/prototype/string/c_string.h"
5354
5355
5356template < typename ITERATOR_TYPE >
5357string_base<ITERATOR_TYPE>::string_base(const ::c::string & cstring) :
5358 string_base(cstring.m_psz)
5359{
5360
5361
5362}
5363
5364
5365
5366
5367
5368template<typename ITERATOR_TYPE>
5369inline const ::block string_base<ITERATOR_TYPE>::block_with_null_terminator() const
5370{
5371
5372 return {(const void *) this->data(), this->size_in_bytes_with_null_terminator()};
5373
5374}
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 tuple.h:72
Definition std_iterator.h:49