acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
string_base.h
1// string_base Created by camilo on 2012-12-18 18:44 <3ThomasBorregaardSorensen!!
2// string_base concept erased and merged into
3// string_base by Camilo on 2025-04-21 17:30 <3ThomasBorregaardSørensen!!
4#pragma once
5
6
7CLASS_DECL_ACME void __what__(::i32 i);
8namespace c
9{
10
11 class string;
12} // namespace c
13
14
15#include "string_iterator.h"
16//#ifdef _STDIO_H_
17//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(1))"_ansi
18//#endif
19#include "string_heap_data.h"
20//#ifdef _STDIO_H_
21//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(2))"_ansi
22//#endif
23#include "const_string_range.h"
24//#ifdef _STDIO_H_
25//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(3))"_ansi
26//#endif
27#include "string_range.h"
28//#ifdef _STDIO_H_
29//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(4))"_ansi
30//#endif
31#include "mutable_string_range.h"
32//#ifdef _STDIO_H_
33//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(5))"_ansi
34//#endif
35#include "acme/prototype/prototype/function.h"
36//#ifdef _STDIO_H_
37//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(A))"_ansi
38//#endif
39//#include "acme/memory/string_memory_allocator.h"
40#include "acme/memory/memory.h"
41//#ifdef _STDIO_H_
42//#error "already included?!?! WHAT?!?! (After including acme/prototype/string/string_base.h(C))"_ansi
43//#endif
44//#if defined(__STD_FORMAT)
45#include <format>
46//#endif
47//#ifdef _STDIO_H_
48//#error "already included?!?! WHAT?!?! (After including <format>)"_ansi
49//#endif
50
51// template < typename ITERATOR_TYPE >
52// using string_natural_pointer =
53// ::natural_pointer <
54// ::string_heap_data <
55// dereference <
56// get_type_item_pointer < ITERATOR_TYPE >
57// >
58// >, ::heap::e_memory_string >;
59
60
61enum enum_canonical
62{
63
64 e_canonical,
65
66};
67
68
69template < typename ITERATOR_TYPE >
70inline const_string_range < ITERATOR_TYPE > string_get_word_separated_by_spaces(const scoped_string_base < ITERATOR_TYPE > & scopedstr, ITERATOR_TYPE * ppnext = nullptr);
71
72template < typename ITERATOR_TYPE >
73inline const_string_range < ITERATOR_TYPE > string_get_word_with_separator_list(const scoped_string_base < ITERATOR_TYPE > & scopedstr, const scoped_string_base < ITERATOR_TYPE > & strSeparatorList, ITERATOR_TYPE * ppnext = nullptr);
74
75template < typename ITERATOR_TYPE >
76inline string_base < ITERATOR_TYPE > string_get_word_with_separator_list_and_go_next(string_base < ITERATOR_TYPE > & str, const scoped_string_base < ITERATOR_TYPE > & strSeparatorList);
77
78template < typename ITERATOR_TYPE >
79using get_word_function = ::function < const_string_range < ITERATOR_TYPE >(const scoped_string_base < ITERATOR_TYPE > &, ITERATOR_TYPE *) >;
80
81
82template < typename ITERATOR_TYPE >
84
85
86template < typename ITERATOR_TYPE >
87class string_base :
88 public ::const_string_range < ITERATOR_TYPE >
89 // , public ::string_natural_pointer < ITERATOR_TYPE >
90{
91public:
92
93
94 using BASE_RANGE = ::const_string_range < ITERATOR_TYPE >;
95 using this_iterator = typename BASE_RANGE::this_iterator;
96 using iterator = typename BASE_RANGE::iterator;
97 using const_iterator = typename BASE_RANGE::const_iterator;
98
99
100
101 //using NATURAL_POINTER = string_natural_pointer < this_iterator >;
102 //using META_DATA = typename NATURAL_POINTER::META_DATA;
103 using PRIMITIVE_STRING_TAG = PRIMITIVE_STRING_TAG_TYPE;
104 using ITEM_POINTER = get_type_item_pointer< this_iterator >;
105 using ITEM = ::const_string_range < ITERATOR_TYPE >::ITEM;
106 using CHARACTER = ::const_string_range < ITERATOR_TYPE >::CHARACTER;
107 //using THIS_RAW_RANGE = typename BASE_RANGE::THIS_RAW_RANGE;
108 using BASE_DATA = BASE_RANGE::BASE_DATA;
109 using SCOPED_STRING = scoped_string_base < this_iterator >;
110
111
112 string_base() { default_construct(); }
113 string_base(no_initialize_t) : ::const_string_range < ITERATOR_TYPE >(no_initialize_t{}) {}
114 string_base(nullptr_t) { default_construct(); }
115 //string_base(enum_for_moving) { }
116 //string_base(enum_get_buffer, character_count length) { get_buffer(length); }
117 //string_base(const_char_pointer psz);
118 //string_base(const ::wd16_character * psz);
119 //string_base(const ::wd32_character * psz);
120 //string_base(const ::std::string & str) : string_base(str.c_str()) { }
121
122
123 template < typed_character_pointer < typename scoped_string_base < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
124 string_base(CHARACTER_POINTER start, CHARACTER_POINTER end, enum_range erange) :
125 BASE_RANGE(no_initialize_t{})
126 {
127
128 this->construct_from_a_range(start, end, erange);
129
130 }
131
132
133 template < other_character_pointer < typename scoped_string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER_POINTER >
134 string_base(OTHER_CHARACTER_POINTER start, OTHER_CHARACTER_POINTER end, enum_range erange = e_range_none) :
135 BASE_RANGE(no_initialize_t{})
136 {
137
138 this->construct_from_a_range(start, end, erange);
139
140 }
141
142
143 string_base(const string_base& str) :
144 BASE_RANGE(no_initialize_t{})
145 {
146
147 this->construct_from_string(str);
148
149 }
150
151
152 template < prototype_std_string STDSTRING >
153 string_base(const STDSTRING & stdstring) : string_base(stdstring.c_str(), stdstring.length()) {}
154
155
156 //template < character_count n >
157 //string_base(const CHARACTER (&s)[n]) :
158 // ::const_string_range<ITERATOR_TYPE>(no_initialize_t{})
159 //{
160
161 // if constexpr (n >= 1)
162 // {
163
164 // if (s[n - 1] == CHARACTER{})
165 // {
166
167 // this->m_begin = s;
168 // this->m_end = s + n - 1;
169 // //this->m_erange = e_range_null_terminated
170 // // | e_range_string_literal;
171 // this->m_erange = e_range_null_terminated;
172 // // | e_range_string_literal;
173
174 // return;
175
176 // }
177
178 // }
179
180 // this->m_begin = s;
181 // this->m_end = s + string_safe_length(s);
182 // this->m_erange = e_range_none;
183 // //this->m_erange = e_range_none | e_range_string_literal;
184
185 //}
186
187
188 template < typename RANGE >
189 string_base(const RANGE & str) requires
190 (::std::is_base_of_v < ::character_range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE >
191 && !
192 (::std::is_base_of_v < string_base < ITERATOR_TYPE >, RANGE >
193 || ::std::is_same_v < string_base < ITERATOR_TYPE >, RANGE >)) :
194 ::const_string_range < ITERATOR_TYPE >(no_initialize_t{})
195 {
196
197 construct_from_a_range(str);
198
199 }
200
201
202 template < typename RANGE, typename RANGE2 >
203 string_base(const RANGE& range1, const RANGE2 & range2) requires
204 ::std::is_base_of_v < ::character_range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE >
205 &&
206 ::std::is_base_of_v < ::character_range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE2 >:
207 ::const_string_range < ITERATOR_TYPE >(no_initialize_t{})
208 {
209
210 construct_from_two_ranges_concatenation(range1, range2);
211
212 }
213
214
215 template < typename OTHER_CHARACTER >
216 string_base(const ::character_range < const OTHER_CHARACTER* >& range)
217 requires other_primitive_character < OTHER_CHARACTER, CHARACTER >:
218 ::const_string_range < ITERATOR_TYPE >(no_initialize_t{})
219 {
220
221 this->construct20(range.m_begin, range.size(), range.m_erange);
222
223 }
224
225
226 //string_base(const ::ansi_string & ansistr) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(ansistr); }
227 //string_base(const ::wd16_string & wd16str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(wd16str); }
228 //string_base(const ::wd32_string & wd32str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(wd32str); }
229 string_base(string_base && str) :
230 ::const_string_range < ITERATOR_TYPE >(no_initialize_t{})
231 {
232 this->m_begin = str.m_begin;
233 this->m_end = str.m_end;
234 this->m_erange = str.m_erange;
235 this->m_pbasedata = str.m_pbasedata;
236 str.m_begin = nullptr;
237 str.m_end = nullptr;
238 str.m_erange = e_range_none;
239 str.m_pbasedata = nullptr;
240 }
241
242 string_base(const ::c::string & cstring);
243
244 //void _construct(const ::ansi_string & ansistr) { construct_from_a_range(ansistr); }
245 //void _construct(const ::wd16_string & wd16str) { construct_from_a_range(wd16str); }
246 //void _construct(const ::wd32_string & wd32str) { construct_from_a_range(wd32str); }
247 //void _construct(string_base && str)
248 //{
249 // this->m_begin = str.m_begin;
250 // this->m_end = str.m_end;
251 // this->m_erange = str.m_erange;
252 // str.m_begin = nullptr;
253 // str.m_end = nullptr;
254 //}
255
256// template<typed_range<::ansi_character *> RANGE>
257// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
258// template<typed_range<const_char_pointer >RANGE>
259// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
260// template<typed_range<::wd16_character *> RANGE>
261// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
262// template<typed_range<const ::wd16_character *> RANGE>
263// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
264// template<typed_range<::wd32_character *> RANGE>
265// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
266// template<typed_range<const ::wd32_character *> RANGE>
267// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
268
269
270 //template<typed_range<::ansi_character *> RANGE>
271 //explicit string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
272 //template<typed_range<::wd16_character *> RANGE>
273 //explicit string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
274 //template<typed_range<::wd32_character *> RANGE>
275 //explicit string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
276
277
278 //template<typed_range<const_char_pointer >RANGE>
279 //explicit string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
280 //template<typed_range<const ::wd16_character *> RANGE>
281 //explicit string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
282 //template<typed_range<const ::wd32_character *> RANGE>
283 //explicit string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
284
285 //template < ::i32 t_size >
286 //inline string_base(const const_string_range_static_array < ITERATOR_TYPE, t_size >& a);
287
288 //template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
289 //inline string_base(const const_string_range_static_array < const OTHER_CHARACTER *, t_size > & a);
290
291// template<typed_range<::ansi_character *> RANGE>
292// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
295// template<typed_range<::wd16_character *> RANGE>
296// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
299// template<typed_range<::wd32_character *> RANGE>
300// string_base(const RANGE & str) : NATURAL_POINTER(no_initialize_t{}) { construct2(str); }
303
304 // string_base(const ::const_ansi_range & ansirange) : NATURAL_POINTER(no_initialize_t{}){construct2(ansirange);}
305// string_base(const ::const_wd16_range & wd16range) : NATURAL_POINTER(no_initialize_t{}){construct2(wd16range);}
306// string_base(const ::const_wd32_range & wd32range) : NATURAL_POINTER(no_initialize_t{}){construct2(wd32range);}
307
308 //xxxstring_base(const const_ansi_range & ansirange) : NATURAL_POINTER(no_initialize_t{}) { construct2(ansirange.begin(), ansirange.size()); }
309 //xxxstring_base(const const_wd16_range & wd16range) : NATURAL_POINTER(no_initialize_t{}) { construct2(wd16range.begin(), wd16range.size()); }
310 //xxxstring_base(const const_wd32_range & wd32range) : NATURAL_POINTER(no_initialize_t{}) { construct2(wd32range.begin(), wd32range.size()); }
311 //string_base(const const_ansi_range & ansirange) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(ansirange); }
312 //string_base(const const_wd16_range & wd16range) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(wd16range); }
313 //string_base(const const_wd32_range & wd32range) : NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(wd32range); }
314 //string_base(const const_ansi_range & ansirange, character_count length) : NATURAL_POINTER(no_initialize_t{}) { construct2(ansirange, 0, length); }
315 //string_base(const const_wd16_range & wd16range, character_count length) : NATURAL_POINTER(no_initialize_t{}) { construct2(wd16range, 0, length); }
316 //string_base(const const_wd32_range & wd32range, character_count length) : NATURAL_POINTER(no_initialize_t{}) { construct2(wd32range, 0, length); }
317 //string_base(const const_ansi_range & ansirange, character_count length) : NATURAL_POINTER(no_initialize_t{}) { construct2(ansirange, start, length); }
318 //string_base(const const_wd16_range & wd16range, character_count length) : NATURAL_POINTER(no_initialize_t{}) { construct2(wd16range, start, length); }
319 //
320 //
321 //string_base(const const_wd32_range & wd32range, character_count length) : NATURAL_POINTER(no_initialize_t{}) { construct2(wd32range, start, length); }
322 template < prototype_block BLOCK >
323 string_base(const BLOCK & block) : string_base((const CHARACTER *)block.begin(), (const CHARACTER *)block.end()) {}
324 template < character_pointer CHARACTER_POINTER >
325 string_base(CHARACTER_POINTER start, character_count length) : ::const_string_range<ITERATOR_TYPE>(no_initialize_t{}) { construct_from_range(start, length); }
326 template < character_pointer CHARACTER_POINTER >
327 string_base(CHARACTER_POINTER start, CHARACTER_POINTER end) : string_base(start, end-start) { }
328 template < character_pointer CHARACTER_POINTER >
329 string_base(CHARACTER_POINTER s1, CHARACTER_POINTER e1, CHARACTER_POINTER s2, CHARACTER_POINTER e2);
330 template < character_pointer CHARACTER_POINTER >
331 string_base(CHARACTER_POINTER start) : string_base(start, string_safe_length(start)) {}
332 template < prototype_character CHARACTER2 >
333 string_base(const CHARACTER2*start, character_count length, enum_range erange) :
334 string_base(start, start + length, erange) { }
335 //template < typename ITERATOR_TYPE2, ::i32 t_size >
336 //string_base(const const_string_range_static_array < ITERATOR_TYPE2, t_size >& a);
337 // template < prototype_character CHARACTER2 >
338// string_base(const CHARACTER2 * pszSource, character_count length);
339 template < prototype_character CHARACTER2, character_count sizeMaximumLength >
340 string_base(const inline_string < CHARACTER2, sizeMaximumLength > & inlinestring) :
341 string_base(inlinestring.begin(), inlinestring.end())
342 { }
343 // string_base(const_char_pointer pansichar, character_count length);
344 //string_base(::str < iterator > str) : string_base((const_iterator)str.begin(), (const_iterator)str.end()) {}
345 //string_base(::str < const_iterator > str) : string_base(str.begin(), str.end()) {}
346 //string_base(::block block) : string_base((const_iterator)block.begin(), (const_iterator)block.end()) {}
347 //string_base(const string_base & str);
348 //string_base(const ::wd16_character * pwd16char);
349 // string_base(const ::wd16_character * pwd16char, character_count length);
350 //string_base(const ::wd32_character * pwd32char);
351 // string_base(const ::wd32_character * pwd32char, character_count length);
352 // string_base(const ::wd32_character * pwd32char, character_count length, character_count pos) : string_base(pwd32char + pos, length) { }
353 //template < prototype_character CHARACTER2 >
354 string_base(const_iterator begin, const_iterator end) : string_base(begin, end - begin) { }
355 //string_base(const string_base & str) : string_base(str, 0, str.size()) { }
356 //string_base(const string_base & str, character_count length) : string_base(str, 0, length) { }
357 //string_base(const string_base & str, character_count length);
358// template < prototype_character CHARACTER2 >
359// string_base(const ::character_range < const CHARACTER2 * > & strSource) : string_base(strSource, 0, strSource.size()) {}
360// template < prototype_character CHARACTER2 >
361// string_base(const ::character_range < const CHARACTER2 * > & strSource, character_count length) : string_base(strSource, 0, minimum(strSource.size(), length)) {}
362// template < prototype_character CHARACTER2 >
363// string_base(const ::character_range < const CHARACTER2 * > & strSource, character_count length);
364 //string_base(const simple_ansistring& simpleansistr);
365 //string_base(const simple_wd16string& simplewd16str);
366 //string_base(const simple_wd32string& simplewd32str);
367 //template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
368 template < typename OTHER_CHARACTER >
369 string_base(OTHER_CHARACTER chSrc, character_count repeat = 1)
370 requires other_primitive_character < OTHER_CHARACTER, CHARACTER > ;
371 string_base(CHARACTER chSrc, character_count repeat = 1);
372 //string_base(::ansi_character ansich) : string_base(&ansich, 1) {}
373 //string_base(::wd16_character wd16ch) : string_base(&wd16ch, 1) {}
374 //string_base(::wd32_character wd32ch) : string_base(&wd32ch, 1) {}
375 //string_base(const ::scoped_string & scopedstr) :NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(str); }
376 //string_base(const ::scoped_wstring & scopedwstr) :NATURAL_POINTER(no_initialize_t{}) { construct_from_a_range(scopedwstr); }
377#if defined(__STD_FORMAT__)
378 string_base(const ::std::string & str) : string_base(str.c_str()) { }
379#endif
380 string_base(const ::atom & atom);
381 string_base(const ::payload & payload);
382 string_base(const ::property & property);
385 inline ~string_base()
386 {
387
388 destroy();
389
390 }
391
392
393 // inline static void string_data_increment_reference_count(ITERATOR_TYPE piterator)
394 // {
395 //
396 // auto pdataSource = BASE_DATA::base_data_from_data(piterator);
397 //
398 // pdataSource->base_data_increment_reference_count();
399 //
400 // }
401
402
403 // inline void __release()
404 // {
405 //
406 // auto pbasedata = this->base_data_from_data(this->m_begin);
407 //
408 // this->base_data_defer_release(pbasedata);
409 //
410 // }
411
412
413 // inline void _release()
414 // {
415 //
416 // if (this->has_string_storage() && ::is_set(this->m_begin))
417 // {
418 //
419 // __release();
420 //
421 // }
422 //
423 // }
424 //
425 //
426 inline void destroy()
427 {
428
429 if (this->has_string_storage() && ::is_set(this->m_begin))
430 {
431
432 ::base_data_defer_release(this->m_pbasedata);
433
434 }
435
436 this->m_begin = nullptr;
437
438 this->m_end = nullptr;
439
440 this->m_erange = e_range_none;
441
442 }
443
444
445
446 const ::block as_block() const { return { (::u8 *)this->begin(), this->character_count_in_bytes() }; }
447
448 static consteval bool is_null_terminated() { return true; }
449
450 void default_construct()
451 {
452
453 this->m_begin = ønil_character_data<CHARACTER>::get();
454
455 this->m_end = this->m_begin;
456
457 this->m_erange = e_range_string_literal;
458
459 this->m_pbasedata = nullptr;
460
461 }
462
463
464 /*void construct(typename NATURAL_POINTER::BASE_DATA * pNew)
465 {
466
467 NATURAL_POINTER::create_assign_natural_meta_data(pNew);
468
469 }*/
470
471
472 template < typed_character_pointer < typename scoped_string_base < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
473 void construct_from_a_range(CHARACTER_POINTER start, CHARACTER_POINTER end, enum_range erange = e_range_none, BASE_DATA * pbasedata = nullptr)
474 {
475
476 if (end <= start)
477 {
478
479 this->default_construct();
480
481 return;
482
483 }
484
485 if (::is_set(pbasedata))
486 {
487
488 this->m_begin = start;
489
490 this->m_end = end;
491
492 //this->m_erange = (enum_range) (erange & ~e_range_scoped_ownership);
493
494 this->m_pbasedata = pbasedata;
495
496 pbasedata->base_data_increment_reference_count();
497
498 return;
499
500 }
501
502 auto lengthNew = end - start;
503
504 pbasedata = create_string_data(lengthNew + 1);
505
506 auto pdata = pbasedata->data();
507
508 this->m_begin = pdata;
509
510 this->m_end = this->m_begin + lengthNew;
511
512 memory_transfer(pdata, start, lengthNew);
513
514 this->_set_length(lengthNew);
515
516 this->m_erange = e_range_none;
517
518 this->m_pbasedata = pbasedata;
519
520 }
521
522
523 template < other_character_pointer < typename scoped_string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER_POINTER >
524 void construct_from_a_range(OTHER_CHARACTER_POINTER start, OTHER_CHARACTER_POINTER end, enum_range erange = e_range_none)
525 {
526
527 auto length = end - start;
528
529 auto lengthNew = utf_to_utf_length(this->m_begin, start, length);
530
531 if (::is_null(start) || end <= start)
532 {
533
534 this->default_construct();
535
536 return;
537
538 }
539
540
541 auto pbasedata = BASE_DATA::create_base_data(lengthNew + 1);
542
543 auto pdata = pbasedata->data();
544
545 this->m_pbasedata = pbasedata;
546
547 this->m_erange = e_range_none;
548
549 this->m_begin = pdata;
550
551 utf_to_utf(this->m_begin, start, lengthNew);
552
553 this->_set_length(lengthNew);
554
555 }
556
557
558 void construct_from_string(const string_base& str);
559
560
561 //template < typename RANGE >
562 //void construct_from_a_range(const RANGE& range) requires
563 // ::std::is_base_of_v < ::character_range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE >
564 // && !
565 // (::std::is_base_of_v < string_base < ITERATOR_TYPE >, RANGE >
566 // || ::std::is_same_v < string_base < ITERATOR_TYPE >, RANGE >)
567 template < prototype_character_range RANGE >
568 void construct_from_a_range(const RANGE& range)
569 {
570
571 if (range.m_pbasedata)
572 {
573
574 if constexpr (sizeof(typename RANGE::ITEM) == sizeof(CHARACTER))
575 {
576
577 this->construct_from_string(*(const string_base*)&range);
578
579 }
580 else
581 {
582
583 this->construct_from_range(range.data(), range.size());
584
585 }
586
587 }
588 else if (range.m_erange & e_range_string_literal)
589 {
590
591 this->m_begin = range.m_begin;
592 this->m_end = range.m_end;
593 this->m_erange = range.m_erange;
594 this->m_pbasedata = nullptr;
595
596 }
597 else
598 {
599
600 this->construct_from_range(range.data(), range.size());
601
602 }
603
604 }
605
606
607 //template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
608
609 // template < typename OTHER_CHARACTER >
610 // void construct20(const ::character_range < const OTHER_CHARACTER* >& range)
611 // requires other_primitive_character < OTHER_CHARACTER, CHARACTER > ;
612
613
614 //inline void construct_from_string(const ITERATOR_TYPE psz, character_count length);
615
616 inline void construct2(const ::character_range < const CHARACTER * > & range);
617
618
619 inline void construct_from_range(ITERATOR_TYPE pSrc, character_count length);
620
621 template < typename OTHER_CHARACTER_POINTER >
622 inline void construct_from_range(OTHER_CHARACTER_POINTER pSrc, character_count length)
623 requires other_character_pointer < OTHER_CHARACTER_POINTER, ITERATOR_TYPE > ;
624
625 //template < prototype_character CHARACTER2 >
626 // //inline void construct_from_a_range(const ::character_range < const CHARACTER2 * > & range);
627
628 //template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER >
629 template < typename OTHER_CHARACTER >
630 inline void construct20(const OTHER_CHARACTER * psz, character_count length, enum_range erange)
631 requires (other_primitive_character < OTHER_CHARACTER, CHARACTER >);
632
633 //template < prototype_character CHARACTER2 >
634 //inline void construct_from_two_ranges_concatenation(const CHARACTER2* s1, character_count n1, const CHARACTER2* s2, character_count n2);
635
636
637
638 template < typename RANGE1, typename RANGE2 >
639 void construct_from_two_ranges_concatenation(const RANGE1& range1, const RANGE2& range2);
640
641 // template < prototype_character CHARACTER2 >
642// inline void construct2(const ::character_range < const CHARACTER2 * > & str);
643// template < prototype_character CHARACTER2 >
644// inline void construct2(const ::character_range < const CHARACTER2 * > & str);
645
646
647 template < prototype_character CHARACTER2 >
648 character_count start_count_length(character_count & start, character_count & count, const CHARACTER2 * pszSource);
649 //void start_count(character_count & start, character_count & count, character_count length);
650
651 inline const string_base & to_string() const { return *this; }
652
653
654 inline const CHARACTER *c_str() const { return this->data(); }
655
656 inline const CHARACTER *c_str_for_printf() const { return this->data(); }
657
658
659 using const_string_range<ITERATOR_TYPE>::begin;
660 using const_string_range<ITERATOR_TYPE>::end;
661
662
663 this_iterator & begin(this_iterator begin)
664 {
665
666 return erase_beginning(begin);
667
668 }
669
670
671 this_iterator & end(this_iterator end)
672 {
673
674 return truncate(end);
675
676 }
677
678
679 bool contains_erase(const SCOPED_STRING& scopedstr)
680 {
681
682 if (scopedstr.is_empty())
683 {
684
685 return true;
686
687 }
688
689
690 bool bContains = false;
691
692 while (true)
693 {
694
695 auto p = this->find(scopedstr);
696
697 if (::is_null(p))
698 {
699
700 return bContains;
701
702 }
703
704 bContains = true;
705
706 this->erase(p, scopedstr.size());
707
708 }
709
710 }
711
712
713 //#if OSBIT == 64
714 // inline const CHARACTER & operator [](::i32 i) const { return this->data()[i]; }
715 //#endif
716
717
718
719 //inline operator const CONST_STRING_RANGE & () const noexcept { return this->data(); }
720
721//#if defined(UNIVERSAL_WINDOWS)
722 //inline operator String ^ () const { return ref allocateø< String(wd16_string >(*this)); }
723//#endif
724
725 string_base to_string_base() const { return *this; }
726 const BASE_RANGE & to_string_base() { return *this; }
727
728 using BASE_RANGE::operator ==;
729 using BASE_RANGE::operator <=>;
730
731 bool operator==(const string_base & str) const { return this->equals(str); }
732 ::std::strong_ordering operator<=>(const string_base & str) const { return this->order(str); }
733
734
735 //template < typename T >
736 //string_base & operator << (const T & t)
737 //{
738
739 // assign(t);
740
741 // return *this;
742
743 //}
744
745
746 //string_base & operator = (const string_base & str);
747// {
748// return *this;
749// }
750// string_base & operator = (const wd16_string & str)
751// {
752// if constexpr (sizeof(CHARACTER) == sizeof(wd16_character))
753// {
754// NATURAL_POINTER::operator=(str);
755// }
756// else
757// {
758// assign(str);
759// }
760// return *this;
761// }
762// string_base & operator = (const wd32_string & str)
763// {
764// if constexpr (sizeof(CHARACTER) == sizeof(wd32_character))
765// {
766// NATURAL_POINTER::operator=(str);
767// }
768// else
769// {
770// assign(str);
771// }
772// return *this;
773// }
774// string_base & operator = (string_base && string_base) { NATURAL_POINTER::operator=(::transfer(string_base)); return *this; }
781 //string_base & operator = (const ::atom & atom);
782 //string_base & operator = (const ::payload & payload);
783 //string_base & operator = (const ::property & property);
786 //template < character_count n >
787 //string_base & operator = (const ::inline_string < ::ansi_character, n > & inlinestring) { assign(inlinestring.begin(), inlinestring.size()); return *this; }
795
796 // //string_base & operator = (const_char_pointer pansichar);
797 // //string_base & operator = (const ::wd16_character * pwd16char);
798 // //string_base & operator = (const ::wd32_character * pwd32char);
799 // //string_base & operator = (const natural_ansistring & ansistr);
800 // //string_base & operator = (const natural_wd16string & wd16str);
801 // //string_base & operator = (const natural_wd32string & wd32str);
808
809 string_base &operator =(const string_base & str)
810 {
811 this->assign_range(str);
812 return *this;
813 }
814
815
816
817 template < typename RANGE >
818 string_base & operator = (const RANGE & str) requires
819 (::std::is_base_of_v < ::character_range < const typename string_base < ITERATOR_TYPE >::CHARACTER* >, RANGE >
820 && !
821 (::std::is_base_of_v < string_base < ITERATOR_TYPE >, RANGE >
822 || ::std::is_same_v < string_base < ITERATOR_TYPE >, RANGE >))
823 {
824 this->assign_range(str);
825 return *this;
826 }
827
828
829 template < prototype_character_range SOME_RANGE >
830 string_base &operator=(SOME_RANGE && range)
831 {
832 this->transfer_range(::transfer(range));
833 return *this;
834 }
835
836
837 //string_base &operator=(string_base &&str)
838 //{
839 // transfer_range(::transfer(str));
840 // return *this;
841 //}
842
843//
844//
845// //template<prototype_character MAY_BE_OTHER_CHARACTER>
846// //string_base &operator=(MAY_BE_OTHER_CHARACTER character)
847// //{
848// // assign(character);
849// // return *this;
850// //}
851//
852//
853// //template<prototype_character MAY_BE_OTHER_CHARACTER>
854// //string_base &operator=(const MAY_BE_OTHER_CHARACTER * psz)
855// //{
856// // assign(psz);
857// // return *this;
858// //}
859//
860// //template<typename MAY_BE_OTHER_CHARACTER_RANGE>
861// //string_base &operator=(const MAY_BE_OTHER_CHARACTER_RANGE &range)
862// // requires (other_character_range<MAY_BE_OTHER_CHARACTER_RANGE, CHARACTER> ||
863// // !::std::is_base_of< string_base, MAY_BE_OTHER_CHARACTER_RANGE>::value)
864// //{
865// // assign_range(range);
866// // return *this;
867// //}
868//
869//
870// template < prototype_block BLOCK >
871// string_base & operator = (const BLOCK & block) { assign((const CHARACTER *)block.begin(), (const CHARACTER *)block.end()); return *this; }
872// //template < prototype_character CHARACTER2 >
873// //string_base & operator = (const ::character_range < const CHARACTER2 * > & str);
874// //string_base & operator = (string_base && str);
875// string_base & operator = (const ::inline_number_string & inline_number_string) {assign(inline_number_string.begin(), inline_number_string.end()); return *this;}
876// string_base & operator = (const scoped_ansi_string & ansistr);
877// string_base & operator = (const scoped_wd16_string & wd16str);
878// string_base & operator = (const scoped_wd32_string & wd32str);
879//#ifdef __STD_FORMAT__
880// string_base& operator = (const ::std::string &str) { operator =(str.c_str()); return *this; }
881//#endif
882// //string_base & operator = (const string_base & str);
883// //string_base & operator = (const string_base & str);
884// //string_base & operator = (::ansi_character ansich);
885// //string_base & operator = (::wd16_character wd16ch);
886// // string_base & operator = (::wd32_character wd32ch);
887// //#ifdef WINDOWS
888// // string_base & operator = (const USHORT * pshSrc) { return operator=((const ::wd16_character *)pshSrc); }
889// //#endif
890// //#ifdef UNIVERSAL_WINDOWS
891// // string_base& operator = (String^& str) { return operator=(str->Begin()); }
892// //#endif
893// //string_base & operator = (const ::atom & atom);
894// //string_base & operator = (const ::payload & payload);
895// //string_base & operator = (const ::property & property);
896//
897 // template < ::i32 t_nSize >
898 // inline string_base & operator=(const static_string<CHARACTER, t_nSize > & ansistrSrc);
899
900 //template < typename TYPE >
901 //inline string_base & operator=(const TYPE & t);
902
903 // maybe it doesn't because of ambiguity with global
904 // += operators... (in all compilers MSVC++, LLVM, GCC...)
905 //template < typename TYPE >
906 //string_base& operator += (const TYPE & t);
907
908 // maybe it doesn't because of ambiguity with global
909 // += operators... (in all compilers MSVC++, LLVM, GCC...)
910 //string_base & operator += (const ::string_base < CHARACTER > & str);
911
912
913 // so exhaustively implementing them at least
914 // for most relevant and proper acme types
915 string_base & operator += (const SCOPED_STRING & scopedstr);
916
917 template < prototype_character CHARACTER >
918 string_base & operator += (CHARACTER character) { this->append_character(character); return *this; }
919
920 // string_base & operator += (const_char_pointer psz) { append(psz); return *this; }
921 // string_base & operator += (const ::wd16_character * psz) { append(psz); return *this; }
922 // string_base & operator += (const ::wd32_character * psz) { append(psz); return *this; }
923 // string_base & operator += (::ansi_character ansich) { append(&ansich, 1); return *this; }
924 // string_base & operator += (::wd16_character wd16ch) { append(&wd16ch, 1); return *this; }
925 // string_base & operator += (::wd32_character wd32ch) { append(&wd32ch, 1); return *this; }
926 // string_base & operator += (const ::const_ansi_range & range) { append(range); return *this; }
927 // string_base & operator += (const ::const_wd16_range & range) { append(range); return *this; }
928 // string_base & operator += (const ::const_wd32_range & range) { append(range); return *this; }
929 // string_base & operator += (const inline_number_string & inlinenumberstring) { append((const ::const_ansi_range &)inlinenumberstring); return *this; }
930 // string_base & operator += (const ::atom & atom);
931 // string_base & operator += (const ::payload & payload);
932 // string_base & operator += (const ::property & property);
933 //template < typename ITERATOR_TYPE2, ::i32 t_size >
934 //string_base& operator += (const const_string_range_static_array < ITERATOR_TYPE2, t_size >& a) { return append(a); }
935//#ifdef __STD_FORMAT__
936 //string_base& operator += (const ::std::string& str) { operator +=(str.c_str()); return *this; }
937//#endif
938// template < has_as_string HAS_AS_STRING >
939// string_base & operator += (const HAS_AS_STRING & has_as_string) { return operator +=(has_as_string.as_string()); }
940
941
942// template < ::i32 t_nSize >
943// inline string_base & operator +=(const static_string<CHARACTER, t_nSize > & ansistrSrc);
944//
945// template < typename TYPE >
946// inline string_base & operator +=(const TYPE & t);
947//
948
949// template < prototype_character CHARACTER2 >
950// string_base operator + (const CHARACTER2 * psz) const { auto str = *this; str.append(scopedstr); return ::transfer(str); }
951
952
953 // maybe it doesn't because of ambiguity with global
954 // + operators... (in all compilers MSVC++, LLVM, GCC...)
955 //template < typename TYPE >
956 //inline string_base operator +(const TYPE & t) const;
957
958 // maybe it doesn't because of ambiguity with global
959 // + operators... (in all compilers MSVC++, LLVM, GCC...)
960 //inline string_base operator +(const ::string_base < CHARACTER > & str) const;
961
962 // so exhaustively implementing them at least
963 // for most relevant and proper acme types
964 //string_base operator + (::const_ansi_range ansirange) const;
965 //string_base operator + (::const_wd16_range wd16range) const;
966 //string_base operator + (::const_wd32_range wd32range) const;
967 //string_base operator + (const ansi_string & ansistr) const;
968 //string_base operator + (const wd16_string & wd16str) const;
969 //string_base operator + (const wd32_string & wd32str) const;
970 //string_base operator + (const inline_number_string & inlinenumberstring) const;
971 //string_base operator + (::ansi_character ansich) const;
972 //string_base operator + (::wd16_character wd16ch) const;
973 //string_base operator + (::wd32_character wd32ch) const;
974 //template < prototype_character CHARACTER2 >
975 //string_base operator + (const array_range < CHARACTER2 > & block) const { return *this + string_base(block); }
976
977
978 //template < prototype_payload PAYLOAD >
979 //string_base operator + (const PAYLOAD & payload) const { return *this + payload.as_string(); }
980
981 //template < prototype_atom ATOM >
982 //string_base operator + (const ATOM & atom) const { return *this + atom.as_string(); }
983
984
985// template < typename TYPE >
986// inline string_base & operator /=(const TYPE & t)
987// // template < typename TYPE >
988// //inline string_base & operator /=(const ::string_base < CHARACTER > & str)
989// {
990//
991// string_base strRight(t);
992//
993// trim_right(string_base("\\/"_ansi));
994//
995// strRight.trim_left(string_base("\\/"_ansi));
996//
997// return this->operator += ("/"_ansi + strRight);
998//
999// }
1000
1001
1002
1003 string_base& surround(const SCOPED_STRING& scopedstr);
1004
1005 string_base& surround(const SCOPED_STRING& scopedstrLeft, const SCOPED_STRING& scopedstrRight);
1006
1007 string_base& f64_quote(bool bEscape = false);
1008
1009 string_base& single_quote(bool bEscape = false);
1010
1011// template < typename TYPE >
1012// inline string_base operator /(const TYPE & t) const
1013// //inline string_base operator /(const ::string_base < CHARACTER > & str) const
1014// {
1015//
1016// string_base strRight(t);
1017//
1018// string_base str(*this);
1019//
1020// str /= strRight;
1021//
1022// return str;
1023//
1024// }
1025
1026
1027 ::character_count size_with_null_terminator() const
1028 {
1029
1030 return this->size() + 1;
1031
1032 }
1033
1034
1035 ::character_count size_in_bytes_with_null_terminator() const
1036 {
1037
1038 return this->size_with_null_terminator() * this->item_size();
1039
1040 }
1041
1042
1043 inline const ::block block_with_null_terminator() const;
1044
1045
1046 template<typename SAME_CHARACTER_RANGE >
1047 string_base &assign_range(const SAME_CHARACTER_RANGE & range)
1048 requires (typed_character_range<SAME_CHARACTER_RANGE, CHARACTER>)
1049 {
1050
1051 if ((::character_range<const CHARACTER *> *)(this) == (::character_range<const CHARACTER *> *)(&range))
1052 {
1053
1054 return *this;
1055
1056 }
1057
1058 auto pdataThis = this->m_pbasedata;
1059
1060 if (range.m_pbasedata)
1061 {
1062
1063 this->m_begin = range.m_begin;
1064
1065 this->m_end = range.m_end;
1066
1067 //this->m_erange = (enum_range)(range.m_erange & ~e_range_scoped_ownership);
1068
1069 this->m_pbasedata = range.m_pbasedata;
1070
1071 this->m_pbasedata->base_data_increment_reference_count();
1072
1073 }
1074 else if (::is_null(range.m_begin) || range.m_end <= range.m_begin)
1075 {
1076
1077 this->default_construct();
1078
1079 }
1080 else
1081 {
1082
1083 auto length = range.size();
1084
1085 auto lengthNew = string_safe_length2(range.m_begin, length);
1086
1087 if (::is_set(pdataThis) &&
1088 !pdataThis->base_data_is_shared() &&
1089 lengthNew <= pdataThis->storage_character_count())
1090 {
1091
1092 pdataThis = nullptr;
1093
1094 }
1095 else
1096 {
1097
1098 auto pbasedata = this->create_string_data2(lengthNew, this->m_erange);
1099
1100 this->m_begin = pbasedata->data();
1101
1102 }
1103
1104 ::memory_transfer((void *) this->m_begin, range.m_begin, sizeof(CHARACTER) * lengthNew);
1105
1106 this->_set_length(lengthNew);
1107
1108 }
1109
1110 if (pdataThis)
1111 {
1112
1113 ::base_data_defer_release(pdataThis);
1114
1115 }
1116
1117 return *this;
1118
1119 }
1120
1121
1122 template<typename SAME_CHARACTER_RANGE>
1123 string_base &transfer_range(SAME_CHARACTER_RANGE &&range)
1124 requires(typed_character_range<SAME_CHARACTER_RANGE, CHARACTER>)
1125 {
1126
1127 if((::character_range<const CHARACTER *>*)(this) == (::character_range<const CHARACTER *>*)(&range))
1128 {
1129
1130 return *this;
1131
1132 }
1133
1134 auto pdataThis = this->m_pbasedata;
1135
1136 if (::is_set(range.m_pbasedata))
1137 {
1138
1139 this->m_begin = range.m_begin;
1140
1141 this->m_end = range.m_end;
1142
1143 //this->m_erange = (enum_range) (range.m_erange & ~e_range_scoped_ownership);
1144
1145 this->m_pbasedata = range.m_pbasedata;
1146
1147 }
1148 else if (::is_null(range.m_begin) || range.m_end <= range.m_begin)
1149 {
1150
1151 this->default_construct();
1152
1153 }
1154 else
1155 {
1156
1157 auto lengthNew = range.size();
1158
1159 if (::is_set(pdataThis) &&
1160 !pdataThis->base_data_is_shared() &&
1161 lengthNew <= pdataThis->storage_character_count())
1162 {
1163
1164 pdataThis = nullptr;
1165
1166 }
1167 else
1168 {
1169
1170 auto pbasedata = this->create_string_data2(lengthNew, this->m_erange);
1171
1172 this->m_begin = pbasedata->data();
1173
1174 }
1175
1176 ::memory_transfer((void *) this->m_begin, range.m_begin, sizeof(CHARACTER) * lengthNew);
1177
1178 this->_set_length(lengthNew);
1179
1180 }
1181
1182 if (pdataThis)
1183 {
1184
1185 ::base_data_defer_release(pdataThis);
1186
1187 }
1188
1189 range.m_begin = nullptr;
1190
1191 range.m_end = nullptr;
1192
1193 range.m_erange = e_range_none;
1194
1195 range.m_pbasedata = nullptr;
1196
1197 return *this;
1198
1199
1200 }
1201
1202
1203 template<typename OTHER_CHARACTER_RANGE>
1204 string_base &assign_range(const OTHER_CHARACTER_RANGE &range)
1205 requires(other_character_range<OTHER_CHARACTER_RANGE, CHARACTER>)
1206 {
1207
1208 this->assign(range.m_begin, range.m_end);
1209
1210 return *this;
1211
1212 }
1213
1214
1215 template < typename OTHER_CHARACTER_RANGE >
1216 inline string_base & transfer_range(OTHER_CHARACTER_RANGE && range)
1217 requires(other_character_range<OTHER_CHARACTER_RANGE, CHARACTER>)
1218 {
1219
1220 this->assign(range.m_begin, range.m_end);
1221
1222 range.m_begin = nullptr;
1223
1224 range.m_end = nullptr;
1225
1226 range.m_erange = e_range_none;
1227
1228 return *this;
1229
1230 }
1231
1232
1233 template < prototype_block BLOCK >
1234 inline string_base & assign(const BLOCK & block) { return assign((const CHARACTER *)block.data(),(const CHARACTER *) block.end()); }
1235
1236 // template < prototype_character CHARACTER2 >
1237 // inline string_base& assign(const ::character_range < const CHARACTER2 * > & str);
1238 //inline string_base & assign(const ansi_string & ansistr);
1239 //inline string_base & assign(const wd16_string & wd16str);
1240 //inline string_base & assign(const wd32_string & wd32str);
1241 //inline string_base & assign(const_char_pointer pansiszSrc);
1242 //inline string_base & assign(const ::wd16_character * pwd16szSrc);
1243 //inline string_base & assign(const ::wd32_character * pwd32szSrc);
1244 //inline string_base & assign(::ansi_character ansich);
1245 //inline string_base & assign(::wd16_character wd16ch);
1246 //inline string_base & assign(::wd32_character wd32ch);
1247
1248
1249 inline string_base& assign(const_iterator start)
1250 {
1251
1252 return assign(start, string_safe_length(start));
1253
1254 }
1255
1256
1257 inline string_base& assign(const_iterator start, const_iterator end)
1258 {
1259
1260 return assign(start, end - start);
1261
1262 }
1263
1264
1265 template < prototype_character CHARACTER2 >
1266 inline string_base & assign(const CHARACTER2 * start, const CHARACTER2 * end);
1267
1268
1269 template < prototype_character CHARACTER2 >
1270 inline string_base & assign(const CHARACTER2 * pszSrc, character_count length);
1271
1272
1273 template < prototype_character CHARACTER2 >
1274 inline string_base & assign(const CHARACTER2 * pszSrc)
1275 {
1276
1277 return assign(pszSrc, string_safe_length(pszSrc));
1278
1279 }
1280
1281
1282 //inline string_base& assign(const wd16_string& wd16str);
1283 //inline string_base& assign(const wd32_string& wd32str);
1284// template < prototype_character CHARACTER2 >
1285// inline string_base & assign(const CHARACTER2 * pszSrc, character_count length)
1286// {
1287// return assign(scopedstrSrc, 0, length);
1288// }
1289 //template < prototype_block BLOCK >
1290 //inline string_base& assign(const BLOCK & pszSrc, character_count length);
1291 template < prototype_character SAME_SIZE_CHARACTER >
1292 inline string_base & _assign(const SAME_SIZE_CHARACTER * pszSrc, character_count length)
1293 requires (sizeof(SAME_SIZE_CHARACTER) == sizeof(CHARACTER));
1294
1295 template < prototype_character OTHER_SIZE_CHARACTER >
1296 inline string_base & _assign(const OTHER_SIZE_CHARACTER * pszSrc, character_count length)
1297 requires (sizeof(OTHER_SIZE_CHARACTER) != sizeof(CHARACTER));
1298 //inline string_base& assign(const ::wd16_character* pwd16szSrc, character_count length);
1299 //inline string_base& assign(const ::wd32_character* pwd32szSrc, character_count length);
1300 template < prototype_character CHARACTER2 >
1301 inline string_base & assign(CHARACTER2 chSrc, character_count repeat = 1);
1302 // inline string_base & assign(::ansi_character ansich, character_count repeat);
1303 // inline string_base & assign(::wd16_character wd16ch, character_count repeat);
1304 // inline string_base & assign(::wd32_character wd32ch, character_count repeat);
1305
1306 //template <class InputIterator>
1307 //inline string_base & assign(InputIterator first, InputIterator last);
1308
1309 //template < ::i32 t_nSize >
1310 //inline string_base & assign(const static_string<CHARACTER, t_nSize > & ansistrSrc);
1311
1312
1313 //template < ::i32 t_size >
1314 //inline string_base & assign(const const_string_range_static_array< const CHARACTER *, t_size > & a);
1315
1316 //template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
1317 //inline string_base & assign(const const_string_range_static_array< const OTHER_CHARACTER *, t_size > & a);
1318
1319
1320
1321
1322
1323
1324 inline string_base & append(character_count length, CHARACTER ch);
1325 template < prototype_character CHARACTER2 >
1326 inline string_base & append_character_array(const CHARACTER2 * psz, character_count length)
1327 { auto pszEnd = psz + length; if(*(pszEnd - 1) == 0) pszEnd--; append(psz, pszEnd - psz); }
1328
1329 inline string_base & append_character(::wd32_character wch);
1330 inline string_base & append_character(::ansi_character ch);
1331 inline string_base & append_character(::wd16_character wch);
1332
1333
1334 //inline string_base & append(const ::const_ansi_range & range);
1335 //inline string_base & append(const ::const_wd16_range & range);
1336 //inline string_base & append(const ::const_wd32_range & range);
1337
1338
1339 inline string_base& append(const ::character_range < ITERATOR_TYPE >& range){ _append(range.m_begin, range.size()); return *this; }
1340
1341
1342 template < typename OTHER_CHARACTER >
1343 inline string_base& append(const ::character_range < const OTHER_CHARACTER* >& range)
1344 requires other_primitive_character < OTHER_CHARACTER, CHARACTER >
1345 {_append(range.m_begin, range.size()); return *this; }
1346
1347
1348 //inline string_base & append(const_char_pointer psz) { return _append(psz, string_safe_length(psz)); }
1349 //inline string_base & append(const ::wd16_character * psz) { return _append(psz, string_safe_length(psz)); }
1350 //inline string_base & append(const ::wd32_character * psz) { return _append(psz, string_safe_length(psz)); }
1351
1352 inline string_base& append(ITERATOR_TYPE psz) { return _append(psz, string_safe_length(psz)); }
1353
1354 template < typename OTHER_CHARACTER >
1355 inline string_base& append(const OTHER_CHARACTER * psz)
1356 requires other_primitive_character < OTHER_CHARACTER, CHARACTER >
1357 { return _append(psz, string_safe_length(psz)); }
1358
1359
1360 //inline string_base & append(const_char_pointer psz, character_count size) { return _append(psz, size); }
1361 //inline string_base & append(const ::wd16_character * psz, character_count size) { return _append(psz, size); }
1362 //inline string_base & append(const ::wd32_character * psz, character_count size) { return _append(psz, size); }
1363
1364
1365 inline string_base& append(const CHARACTER * psz, character_count size) { return _append(psz, size); }
1366
1367 template < typename OTHER_CHARACTER >
1368 inline string_base& append(const OTHER_CHARACTER* psz, character_count size)
1369 requires other_primitive_character < OTHER_CHARACTER, CHARACTER >{ return _append(psz, size); }
1370
1371
1372 inline string_base < ITERATOR_TYPE > & _append(const CHARACTER * pszSrc, character_count count);
1373
1374 template < typename OTHER_CHARACTER >
1375 inline string_base < ITERATOR_TYPE >& _append(const OTHER_CHARACTER * pszSrc, character_count count)
1376 requires other_primitive_character < OTHER_CHARACTER, CHARACTER >;
1377
1378 //template <::i32 t_size >
1379 //inline string_base < ITERATOR_TYPE > & append(const const_string_range_static_array < ITERATOR_TYPE, t_size > & a);
1380
1381 //template <other_primitive_character<typename string_base < ITERATOR_TYPE >::CHARACTER> CHARACTER2, ::i32 t_size >
1382 //inline string_base < ITERATOR_TYPE > & append(const const_string_range_static_array < const CHARACTER2 *, t_size > & a);
1383
1384 //inline string_base & append(const ::wd16_character * pszSrc);
1385 //inline string_base & append(const ::wd16_character * pszSrc, character_count nLength);
1386 //inline string_base & append(const wd16_string & ansistrSrc);
1387
1388 //inline string_base & append(const ::wd32_character * pszSrc);
1389 //inline string_base & append(const ::wd32_character * pszSrc, character_count nLength);
1390 //inline string_base & append(const wd32_string & ansistrSrc);
1391
1392 //template < ::i32 t_size >
1393 //inline string_base & append(const const_string_range_static_array< const CHARACTER *, t_size > & a);
1394
1395 //template < other_primitive_character < typename string_base < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER, ::i32 t_size >
1396 //inline string_base & append(const const_string_range_static_array< const OTHER_CHARACTER *, t_size > & a);
1397 inline string_base & append(const ::atom & atom);
1398 inline string_base & append(const ::payload & payload);
1399 inline string_base & append(const ::property & property);
1400
1401
1402 inline string_base & concatenate_with_separator(const SCOPED_STRING & scopedstrSeparator, const SCOPED_STRING & scopedstr);
1403
1404
1405 inline void empty()
1406 {
1407
1408 if (this->has_string_storage())
1409 {
1410
1411 ::base_data_defer_release(this->m_pbasedata);
1412
1413 }
1414
1415 default_construct();
1416
1417 //}
1418 //else
1419 //{
1420
1421
1422 //}
1423
1424 }
1425
1426
1427 //inline CHARACTER * get_buffer(bool bPreserve = false)
1428 //{
1429
1430 // auto p = this->metadata();
1431
1432 // ASSERT(p->m_countReference >= 1);
1433
1434 // if (p->natural_is_shared())
1435 // {
1436
1437 // fork_string(p->character_count(), bPreserve);
1438
1439 // }
1440
1441 // return (CHARACTER *) this->data();
1442
1443 //}
1444
1445
1446 //template < bool t_bPreserve >
1447 //inline CHARACTER * _create_string(character_count character_count)
1448 //{
1449
1450 // auto pNew = this->base_data_create(character_count);
1451
1452 // auto pbuffer = pNew->data();
1453
1454 // if constexpr (t_bPreserve)
1455 // {
1456
1457 // auto s = this->size();
1458
1459 // if (s > 0)
1460 // {
1461
1462 // ::memory_copy(pbuffer, this->m_begin, minimum(s, character_count) * sizeof(CHARACTER));
1463
1464 // }
1465
1466 // }
1467
1468 // this->m_begin = new_begin;
1469
1470 // this->m_end = new_begin + character_count;
1471
1472 // this->set_string_flag();
1473
1474 // return new_begin;
1475
1476 //}
1477
1478
1479
1480
1481 // inline CHARACTER * construct_string(character_count character_count)
1482 // {
1483 //
1484 // auto pbasedata = BASE_DATA::create_base_data(character_count + 1);
1485 //
1486 // this->m_begin = pbasedata->data();
1487 //
1488 // this->m_end = this->m_begin + character_count;
1489 //
1490 // this->m_erange = e_range_none;
1491 //
1492 // this->m_pbasedata = pbasedata;
1493 //
1494 // return (CHARACTER *) this->m_begin;
1495 //
1496 // }
1497
1498
1499 inline auto_string_buffer<ITERATOR_TYPE> auto_release_buffer(character_count characterCount = -1);
1500
1501
1502 template < bool t_bPreserve = false>
1503 inline CHARACTER * get_buffer(character_count characterCount = -1)
1504 {
1505
1506 this->defer_set_size<t_bPreserve>(characterCount);
1507
1508 return (CHARACTER*)this->m_begin;
1509
1510// auto p = (CHARACTER *) this->m_begin;
1511//
1512// if (::is_set(this->m_pbasedata))
1513// {
1514//
1515// auto pbasedata = this->m_pbasedata;
1516//
1517// #ifdef _DEBUG
1518//
1519// if (::is_set(pbasedata) && pbasedata->m_countReference <= 0)
1520// {
1521//
1522// __what__(1);
1523//
1524// }
1525//
1526// #endif
1527//
1528// if (::is_null(pbasedata) || pbasedata->base_data_is_shared() || characterCount > pbasedata->storage_character_count())
1529// {
1530//
1531// defer_set_size<true, t_bPreserve >(characterCount > 0 ? characterCount : this->size());
1532//
1533// }
1534// else
1535// {
1536//
1537// this->m_end = this->m_begin + (characterCount > 0 ? characterCount : this->size());
1538//
1539// }
1540// //else
1541// //{
1542//
1543// // this->metadata()->set_character_count(characterCount);
1544//
1545// // this->m_end = this->m_begin + characterCount;
1546//
1547// //}
1548//
1549// }
1550// else
1551// {
1552//
1553// p = create_string<t_bPreserve>(characterCount);
1554//
1555// }
1556//
1557// return p;
1558
1559 }
1560
1561
1562 inline mutable_string_range < CHARACTER * > get_range_buffer(character_count characterCount)
1563 {
1564
1565 auto p = get_buffer(characterCount);
1566
1567 return { p, p + characterCount };
1568
1569 }
1570
1571
1572 inline void release_range_buffer(const mutable_string_range < CHARACTER * > & range)
1573 {
1574
1575 if(range.m_end > (this->m_begin + this->storage_character_count()))
1576 {
1577
1578 throw_exception(error_invalid_buffer);
1579
1580 }
1581
1582 ::memory_transfer((CHARACTER *) this->m_begin, range.m_begin, range.size());
1583
1584 release_buffer(range.size());
1585
1586 }
1587
1588
1589 // inline CHARACTER * defer_get_string_buffer(character_count size, const string_base & str)
1590 // {
1591
1592 // auto p = this->metadata();
1593
1594 // ASSERT(p->m_countReference >= 1);
1595
1596 // if (::is_null(p) || p->natural_is_shared() || size > p->length() || p->contains_data(str))
1597 // {
1598
1599 // fork_string(size);
1600
1601 // }
1602
1603 // this->metadata()->set_length(size);
1604
1605 // return this->data();
1606
1607 // }
1608
1609
1610 inline void get_string(CHARACTER * psz) const noexcept;
1611
1612// inline const CHARACTER * get_string() const noexcept { return this->data(); }
1613
1614
1615 inline bool if_empty_set_to(const string_base & str)
1616 {
1617
1618 if (!this->is_empty())
1619 {
1620
1621 return false;
1622
1623 }
1624
1625 operator =(str);
1626
1627 return true;
1628
1629 }
1630
1631
1632 inline static string_base empty_string() { return string_base(); }
1633
1634 string_base & release_buffer(character_count nNewLength = -1);
1635
1636
1637 inline this_iterator truncate_on_find_character(CHARACTER ch);
1638
1639 inline this_iterator & truncate(this_iterator p);
1640 template < prototype_integral INTEGRAL >
1641 inline this_iterator & truncate(INTEGRAL count) {return truncate(this->m_begin + count);}
1642
1643 template < prototype_integral INTEGRAL >
1644 inline this_iterator & rear_truncate(INTEGRAL count)
1645 {
1646
1647 auto count2 = ::minimum(this->length(), count);
1648
1649 return this->truncate(this->length() - count2);
1650
1651 }
1652
1653
1654
1655 template < prototype_integral INTEGRAL >
1656 inline string_base truncated(INTEGRAL count) const
1657 {
1658
1659 if (this->length() <= count)
1660 {
1661
1662 return *this;
1663
1664 }
1665
1666 return this->left(count);
1667
1668 }
1669
1670 //string_base right(character_count nCount) const { return *this = BASE_RANGE::right(nCount); }
1671
1672 //string_base left(character_count count) const { return *this = BASE_RANGE::left(nCount); }
1673
1674 //string_base left(const_iterator p) const { return *this = BASE_RANGE::left(p); }
1675
1676 //string_base left_including_any_character_in(const SCOPED_STRING& scopedstrCharSet) const { return *this = BASE_RANGE::left_including_any_character_in(scopedstrCharSet); }
1677
1678 //string_base left_skipping_any_character_in(const SCOPED_STRING& scopedstrCharSet) const { return *this = BASE_RANGE::left_skipping_any_character_in(scopedstrCharSet); }
1679
1680
1681
1682 inline this_iterator & erase_beginning(this_iterator p);
1683
1684 inline void set_at(character_count iChar, CHARACTER ch);
1685
1686
1687 //inline BASE_DATA * create_meta_data(character_count characterCount)
1688 //{
1689
1690 // auto newNullTerminatedByteCount = null_terminated_character_count_to_byte_length(this->begin(), characterCount);
1691
1692 // auto pbasedata = this->_create_meta_data(newNullTerminatedByteCount);
1693
1694 // pbasedata->m_countData = characterCount;
1695
1696 // return pbasedata;
1697
1698 //}
1699
1701 template < bool t_bPreserve >
1702 inline CHARACTER* create_string(character_count character_count)
1703 {
1704
1705 return fork_string< false, t_bPreserve >(character_count);
1706
1707 }
1708
1709
1718 template < bool t_bPreserve >
1719 //inline CHARACTER * fork_string(character_count characterCount)
1720 inline void defer_set_size(character_count characterCount)
1721 {
1722
1723 auto old_size = this->size();
1724
1725 auto lengthNew = characterCount < 0 ? old_size + characterCount + 1 : characterCount;
1726
1727 auto pbasedataOld = this->m_pbasedata;
1728
1729 auto pdataOld = this->m_begin;
1730
1733 if (::is_set(pbasedataOld) &&
1734 !pbasedataOld->base_data_is_shared() &&
1735 lengthNew <= pbasedataOld->storage_character_count())
1736 {
1737
1738// this->_set_length(lengthNew);
1739
1740 //return (CHARACTER *) this->m_begin;
1741
1742 return;
1743
1744 }
1745
1746 //auto allocationSize
1747
1748 //if constexpr(t_bWasString)
1749 //{
1750
1751 // if (this->m_erange & e_range_buffer && lengthNew >= 16_KiB)
1752 // {
1753
1754 // allocationSize *= 2;
1755
1756 // }
1757
1758 //}
1759
1760 auto pbasedata = this->create_string_data2(lengthNew, this->m_erange);
1761
1762 auto pdata = pbasedata->data();
1763
1764 if (pbasedataOld)
1765 {
1766
1767 ASSERT(::is_null(pbasedataOld) || pbasedataOld->m_countReference >= 1);
1768
1769 }
1770
1771 if (::is_set(pdataOld))
1772 {
1773
1774 if constexpr (t_bPreserve)
1775 {
1776
1777 auto sizeCopy = minimum(old_size, lengthNew);
1778
1779 if (sizeCopy > 0)
1780 {
1781
1782 memory_copy((void*)pdata, pdataOld, sizeCopy * sizeof(CHARACTER));
1783
1784 }
1785
1786 }
1787
1788 }
1789
1790 if (::is_set(pbasedataOld))
1791 {
1792
1793 //if constexpr (t_bWasString)
1794 //{
1795
1796 ::base_data_defer_release(pbasedataOld);
1797
1798 //}
1799
1800 }
1801
1802 this->m_begin = pdata;
1803
1804 //this->_set_length(lengthNew);
1805
1806 //return pdata;
1807
1808 }
1809
1810
1811 // /// draft: all allocation, release and assignment done
1812 // template < bool t_bWasString, bool t_bPreserve >
1813 // inline CHARACTER * fork_string(character_count characterCount)
1814 // {
1815 //
1816 // auto old_size = this->size();
1817 //
1818 // auto lengthNew = characterCount;
1819 //
1820 // auto pbasedataOld = this->m_pbasedata;
1821 //
1822 // auto pdataOld = this->m_begin;
1823 //
1824 // /// if this string had heap string storage,
1825 // /// checks if old storage can hold new requested size.
1826 // if constexpr (t_bWasString)
1827 // {
1828 //
1829 // if (::is_set(pbasedataOld) &&
1830 // !pbasedataOld->base_data_is_shared() &&
1831 // lengthNew <= pbasedataOld->storage_character_count())
1832 // {
1833 //
1834 // this->_set_length(lengthNew);
1835 //
1836 // return (CHARACTER *) this->m_begin;
1837 //
1838 // }
1839 //
1840 // }
1841 //
1842 // //auto allocationSize
1843 //
1844 // //if constexpr(t_bWasString)
1845 // //{
1846 //
1847 // // if (this->m_erange & e_range_buffer && lengthNew >= 16_KiB)
1848 // // {
1849 //
1850 // // allocationSize *= 2;
1851 //
1852 // // }
1853 //
1854 // //}
1855 //
1856 // auto pbasedata = this->create_string_data2(lengthNew, this->m_erange);
1857 //
1858 // auto pdata = pbasedata->data();
1859 //
1860 // if constexpr (t_bWasString)
1861 // {
1862 //
1863 // ASSERT(::is_null(pbasedataOld) || pbasedataOld->m_countReference >= 1);
1864 //
1865 // }
1866 //
1867 // if (::is_set(pdataOld))
1868 // {
1869 //
1870 // if constexpr (t_bPreserve)
1871 // {
1872 //
1873 // auto sizeCopy = minimum(old_size, lengthNew);
1874 //
1875 // if (sizeCopy > 0)
1876 // {
1877 //
1878 // memory_copy((void*)pdata, pdataOld, sizeCopy * sizeof(CHARACTER));
1879 //
1880 // }
1881 //
1882 // }
1883 //
1884 // }
1885 //
1886 // if (::is_set(pbasedataOld))
1887 // {
1888 //
1889 // if constexpr (t_bWasString)
1890 // {
1891 //
1892 // ::base_data_defer_release(pbasedataOld);
1893 //
1894 // }
1895 //
1896 // }
1897 //
1898 // this->m_begin = pdata;
1899 //
1900 // this->_set_length(lengthNew);
1901 //
1902 // return pdata;
1903 //
1904 // }
1905
1906
1914 //template < bool t_bPreserve = false >
1915 //CHARACTER * create_string(character_count character_count);
1921 //CHARACTER * _create_string(character_count character_count);
1922
1923
1924 //template < bool t_bWasString, bool t_bPreserve >
1925 //CHARACTER * fork_string(character_count character_count);
1926
1927
1928 // template < bool t_bPreserve >
1929 // CHARACTER * defer_fork_string(character_count character_count)
1930 // {
1931 //
1932 // if (::is_null(this->m_pbasedata))
1933 // {
1934 //
1935 // return fork_string<false, t_bPreserve>(character_count);
1936 //
1937 // }
1938 //
1939 // auto pbasedata = this->m_pbasedata;
1940 //
1941 // auto p = pbasedata->data();
1942 //
1943 // if (::is_set(pbasedata)
1944 // && (pbasedata->base_data_is_shared() || character_count > pbasedata->storage_character_count()))
1945 // {
1946 //
1947 // p = fork_string<true, t_bPreserve>(character_count);
1948 //
1949 // }
1950 //
1951 // return p;
1952 //
1953 // }
1954
1955
1956 //void _fork_string();
1957
1958 //inline static BASE_DATA * create_meta_data(character_count characterCount);
1959
1960 //void prepare_write(character_count nLength)
1961 //{
1962
1963 // auto p = this->metadata();
1964
1965 // if (p->natural_is_shared() || nLength >= this->storage_character_count())
1966 // {
1967
1968 // fork_string(nLength);
1969
1970 // }
1971
1972 //}
1973
1974
1975
1976 const SCOPED_STRING & if_empty(const SCOPED_STRING & scopedstr) const { return this->is_empty() ? scopedstr : *((const SCOPED_STRING *) this); }
1977 bool set_if_empty(const SCOPED_STRING & scopedstr) { return this->is_empty() ? (*this = scopedstr, true) : false; }
1978
1979
1980 void add(CHARACTER ch);
1981
1982
1983
1984 void reserve(character_count res_arg = 0);
1985
1986
1987 string_base& erase_end(character_count start) { return this->index_erase(start, (::character_count)this->index_of(this->end())); }
1988
1989
1990 string_base& erase_count_end(character_count count) { return this->index_erase(this->size() - count, count); }
1991
1992
1993 string_base & index_erase(character_count start, character_count count);
1994
1996 string_base & index_erase(character_count count) { return this->index_erase((::character_count)0, count); }
1997
1998 string_base & erase(const_iterator start, character_count count) { return this->index_erase(this->index_of(start), count); }
1999
2000 string_base & erase(const_iterator start, const_iterator end = 0)
2001 {
2002
2003 if (!end) end = this->end();
2004
2005 return this->index_erase(this->index_of(start), this->index_of(end) - this->index_of(start));
2006
2007 }
2008
2009 ::collection::count insert(character_count iIndex, CHARACTER ch);
2010
2011 ::collection::count insert(character_count iIndex, const string_base & str);
2012
2013 ::collection::count replace_with(CHARACTER charNew, CHARACTER charOld, character_count start = 0);
2014
2015 template < typename EQUALITY >
2016 ::collection::count _replace_with(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start, EQUALITY equality);
2017
2018
2019 ::collection::count replace_with(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start = 0)
2020 {
2021
2022 return _replace_with(scopedstrNew, scopedstrOld, start, ::comparison::comparison<CHARACTER>());
2023
2024 }
2025
2026
2027 ::collection::count case_insensitive_replace_with(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count start = 0)
2028 {
2029
2030 return _replace_with(scopedstrNew, scopedstrOld, start, ::comparison::case_insensitive<CHARACTER>());
2031
2032 }
2033
2034 ::collection::count replace_with_count(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count iStart = 0);
2035
2036 ::collection::count replace_with_ci_count(const SCOPED_STRING & scopedstrNew, const SCOPED_STRING & scopedstrOld, character_count iStart = 0);
2037
2038 ::collection::count find_replace(CHARACTER charOld, CHARACTER charNew, character_count iStart = 0)
2039 {
2040
2041 return replace_with(charNew, charOld, iStart);
2042
2043 }
2044
2045 ::collection::count find_replace(const SCOPED_STRING & scopedstrOld, const SCOPED_STRING & scopedstrNew, character_count start = 0)
2046 {
2047
2048 return _replace_with(scopedstrNew, scopedstrOld, start, comparison::comparison<CHARACTER>());
2049
2050 }
2051
2052
2053 ::collection::count case_insensitive_find_replace(const SCOPED_STRING & scopedstrOld, const SCOPED_STRING & scopedstrNew, character_count start = 0)
2054 {
2055
2056 return _replace_with(scopedstrNew, scopedstrOld, start, comparison::case_insensitive<CHARACTER>());
2057
2058 }
2059
2060
2061 // replace all occurrences of string_base 'pszOld' with string_base 'pszNew'
2062 //template < raw_pointer_castable < CHARACTER_TYPE > PCHAROLD, raw_pointer_castable < CHARACTER_TYPE > PCHARNEW >
2063 ::collection::count find_replace_count(const SCOPED_STRING & scopedstrOld, const SCOPED_STRING & scopedstrNew, character_count iStart = 0)
2064 {
2065
2066 return replace_with_count(scopedstrNew, scopedstrOld, iStart);
2067
2068 }
2069
2070
2071 //template < raw_pointer_castable < CHARACTER_TYPE > PCHAROLD, raw_pointer_castable < CHARACTER_TYPE > PCHARNEW >
2072 ::collection::count case_insensitive_find_replace_count(const SCOPED_STRING & scopedstrOld, const SCOPED_STRING & scopedstrNew, character_count iStart = 0)
2073 {
2074
2075 return replace_with_ci_count(scopedstrNew, scopedstrOld, iStart);
2076
2077 }
2078
2079
2081 //character_count xxx_replace(CHARACTER charOld, CHARACTER charNew, character_count iStart = 0);
2082
2084 //template < raw_pointer_castable < CHARACTER_TYPE > PCHAROLD, raw_pointer_castable < CHARACTER_TYPE > PCHARNEW >
2085 //character_count xxx_replace(PCHAROLD pcharOld, PCHARNEW pcharNew, character_count iStart = 0);
2086
2087 //template < raw_pointer_castable < CHARACTER_TYPE > PCHAROLD, raw_pointer_castable < CHARACTER_TYPE > PCHARNEW >
2088 //character_count case_insensitive_xxx_replace(PCHAROLD pcharOld, PCHARNEW pcharNew, character_count iStart = 0);
2089
2091 //template < raw_pointer_castable < CHARACTER_TYPE > PCHAROLD, raw_pointer_castable < CHARACTER_TYPE > PCHARNEW >
2092 //::collection::count xxx_replace_count(PCHAROLD pcharOld, PCHARNEW pcharNew, character_count iStart = 0);
2093
2094 //template < raw_pointer_castable < CHARACTER_TYPE > PCHAROLD, raw_pointer_castable < CHARACTER_TYPE > PCHARNEW >
2095 //::collection::count xxx_replace_ci_count(PCHAROLD pcharOld, PCHARNEW pcharNew, character_count iStart = 0);
2096
2097 //::collection::count utf8_replace(const string_base &scopedstrOld, const string_base &scopedstrNew, character_count iStart = 0);
2098
2099 string_base & replace(const_iterator start, const_iterator end, const SCOPED_STRING & scopedstr);
2100 string_base & replace_index(character_count start, character_count end, const SCOPED_STRING & scopedstr)
2101 {
2102
2103 return replace(this->begin() + start, this->begin() + end, scopedstr);
2104
2105 }
2106 //string_base & replace(character_count iStart, character_count nCount, const SCOPED_STRING & scopedstr, character_count nLen);
2107
2108 // erase all occurrences of character 'chRemove'
2109 ::collection::count erase_character(CHARACTER chRemove);
2110 ::collection::count erase_any_character_in(const SCOPED_STRING & scopedstrCharacters);
2111
2112 string_base Tokenize(const SCOPED_STRING & scopedstrTokens, character_count & iStart) const;
2113
2114
2115 string_base & begins_eat_any_character_in(const SCOPED_STRING & scopedstrCharacters = 0)
2116 {
2117
2118 auto pbegin = this->skip_any_character_in(scopedstrCharacters);
2119
2120 if(pbegin != this->begin())
2121 {
2122
2123 this->erase_beginning(pbegin);
2124
2125 }
2126
2127 return *this;
2128
2129 }
2130
2131
2132 //character_count get_token(const string_base &strSeparators, character_count pos = -1) const RELEASENOTHROW;
2133 //character_count get_token(const string_base &strSeparators) const RELEASENOTHROW;
2134 //character_count get_token(const CHARACTER * pszSeparators, character_count pos = -1) const RELEASENOTHROW;
2135 //character_count get_token(CHARACTER chSeparator, character_count pos = -1) const RELEASENOTHROW;
2136
2137 //character_count _get_token(const string_base &strSeparators, character_count pos = -1) const RELEASENOTHROW;
2138 //character_count _get_token(const string_base &strSeparators) const RELEASENOTHROW;
2139 //character_count _get_token(const CHARACTER * pszSeparators, character_count pos = -1) const RELEASENOTHROW;
2140 //character_count _get_token(CHARACTER chSeparator, character_count pos = -1) const RELEASENOTHROW;
2141
2142
2143 string_base intersection(const SCOPED_STRING & scopedstr) const;
2144
2145
2146 string_base ansistr() const
2147 {
2148 return *this;
2149 }
2150
2151
2152 //const CHARACTER * begin() const
2153 //{
2154
2155 // return data();
2156
2157 //}
2158
2159
2160 //const CHARACTER * end() const
2161 //{
2162
2163 // return data() + size();
2164
2165 //}
2166
2167
2168 unicode_iterator < CHARACTER > unicode_begin() const
2169 {
2170
2171 return this->data();
2172
2173 }
2174
2175
2176 unicode_iterator < CHARACTER > unicode_end() const
2177 {
2178
2179 return this->data() + this->size();
2180
2181 }
2182
2183 template < prototype_integral START >
2184 string_base unicode_substr(START start) const
2185 {
2186
2187 return { (this->unicode_begin() + start).c_str(), this->end()};
2188
2189 }
2190
2191
2192 template < prototype_integral START, prototype_integral COUNT >
2193 string_base unicode_substr(START start, COUNT count) const
2194 {
2195
2196 return { (this->unicode_begin() + start).c_str(), (this->unicode_begin() + start + count).c_str()};
2197
2198 }
2199
2200
2201 constexpr bool starts_with_word(const SCOPED_STRING& range, const ::get_word_function < ITERATOR_TYPE > & functionGetWord) const
2202 {
2203
2204 return functionGetWord(*this, nullptr).order(range) == 0;
2205
2206
2207 }
2208
2209
2210 string_base get_word(const SCOPED_STRING& sSep)
2211 {
2212
2213 return ::string_get_word_with_separator_list_and_go_next(*this, sSep);
2214
2215 }
2216
2217
2218 const_string_range < ITERATOR_TYPE > _peek_word(const SCOPED_STRING &sSep, ITERATOR_TYPE * ppnext = nullptr) const
2219 {
2220
2221
2222 return ::string_get_word_with_separator_list((const SCOPED_STRING &) *this, sSep, ppnext);
2223
2224 }
2225
2226
2227 string_base peek_word(const SCOPED_STRING &sSep, ITERATOR_TYPE *ppnext = nullptr) const
2228 {
2229
2230 return this->_peek_word(sSep, ppnext);
2231
2232 }
2233
2234
2235 constexpr bool case_insensitive_starts_with_word(const SCOPED_STRING &range,
2236 const get_word_function<ITERATOR_TYPE> &functionGetWord) const
2237 {
2238
2239 return functionGetWord(*this, nullptr).case_insensitive_order(range) == 0;
2240
2241 }
2242
2243
2244 constexpr bool starts_with_word(const SCOPED_STRING& range) const
2245 {
2246
2247 return this->starts_with_word(range, &::string_get_word_separated_by_spaces < ITERATOR_TYPE >);
2248
2249 }
2250
2251
2252 constexpr bool case_insensitive_starts_with_word(const SCOPED_STRING& range) const
2253 {
2254
2255 return case_insensitive_starts_with_word(range, &::string_get_word_separated_by_spaces < ITERATOR_TYPE >);
2256
2257 }
2258
2259
2260 //inline bool begins(const CHARACTER * pszPrefix) const;
2261
2262 //inline bool begins(const string_base &strPrefix) const;
2263 //inline bool ends(const string_base &strSuffix) const;
2264
2265 inline bool begins_eat(const SCOPED_STRING & scopedstrPrefix);
2266 inline bool ends_eat(const SCOPED_STRING & scopedstrSuffix);
2267
2268 inline bool case_insensitive_begins_eat(const SCOPED_STRING & scopedstrPrefix);
2269 inline bool case_insensitive_ends_eat(const SCOPED_STRING & scopedstrSuffix);
2270
2271 inline bool begins_erase_get_erased(string_base& strErased, const SCOPED_STRING& scopedstr);
2272 inline bool ends_erase_get_erased(string_base& strErased, const SCOPED_STRING& scopedstr);
2273
2274 inline bool begins_replace(const SCOPED_STRING & scopedstrNewPrefix, const SCOPED_STRING & scopedstrPrefix);
2275
2276 inline bool case_insensitive_begins_replace(const SCOPED_STRING & scopedstrNewPrefix, const SCOPED_STRING & scopedstrPrefix);
2277
2278 inline bool begins_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstr) const;
2279 inline bool ends_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstr) const;
2280
2281 inline bool case_insensitive_begins_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstr) const;
2282 inline bool case_insensitive_ends_get_remainder(string_base & strRemainder, const SCOPED_STRING & scopedstr) const;
2283
2284 inline string_base begins_bitten(const SCOPED_STRING & scopedstr) const;
2285 inline string_base ends_bitten(const SCOPED_STRING & scopedstr) const;
2286
2287 inline string_base case_insensitive_begins_bitten(const SCOPED_STRING & scopedstr) const;
2288 inline string_base case_insensitive_ends_bitten(const SCOPED_STRING & scopedstr) const;
2289
2290 inline string_base case_insensitive_begins_eaten(const SCOPED_STRING & scopedstr) const;
2291 inline string_base case_insensitive_ends_eaten(const SCOPED_STRING & scopedstr) const;
2292
2293 inline string_base & ensure_prefix(const SCOPED_STRING & scopedstrPrefix);
2294 inline string_base & case_insensitive_ensure_prefix(const SCOPED_STRING & scopedstrPrefix);
2295
2296 inline string_base & ensure_suffix(const SCOPED_STRING & scopedstrSuffix);
2297 inline string_base & case_insensitive_ensure_suffix(const SCOPED_STRING & scopedstrSuffix);
2298
2299 inline string_base defer_prefixed(const SCOPED_STRING & scopedstrPrefix) const;
2300 inline string_base case_insensitive_defer_prefixed(const SCOPED_STRING & scopedstrPrefix) const;
2301
2302 inline string_base defer_suffixed(const SCOPED_STRING & scopedstrSuffix) const;
2303 inline string_base case_insensitive_defer_suffixed(const SCOPED_STRING & scopedstrSuffix) const;
2304
2305 //inline bool begins(const string_base &str) const;
2306 //inline bool ends(const string_base &str) const;
2307
2308 //inline bool case_insensitive_begins(const string_base &str) const;
2309 //inline bool case_insensitive_ends(const string_base &str) const;
2310
2311 //inline bool begins_eat(const string_base &str);
2312 //inline bool ends_eat(const string_base &str);
2313
2314 //inline bool case_insensitive_begins_eat(const string_base &str);
2315 //inline bool case_insensitive_ends_eat(const string_base &str);
2316
2317 //inline string_base& ensure_prefix(const string_base &strPrefix);
2318 //inline string_base& case_insensitive_ensure_prefix(const string_base &strPrefix);
2319
2320 //inline string_base& ensure_ends(const string_base &strSuffix);
2321 //inline string_base& case_insensitive_ensure_ends(const string_base &strSuffix);
2322
2323 bool eat_before(string_base & strBefore, const SCOPED_STRING & strSeparator, bool bEatEverythingIfNotFound = false);
2324 bool eat_before_let_separator(string_base & strBefore, const SCOPED_STRING & strSeparator, bool bEatEverythingIfNotFound = false);
2325
2326 // manipulation
2327
2328 // Convert the string_base to uppercase
2329 string_base & make_upper();
2330
2331 // Convert the string_base to lowercase
2332 string_base & make_lower();
2333
2334 // Reverse the string_base
2335 string_base & MakeReverse();
2336
2337 string_base lower() const;
2338
2339 string_base upper() const;
2340
2341
2342 // Convert the string_base to uppercase
2343 string_base uppered() const;
2344
2346 //string_base lowered() const;
2347
2348 // Convert the string_base to lowercase
2349 string_base reversed() const;
2350
2351 // trimming
2352
2353 // erase all trailing whitespace
2354 string_base & trim_right();
2355
2356 // erase all leading whitespace
2357 string_base & trim_left();
2358
2359 // erase all leading and trailing whitespace
2360 string_base & trim();
2361
2362 // erase all leading and trailing occurrences of character 'chTarget'
2363 string_base & trim(CHARACTER chTarget);
2364
2365 // erase all leading and trailing occurrences of any of the characters in the string_base 'pszTargets'
2366 string_base & trim(const SCOPED_STRING & scopedstrTargets);
2367
2368 // trimming anything (either side)
2369
2370 // erase all trailing occurrences of character 'chTarget'
2371 string_base & trim_right(CHARACTER chTarget);
2372
2373 // erase all trailing occurrences of any of the characters in string_base 'pszTargets'
2375 //string_base & trim_right(PCHAR pcharTargets);
2376 string_base & trim_right(const SCOPED_STRING & scopedstrTargets);
2377
2378 // erase all leading occurrences of character 'chTarget'
2379 string_base & trim_left(CHARACTER chTarget);
2380
2381 // erase all leading occurrences of any of the characters in string_base 'pszTargets'
2382 //template < pointer_castable < CHARACTER > PCHAR >
2383 //string_base& trim_left(PCHAR pchTargets);
2384 string_base & trim_left(const SCOPED_STRING & scopedstrTargets);
2385
2386
2387 // erase all trailing whitespace
2388 string_base right_trimmed() const;
2389
2390 // erase all leading whitespace
2391 string_base left_trimmed() const;
2392
2393 // erase all leading and trailing whitespace
2394 string_base trimmed() const;
2395
2396 // erase all leading and trailing occurrences of character 'chTarget'
2397 string_base trimmed(CHARACTER chTarget) const;
2398
2399 // erase all leading and trailing occurrences of any of the characters in the string_base 'pszTargets'
2400 string_base trimmed(const SCOPED_STRING & scopedstrTargets) const;
2401
2402 // trimming anything (either side)
2403
2404 // erase all trailing occurrences of character 'chTarget'
2405 string_base right_trimmed(CHARACTER chTarget) const;
2406
2407 // erase all trailing occurrences of any of the characters in string_base 'pszTargets'
2408 string_base right_trimmed(const SCOPED_STRING & scopedstrCharacters) const;
2409
2410 // erase all leading occurrences of character 'chTarget'
2411 string_base left_trimmed(CHARACTER chTarget) const;
2412
2413 // erase all leading occurrences of any of the characters in string_base 'pszTargets'
2414 string_base left_trimmed(const SCOPED_STRING & strTargets) const;
2415
2416
2417 bool pair_trim(CHARACTER character1, CHARACTER character2)
2418 {
2419
2420 if (this->size() >= 2)
2421 {
2422
2423 if (this->first() == character1 && this->last() == character2)
2424 {
2425
2426 *this = this->substr(1, this->length() - 2);
2427
2428 return true;
2429
2430 }
2431
2432 }
2433
2434 return false;
2435
2436 }
2437
2438
2439 string_base & pair_trim_quotes()
2440 {
2441
2442 while (pair_trim('\"', '\"') || pair_trim('\'', '\''));
2443
2444 return *this;
2445
2446 }
2447
2448
2449 string_base paired_trim_quotes()
2450 {
2451
2452 auto str = *this;
2453
2454 str.pair_trim_quotes();
2455
2456 return ::transfer(str);
2457
2458 }
2459
2460
2461 //BASE_RANGE substr(const_iterator p) const { return ::transfer(substr(p, -1)); }
2462
2463 //template < prototype_integral COUNT >
2464 //BASE_RANGE substr(const_iterator p, COUNT count) const { return ::transfer(substr(p - this->begin(), count)); }
2465
2466 //template < prototype_integral START >
2467 //BASE_RANGE substr(START start) const;
2468 //template < prototype_integral START, prototype_integral COUNT >
2469 //BASE_RANGE substr(START start, COUNT count) const;
2470 //template < prototype_integral START >
2471 //BASE_RANGE substr(START start, const_iterator p) const { return substr(start, (p - this->m_begin) - start); }
2472
2473
2474
2475 string_base & formatf(const CHARACTER * pszFormat, ...);
2476
2477 string_base & formatf_arguments(const CHARACTER * pszFormat, va_list args);
2478
2479 string_base & format_arguments(const scoped_string & scopedstrFormat, std::format_args args)
2480 requires(::is_same<CHARACTER, ansi_character>);
2481
2482 string_base & format_arguments(const scoped_wstring & scopedstrFormat, std::wformat_args args)
2483 requires(::is_same<CHARACTER, wide_character>);
2484
2485 string_base & append_formatf(const CHARACTER * pszFormat, ...);
2486
2487 string_base & append_formatf_arguments(const CHARACTER * pszFormat, va_list args);
2488
2489
2490//#if defined(__STD_FORMAT__)
2491
2492
2493
2494
2495 template<typename... Args>
2496 string_base & format(::std::format_string<Args...> fmt, Args&&... args)
2497 {
2498
2499 auto s = std::format(fmt, std::forward<Args>(args)...);
2500
2501 return this->assign(s.c_str(), s.size());
2502
2503 }
2504
2505 //template<typename... Args>
2506 //string_base & append_format(std::format_string<Args...> fmt, Args&&... args)
2507 //{
2508
2509 // return this->operator +=(std::format(fmt, std::forward<Args>(args)...));
2510
2511 //}
2512
2513
2514 template <typename... Args>
2515 string_base& append_format(std::format_string<Args...> fmt, Args&&... args)
2516 {
2517
2518 auto str = std::format(fmt, std::forward<Args>(args)...);
2519
2520 return this->append(str.c_str(), str.size());
2521
2522 }
2523
2524
2525 template<typename... Args>
2526 string_base & runtime_format(const scoped_string & scopedstrFormat, Args&&... args)
2527 requires(::is_same<CHARACTER, ansi_character>);
2528
2529 template<typename... Args>
2530 string_base & runtime_format(const scoped_wstring & scopedstrFormat, Args&&... args)
2531 requires(::is_same<CHARACTER, wide_character>);
2532
2533//#endif
2534
2535 //void FormatMessage(const CHARACTER * pszFormat, ...);
2536
2537
2538
2539
2540 // set the string_base to the value of environment ::payload 'pszVar'
2541 //bool xxxget_environment_variable(const string_base &strVar);
2542
2543 // set the string_base to the value of environment ::payload 'pszVar'
2544 //bool xxxgetenv(const string_base &strVar);
2545
2546 // Load the string_base from resource 'nID'
2547 //bool load_string(::particle * pparticle, atom atom);
2548
2549 // Load the string_base from resource 'nID' in module 'hInstance'
2550 /* bool load_string(HINSTANCE hInstance,character_count nID )
2551 {
2552 const STRINGRESOURCEIMAGE* pImage = gen_GetStringResourceImage( hInstance, nID );
2553 if( pImage == nullptr )
2554 {
2555 return( false );
2556 }
2557
2558 character_count nLength = str_traits::GetcharLength( pImage->achString, pImage->nLength );
2559 CHARACTER * pszBuffer = GetBuffer( nLength );
2560 str_traits::ConvertTochar( pszBuffer, nLength, pImage->achString, pImage->nLength );
2561 release_buffer( nLength );
2562
2563 return( true );
2564 }*/
2565
2566 // Load the string_base from resource 'nID' in module 'hInstance', using language 'wLanguageID'
2567 /*bool load_string(HINSTANCE hInstance,character_count nID,::u16 wLanguageID )
2568 {
2569 const STRINGRESOURCEIMAGE* pImage = gen_GetStringResourceImage( hInstance, nID, wLanguageID );
2570 if( pImage == nullptr )
2571 {
2572 return( false );
2573 }
2574
2575 character_count nLength = str_traits::GetcharLength( pImage->achString, pImage->nLength );
2576 CHARACTER * pszBuffer = GetBuffer( nLength );
2577 str_traits::ConvertTochar( pszBuffer, nLength, pImage->achString, pImage->nLength );
2578 release_buffer( nLength );
2579
2580 return( true );
2581 }*/
2582
2583 void resize(character_count n)
2584 {
2585 resize(n, '\0');
2586 }
2587
2588 void resize(character_count n, CHARACTER c);
2589
2590
2591
2592
2593 string_base unichar_substr(character_count iFirst) const;
2594 string_base unichar_substr(character_count iFirst, character_count nCount) const;
2595 string_base unichar_left(character_count nCount) const;
2596 string_base unichar_mid(character_count iFirst) const;
2597 string_base unichar_mid(character_count iFirst, character_count nCount) const;
2598
2599
2600 //character_count char_get_count(character_count iCharCount) const;
2601 //ansi_string char_left(character_count nCount) const;
2602 //ansi_string char_mid(character_count iFirst) const;
2603 //ansi_string char_mid(character_count iFirst, character_count nCount) const;
2604
2605 void clear();
2606
2607
2608
2609 typedef character_count size_type;
2610
2611
2612
2613
2614};
2615
2616
2617template < typename ITERATOR_TYPE >
2618class auto_string_buffer
2619{
2620public:
2621
2622
2623 using STRING = string_base < ITERATOR_TYPE >;
2624
2625 using CHARACTER = typename STRING::CHARACTER;
2626
2627 STRING * m_pstring;
2628
2629 CHARACTER * m_pbuffer;
2630
2631 auto_string_buffer(STRING * pstring, character_count charactercount = -1):
2632 m_pstring(pstring)
2633 {
2634
2635 m_pbuffer = m_pstring->get_buffer(charactercount);
2636
2637 }
2638
2639 ~auto_string_buffer()
2640 {
2641
2642 m_pstring->release_buffer();
2643
2644 }
2645
2646 operator CHARACTER *() {return m_pbuffer;}
2647
2648
2649};
2650
2651
2652
2653template < typename ITERATOR_TYPE >
2654inline auto_string_buffer<ITERATOR_TYPE> string_base < ITERATOR_TYPE >::auto_release_buffer(character_count characterCount)
2655{
2656
2657 return {this, characterCount};
2658}
2659
2660
2661
2662// For MSVC, but not for GCC?
2663//inline ::string operator + (const ::scoped_string & scopedstrA, const ::scoped_string & scopedstrB)
2664//{
2665//
2666// auto str = strA;
2667//
2668// str += strB;
2669//
2670// return str;
2671//
2672//}
2673
2674
2675//inline ::string operator +(const ::scoped_string & scopedstr, const ::const_ansi_range & range)
2676//{
2677//
2678// auto strResult = str;
2679//
2680// strResult.append(range);
2681//
2682// return ::transfer(strResult);
2683//
2684//}
2685
2686
2687//inline ::string operator + (const ::scoped_string & scopedstr, ::i8 ch);
2688
2689//inline ::string operator +(const ::scoped_string & scopedstr, const_char_pointer psz)
2690//{
2691//
2692// return str + ::string(scopedstr);
2693//
2694//}
2695
2696
2697//template < ::collection::count c >
2698//inline ::string operator +(const ::scoped_string & scopedstr, const ::i8(&sz)[c]);
2699//
2700//
2701//template < character_count m_sizeMaximumLength >
2702//inline ::string operator +(const ::scoped_string & scopedstr, const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring);
2703
2704//inline ::string operator +(const ::scoped_string & scopedstr, const ::scoped_string & scopedstr)
2705//{
2706//
2707// return ::string(str) + str;
2708//
2709//}
2710
2711
2712//inline ::string operator +(::i8 ch, const ::scoped_string & scopedstr);
2713
2714
2715// For MSVC, but not for GCC?
2716//template < ::collection::count c >
2717//inline ::string operator +(const ::i8(&sz)[c], const ::scoped_string & scopedstr)
2718//{
2719//
2720// return ::string(sz) + str;
2721//
2722//}
2723
2724
2725//template < ::collection::count c >
2726//inline ::string operator +(const ::const_ansi_range & str, const ::i8(&sz)[c])
2727//{
2728//
2729// return ::string(str) + sz;
2730//
2731//}
2732
2733
2734// For MSVC, but not for GCC?
2735//inline ::string operator +(const ::const_ansi_range & range, const ::scoped_string & scopedstr)
2736//{
2737//
2738// return ::string(range) + str;
2739//
2740//}
2741
2742
2743//template < prototype_character CHARACTER, typename CHARACTER2 >
2744//constexpr ::string_base < const CHARACTER * > operator +(CHARACTER ch, ::str < const CHARACTER2 * > str)
2745//{
2746//
2747// return ::transfer(::string_base < const CHARACTER * >(ch) + ::string_base < const CHARACTER * >(str));
2748//
2749//}
2750
2751
2752//template < prototype_character CHARACTER1, prototype_character CHARACTER2, character_count sizeMaximumLength >
2753//inline ::string_base < const CHARACTER1 * > operator + (const CHARACTER1 * psz, const inline_string<CHARACTER2, sizeMaximumLength > & inlinestring)
2754//{
2755//
2756// return ::string_base < const CHARACTER1 * >(scopedstr) + ::string_base < const CHARACTER1 * >(inlinestring);
2757//
2758//}
2759//
2760//template < prototype_character CHARACTER, prototype_character CHARACTER2 >
2761//constexpr ::string_base < const CHARACTER * > operator + (::str < const CHARACTER * > str, const CHARACTER2 * psz)
2762//{
2763//
2764// return ::transfer(::string_base < const CHARACTER * >(str) + ::string_base < const CHARACTER * >(scopedstr));
2765//
2766//}
2767
2768
2769//inline ::wstring operator + (::wstring wstrA, ::wstring wstrB)
2770//{
2771//
2772// wstrA += wstrB;
2773//
2774// return wstrA;
2775//
2776//}
2777
2778
2779//inline ::wstring operator +(const ::wide_character * pwsz, ::wstring wstr)
2780//{
2781//
2782// return ::wstring(pwsz) + wstr;
2783//
2784//}
2785//
2786//
2787//template < ::collection::count c >
2788//inline ::wstring operator +(const ::wide_character(&wsz)[c], ::wstring wstr)
2789//{
2790//
2791// return ::wstring(wsz) + wstr;
2792//
2793//}
2794
2795//
2796//block::block(const string_base &str)
2797//
2798//{
2799// this->m_begin = (::u8 *)str.m_begin;
2800// this->m_end = (::u8 *) str.m_end;
2801//
2802//}
2803
2804
2805//template < ::collection::count c, character_count m_sizeMaximumLength >
2806//inline ::string operator +(const ::i8(&sz)[c], const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring);
2807
2808
2809//template < ::collection::count c, character_count m_sizeMaximumLength >
2810//inline ::string operator +(const ::inline_string < ::i8, m_sizeMaximumLength > & inlinestring, const ::i8(&sz)[c]);
2811
2812
2813
2814
2815
2816
2817
2818
2819template < prototype_character CHARACTER >
2820class argument_of_struct < ::string_base < const CHARACTER * > >
2821{
2822public:
2823
2824 using type = const ::scoped_string_base < const CHARACTER * > &;
2825
2826};
2827
2828
2829
2830
2831//template < typename ITERATOR_TYPE >
2832//inline ::string_base < ITERATOR_TYPE > operator + (const string_range < ITERATOR_TYPE > & strA, const string_range < ITERATOR_TYPE > & strB )
2833//{
2834//
2835// string_base < ITERATOR_TYPE > str;
2836//
2837// auto length = strA.size() + strB.size();
2838//
2839// auto p = str.get_buffer(length);
2840//
2841// ::memory_copy(p, strA, strA.size());
2842//
2843// ::memory_copy(p + strA.size(), strB, strB.size());
2844//
2845// str.release_buffer(length);
2846//
2847// return ::transfer(str);
2848//
2849//}
2850
2851
2852//template < character_count n, typename ITERATOR_TYPE >
2853//inline ::string_base < ITERATOR_TYPE > operator + (const ::i8 (&cha)[n], const string_range < ITERATOR_TYPE > & str)
2854//{
2855//
2856// return ::transfer(::string_base < ITERATOR_TYPE >(cha) + str);
2857//
2858//}
2859
2860
2861// For MSVC, but not for GCC?
2862//template < typename ITERATOR_TYPE >
2863//inline ::string_base < ITERATOR_TYPE > operator + (const_char_pointer psz, const string_base < ITERATOR_TYPE > & str)
2864//{
2865//
2866// return ::transfer(::string_base < ITERATOR_TYPE >(scopedstr) + str);
2867//
2868//}
2869
2870
2871
2872// For MSVC, but not for GCC?
2873//template < character_count n, typename ITERATOR_TYPE >
2874//inline ::string_base < ITERATOR_TYPE > operator + (const ::i8(&cha)[n], const string_base < ITERATOR_TYPE > & str)
2875//{
2876//
2877// return ::transfer(::string_base < ITERATOR_TYPE >(cha) + str);
2878//
2879//}
2880
2881
2882
2883template < prototype_floating FLOATING >
2884inline ::string as_string(FLOATING f, const_char_pointer pszFormat = "%f"_ansi);
2885
2886
2887inline ::string as_string(const ::block & block)
2888{
2889
2890 ::i8 chNull = '\0';
2891
2892 auto p = memory_find(block.data(), block.size(), &chNull, 1);
2893
2894 auto offset = ((char_pointer )p - (char_pointer )block.data());
2895
2896 if (::is_set(p) && offset < block.size())
2897 {
2898
2899 return { (const_char_pointer )block.data(), offset };
2900
2901 }
2902 else
2903 {
2904
2905 return { (const_char_pointer )block.data(), block.size() };
2906
2907 }
2908
2909}
2910
2911
2912template < >
2913inline ::hash32 as_hash32 < const ansi_string & >(const ansi_string & ansistr);
2914
2915
2916template < >
2917inline ::hash32 as_hash32 < const wide_string & >(const wide_string & widestr);
2918
2919
2920template < >
2921inline ::hash32 as_hash32 < ansi_string >(const ansi_string & ansistr);
2922
2923
2924template < >
2925inline ::hash32 as_hash32 < wide_string >(const wide_string & widestr);
2926
2927
2928
2929
2930//template < typed_range < ::wd16_character * > WD16_RANGE >
2931//string_base operator + (const WD16_RANGE & range) const { auto str = *this; str.append(range.begin(), range.end()); return ::transfer(str); }
2932//
2933//template < typed_range < ::wd32_character * > WD32_RANGE >
2934//string_base operator + (const WD32_RANGE & range) const { auto str = *this; str.append(range.begin(), range.end()); return ::transfer(str); }
2935//
2936//template < typed_range < const_char_pointer >ANSI_RANGE >
2937//string_base operator + (const ANSI_RANGE & range) const { auto str = *this; str.append(range.begin(), range.end()); return ::transfer(str); }
2938//
2939//template < typed_range < const ::wd16_character * > WD16_RANGE >
2940//string_base operator + (const WD16_RANGE & range) const { auto str = *this; str.append(range.begin(), range.end()); return ::transfer(str); }
2941//
2942//template < typed_range < const ::wd32_character * > WD32_RANGE >
2943//string_base operator + (const WD32_RANGE & range) const { auto str = *this; str.append(range.begin(), range.end()); return ::transfer(str); }
2944
2945
2946template < prototype_character CHARACTER2, has_as_string HAS_AS_STRING >
2947::string_base < const CHARACTER2 * > operator + (const CHARACTER2 * psz, const HAS_AS_STRING & has_as_string)
2948{
2949
2950 return ::transfer(::string_base < const CHARACTER2 * >(psz) + has_as_string.as_string());
2951
2952}
2953
2954
2955
2956
2957
2958
2959
2960//template < prototype_character CHARACTER, ::i32 t_size, character_count n >
2961//const_string_range_static_array < const CHARACTER *, t_size + 1 > operator + (const const_string_range_static_array < const CHARACTER *, t_size > & a, const CHARACTER(&s)[n])
2962//{
2963//
2964// //return { a, ::as_string_literal< CHARACTER, n>(s) };
2965// return { a, s };
2966//
2967//}
2968
2969
2970//template < prototype_character CHARACTER, ::i32 t_size, typed_character_pointer < CHARACTER > TYPED_CHARACTER_POINTER >
2971//const_string_range_static_array < const CHARACTER *, t_size + 1 > operator + (const const_string_range_static_array < const CHARACTER *, t_size > & a, TYPED_CHARACTER_POINTER psz)
2972//{
2973//
2974// return { a, {psz, psz + string_safe_length(scopedstr), e_range_null_terminated } };
2975//
2976//}
2977
2978
2979
2980//template < prototype_character CHARACTER, prototype_character CHARACTER2 >
2981//::string_base < const CHARACTER * > operator + (const CHARACTER * psz, const CHARACTER2 * psz2)
2982//{
2983//
2984// return ::transfer(::string_base < const CHARACTER * >(psz) + ::string_base < const CHARACTER * >(psz2));
2985//
2986//}
2987
2988
2989//template < typename T >
2990//concept prototype_string =
2991//::std::is_base_of<T, ::ansi_string >::value ||
2992//::std::is_base_of<T, ::wd16_string >::value ||
2993//::std::is_base_of<T, ::wd32_string >::value;
2994
2995
2996
2997inline string & operator <<(string & str, const_char_pointer psz);
2998
2999template < prototype_integral INTEGRAL >
3000inline string & operator <<(string & str, INTEGRAL i);
3001
3002using a_string_function = ::function < ::string(void) >;
3003
3004
3005
3006
3007// Created by speccylad(twitch)/turd(discord) trasncript by camilo on
3008// 2023-10-19 23:26 <3ThomasBorregaardSorensen!!
3009//#pragma once
3010
3011
3012//#include <format>
3013
3014
3015//template <>
3016//struct std::formatter<::string > :
3017// public std::formatter<std::string>
3018//{
3019//
3020// template<typename Context>
3021// auto format(const ::string& s, Context& ctx) const
3022// {
3023//
3024// return std::formatter<string>::format(std::format("{}", s.c_str()), ctx);
3025// }
3026
3027//};
3028
3029
3030//#if defined(__STD_FORMAT__)
3031
3032// Simple specialization for strings in the Ca2 framework.
3033// This just uses ::string::c_str() to format.
3034// template<>
3035// struct std::formatter<::string> : std::formatter<std::string> {
3036// template<class FormatContext>
3037// auto format(const ::string & value, FormatContext & fc) const
3038// {
3039// return std::formatter<std::string>::format(value.c_str(), fc);
3040// }
3041// };
3042
3043template < >
3044struct std::formatter<::string > :
3045 public ::std::formatter< ::std::string_view >
3046{
3047 template < typename FormatContext >
3048 auto format(const ::string & str, FormatContext & context) const
3049 {
3050 return ::std::formatter<::std::string_view>::format(
3051 ::std::string_view{ str.begin(), str.end() }, context);
3052 }
3053};
3054
3055
3056template<typename ...Args>
3057[[nodiscard]] inline ::string
3058format(const std::format_string<Args...> fmt, Args&&... args) noexcept
3059{
3060
3061 return ::string(std::format<Args...>(fmt, std::forward<Args>(args)...).c_str());
3062
3063}
3064
3065
3066//#endif
3067
3068
3069[[nodiscard]] inline ::string formatf(const_char_pointer pszFormat, ...) noexcept
3070{
3071
3072 ::string str;
3073
3074 va_list argList;
3075
3076 va_start(argList, pszFormat);
3077
3078 str.formatf_arguments(pszFormat, argList);
3079
3080 va_end(argList);
3081
3082 return ::transfer(str);
3083
3084}
3085
3086
3087template < typename ITERATOR_TYPE >
3088inline const_string_range < ITERATOR_TYPE > string_get_word_separated_by_spaces(const scoped_string_base < ITERATOR_TYPE > & scopedstr, ITERATOR_TYPE * pfound)
3089{
3090
3091 auto find = scopedstr.find_first_whitespace();
3092
3093 if(::is_set(pfound))
3094 {
3095
3096 *pfound = find;
3097
3098 }
3099
3100 return { scopedstr.begin(), find };
3101
3102}
3103
3104
3105
3106
3107template < typename ITERATOR_TYPE >
3108inline const_string_range < ITERATOR_TYPE > string_get_word_with_separator_list(const scoped_string_base < ITERATOR_TYPE > & scopedstr, const scoped_string_base < ITERATOR_TYPE > & scopedstrSeparatorList, ITERATOR_TYPE * pnext)
3109{
3110
3111 auto end = scopedstr.find_first_character_in(scopedstrSeparatorList);
3112
3113 auto find = end;
3114
3115 if(::is_empty(end))
3116 {
3117
3118 end = scopedstr.end();
3119
3120 find = end;
3121
3122 }
3123 else
3124 {
3125
3126 find = scopedstr(find).skip_any_character_in(scopedstrSeparatorList);
3127
3128 if(::is_empty(find))
3129 {
3130
3131 find = scopedstr.end();
3132
3133 }
3134
3135 }
3136
3137 if(::is_set(pnext))
3138 {
3139
3140 *pnext = find;
3141
3142 }
3143
3144 return { scopedstr.begin(), end };
3145
3146}
3147
3148
3149template < typename ITERATOR_TYPE >
3150inline string_base < ITERATOR_TYPE > string_get_word_with_separator_list_and_go_next(string_base < ITERATOR_TYPE > & str, const scoped_string_base < ITERATOR_TYPE > & scopedstrSeparatorList)
3151{
3152
3153 ITERATOR_TYPE pnext = nullptr;
3154
3155 string_base < ITERATOR_TYPE > rangeWord = string_get_word_with_separator_list((const scoped_string_base<ITERATOR_TYPE> &) str, scopedstrSeparatorList, &pnext);
3156
3157 if (::is_set(pnext))
3158 {
3159
3160 str = pnext;
3161
3162 }
3163
3164 return rangeWord;
3165
3166}
3167
3168
3169template<typename ITERATOR_TYPE>
3170string_base<ITERATOR_TYPE> const_string_range<ITERATOR_TYPE>::surrounded(const SCOPED_STRING& scopedstr) const
3171{
3172
3173 return scopedstr + *this + scopedstr;
3174
3175}
3176
3177template<typename ITERATOR_TYPE>
3178string_base<ITERATOR_TYPE> const_string_range<ITERATOR_TYPE>::f64_quoted(bool bEscape) const
3179{
3180
3181 if (bEscape)
3182 {
3183
3185
3186 str.find_replace("\\"_ansi, "\\\\"_ansi);
3187
3188 str.find_replace("\""_ansi, "\\\""_ansi);
3189
3190 return str.f64_quoted(false);
3191
3192 }
3193
3194 return this->surrounded("\""_ansi);
3195
3196}
3197
3198
3199
3200template<typename ITERATOR_TYPE>
3201string_base<ITERATOR_TYPE> const_string_range<ITERATOR_TYPE>::single_quoted(bool bEscape) const
3202{
3203
3204 if (bEscape)
3205 {
3206
3208
3209 str.find_replace("\\"_ansi, "\\\\"_ansi);
3210
3211 str.find_replace("\'"_ansi, "\\'"_ansi);
3212
3213 return str.f64_quoted(false);
3214
3215 }
3216
3217 return this->surrounded("\'"_ansi);
3218
3219}
3220
3221
3222template<typename ITERATOR_TYPE>
3223typename const_string_range<ITERATOR_TYPE>::STRING_ARRAY const_string_range<ITERATOR_TYPE>::explode(const SCOPED_STRING & scopedstrSeparator, bool bAddEmpty) const
3224{
3225
3226 STRING_ARRAY stra;
3227
3228 stra.explode(scopedstrSeparator, *this, bAddEmpty);
3229
3230 return stra;
3231
3232}
3233
3234
3235template<typename ITERATOR_TYPE>
3236string_base<ITERATOR_TYPE> & string_base<ITERATOR_TYPE>::surround(const SCOPED_STRING& scopedstr)
3237{
3238
3239 return operator=(this->surrounded(scopedstr));
3240
3241}
3242
3243
3244template<typename ITERATOR_TYPE>
3245string_base<ITERATOR_TYPE>& string_base<ITERATOR_TYPE>::surround(const SCOPED_STRING& scopedstrLeft, const SCOPED_STRING& scopedstrRight)
3246{
3247
3248 return operator=(this->surrounded(scopedstrLeft, scopedstrRight));
3249
3250}
3251
3252
3253template<typename ITERATOR_TYPE>
3254string_base<ITERATOR_TYPE>& string_base<ITERATOR_TYPE>::f64_quote(bool bEscape)
3255{
3256
3257 return operator=(this->f64_quoted(bEscape));
3258
3259}
3260
3261
3262template<typename ITERATOR_TYPE>
3263string_base<ITERATOR_TYPE>& string_base<ITERATOR_TYPE>::single_quote(bool bEscape)
3264{
3265
3266 return operator=(this->single_quoted(bEscape));
3267
3268}
3269
3270
3271CLASS_DECL_ACME ::string _(const ::scoped_string & scopedstr);
3272
3273
3274
3275
3276
3277
3278template < prototype_character CHARACTER, other_primitive_character < CHARACTER > CHARACTER2 >
3279::string_base < const CHARACTER* > operator + (
3280 const ::character_range < const CHARACTER* >& range1,
3281 const ::character_range < const CHARACTER2* >& range2)
3282{
3283
3284 return range1 + ::string_base < const CHARACTER* >(range2);
3285
3286}
3287
3288
3289template < character_pointer CHARACTER_POINTER >
3290::string_base < const non_const < non_pointer<CHARACTER_POINTER>> * > operator + (
3291 CHARACTER_POINTER p,
3292 const ::character_range < const non_const< non_pointer < CHARACTER_POINTER > > * > & range
3293 )
3294{
3295
3296 return { {p, p + string_safe_length(p), _initialize_range_contains_null_terminated},
3297 range };
3298
3299}
3300
3301
3302template < character_pointer CHARACTER_POINTER, other_character_range < ::decay < CHARACTER_POINTER > > OTHER_CHARACTER_RANGE >
3303::string_base < typename OTHER_CHARACTER_RANGE::const_iterator > operator + (
3304 CHARACTER_POINTER p,
3305 const OTHER_CHARACTER_RANGE & range
3306 )
3307{
3308
3309 ::string_base < typename OTHER_CHARACTER_RANGE::const_iterator > str(p);
3310
3311 str += range;
3312
3313 return ::transfer(str);
3314
3315}
3316
3317//
3318// template < prototype_character CHARACTER, prototype_character CHARACTER2 >
3319// character_count __utf_length(CHARACTER * ptrigger, character_count *& plen, const CHARACTER2 * pSource, character_count lenSource)
3320// {
3321//
3322// return *plen++ = utf_to_utf_length(ptrigger, pSource, lenSource);
3323//
3324// }
3325//
3326//
3327// template < prototype_character CHARACTER, prototype_character CHARACTER2 >
3328// void __utf_concatenate_to(CHARACTER *& p, character_count *& plen, const CHARACTER2 * pSource, character_count lenSource)
3329// {
3330//
3331// utf_to_utf(p, pSource, lenSource);
3332//
3333// p += *plen++;
3334//
3335// }
3336
3337
3338template < prototype_character_range RANGE, typed_character_pointer < typename RANGE::CHARACTER > CHARACTER_POINTER >
3339::string_base < typename RANGE::const_iterator > operator + (const RANGE& range, CHARACTER_POINTER psz)
3340{
3341
3342 return { range, ::const_string_range <typename RANGE::const_iterator >(psz, psz + string_safe_length(psz)) };
3343
3344}
3345
3346//
3348//template <typename... Args>
3349//::string format(::std::string_view fmt, Args&&... args)
3350//{
3351//
3352// auto s = std::vformat(fmt, std::make_format_args(args...));
3353//
3354// return ::string(s.c_str(),s.size());
3355//
3356//}
3357//
3358
3359
3360// template < typename ITERATOR_TYPE >
3361// inline typename ::character_range < ITERATOR_TYPE >::CHARACTER * create_string_data(character_count character_count)
3362// {
3363//
3364// auto p = ::string_base < ITERATOR_TYPE >::create_string_data(character_count);
3365//
3366// return p;
3367//
3368// }
3369
3370//
3371// template < typename RANGE, typename ITERATOR_TYPE >
3372// inline RANGE & create_string(RANGE & rangeTarget, const ::character_range < ITERATOR_TYPE > & rangeSource)
3373// requires (::std::is_base_of < ::character_range < ITERATOR_TYPE >, RANGE >::value)
3374// {
3375//
3376// auto length = rangeSource.size();
3377//
3378// rangeTarget.m_begin = create_string_data<ITERATOR_TYPE>(length);
3379//
3380// rangeTarget.m_end = rangeTarget.m_begin + length;
3381//
3382// rangeTarget.m_erange = e_range_string;
3383//
3384// return rangeTarget;
3385//
3386// }
3387//
3388//
3389// template < typename RANGE, typename OTHER_ITERATOR_TYPE >
3390// inline RANGE & create_string(RANGE & rangeTarget, const ::character_range < OTHER_ITERATOR_TYPE > & rangeSource)
3391// requires (sizeof(get_iterator_item < OTHER_ITERATOR_TYPE >) != sizeof(typename RANGE::ITEM)
3392// && ::std::is_base_of < ::character_range < typename RANGE::this_iterator >, RANGE >::value)
3393// {
3394//
3395// auto length = utf_to_utf_length(rangeTarget.m_begin, rangeSource, rangeSource.size());
3396//
3397// rangeTarget.m_begin = create_string_data < typename RANGE::this_iterator >(length);
3398//
3399// rangeTarget.m_end = rangeTarget.m_begin + length;
3400//
3401// utf_to_utf(rangeTarget.m_begin, rangeSource.m_begin, length);
3402//
3403// rangeTarget.m_erange = e_range_string;
3404//
3405// return rangeTarget;
3406//
3407// }
3408
3409
3413//template < typename RANGE, typename ITERATOR_TYPE >
3414//RANGE & create_string(RANGE & range, ITERATOR_TYPE start, ITERATOR_TYPE end, enum_range erange)
3415//requires (::std::is_base_of < ::character_range < ITERATOR_TYPE >, RANGE >::value)
3416//{
3417//
3418// auto lengthNew = range.size();
3419//
3420// auto pbasedata = BASE_DATA::create_base_data(lengthNew);
3421//
3422// auto pdata = pbasedata->data();
3423//
3424// range.m_begin = pdata;
3425//
3426// ::memory_transfer(range.m_begin, start, length);
3427//
3428// range._set_length(lengthNew);
3429//
3430// range.m_erange = e_range_none;
3431//
3432// range.m_pbasedata = pbasedata;
3433//
3434// return range;
3435//
3436//}
3437//
3438
3439
3440
3441
3442
3443
3444template <prototype_character_range CHARACTER_RANGE >
3445requires(sizeof(::character_decay<::non_pointer<::non_const< typename CHARACTER_RANGE::this_iterator>>>) > 1)
3446struct std::formatter<CHARACTER_RANGE>
3447{
3448 using BASE_TYPE = CHARACTER_RANGE;
3449 using this_iterator = typename BASE_TYPE::this_iterator;
3450 using character_type = ::character_decay<::non_pointer<::non_const< this_iterator>>>;
3451 //using string_view_type = ::std::basic_string_view<character_type>;
3452 using string_view_type = ::std::string_view;
3453 using target_iterator = const_char_pointer ;
3454
3455 std::formatter<string_view_type> base;
3456
3457 // Forward parse explicitly
3458 template <typename FormatContext>
3459 constexpr auto parse(FormatContext& ctx) {
3460 return base.parse(ctx);
3461 }
3462
3463 template <typename FormatContext>
3464 auto format(const BASE_TYPE & characterrange, FormatContext& ctx) const {
3465 ::string str(characterrange);
3466 return base.format(
3467 string_view_type{
3468 (target_iterator) str.begin(),
3469 (target_iterator) str.end()
3470 },
3471 ctx
3472 );
3473 }
3474};
3475
3476
3477// template < typename ITERATOR_TYPE >
3478// auto_string_buffer<ITERATOR_TYPE>::auto_string_buffer(::string_base < ITERATOR_TYPE > * pstring, character_count charactercount):
3479// m_pstring(pstring)
3480// {
3481// m_pbuffer= m_pstring->get_buffer(charactercount);
3482//
3483// }
3484//
3485// template < typename ITERATOR_TYPE >
3486// auto_string_buffer<ITERATOR_TYPE>::~auto_string_buffer()
3487// {
3488//
3489// m_pstring->release_buffer();
3490//
3491// //m_pbuffer= pstringbase->get_buffer(charactercount);
3492//
3493// }
3494//
3495
3496
3497CLASS_DECL_ACME string format_arguments(const scoped_string & scopedstrFormat, std::format_args args);
3498CLASS_DECL_ACME wstring wformat_arguments(const scoped_wstring & scopedstrFormat, std::wformat_args args);
3499
3500
3501
3502template<typename ITERATOR_TYPE, prototype_character CHARACTER>
3503inline ::string_base<ITERATOR_TYPE> &operator<<(::string_base<ITERATOR_TYPE> &str, const CHARACTER *psz)
3504{
3505
3506 str.append(psz);
3507
3508 return str;
3509}
Definition atom.h:237
Definition string_base.h:2619
Definition c_string.h:12
ITERATOR_TYPE find_first_whitespace() const RELEASENOTHROW
for the rear_* functions the most relevant returned value is actually in m_end.
Definition const_string_range.h:2560
Definition _template_forward_declaration.h:297
Definition parse.h:40
Definition payload.h:54
Definition property.h:81
Definition range.h:223
Definition scoped_string_base.h:13
Definition string_base.h:90
string_base & index_erase(character_count count)
erase count characters from start
Definition string_base.h:1996
void defer_set_size(character_count characterCount)
Definition string_base.h:1720
CHARACTER * create_string(character_count character_count)
draft: all allocation, release and assignment done
Definition string_base.h:1702
string_base & trim_right(const SCOPED_STRING &scopedstrTargets)
template < pointer_castable < CHARACTER > PCHAR >
Definition _impl_string_base.h:3484
void construct2(const ::character_range< const CHARACTER * > &range)
Definition _impl_string_base.h:438
Definition aaa_want_to_remove_str_wstring.h:94
Definition _initial_concepts.h:462
Definition _forward_declaration.h:1323
Definition _forward_declaration.h:2520
Definition block.h:46
Definition _tags.h:5