acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
mutable_string_range.h
1// From string_range.h by camilo on 2023-02-20 20:25 <3ThomasBorregaardSorensen!!
2#pragma once
3
4
5#include "string_range.h"
6
7
8template<typename ITERATOR_TYPE>
9class mutable_string_range :
10 //public ::comparable_range < ::comparable_eq_range < ::array_range < ::range < ITERATOR_TYPE > > > >
11 //public ::array_range < ::range < ITERATOR_TYPE > > >
12public ::const_string_range<ITERATOR_TYPE> {
13public:
14
15
16 //using BASE_RANGE = ::comparable_range < ::comparable_eq_range < ::array_range < ::range < ITERATOR_TYPE > > > >;
17
18 using BASE_RANGE = ::const_string_range<ITERATOR_TYPE>;
19
20 using THIS_RANGE = ::mutable_string_range<ITERATOR_TYPE>;
21
22 using STRING_RANGE = ::string_range < BASE_RANGE >;
23
24 using ITEM_POINTER = get_type_item_pointer<ITERATOR_TYPE>;
25 using ITEM = non_const<dereference<ITEM_POINTER> >;
26 using CHARACTER = ITEM;
27
28
29 using this_iterator = typename BASE_RANGE::this_iterator;
30 using iterator = typename BASE_RANGE::iterator;
31 using const_iterator = typename BASE_RANGE::const_iterator;
32
33 using STRING_BASE = ::string_base< const_iterator >;
34
35
36 using THIS_RAW_RANGE = typename BASE_RANGE::THIS_RAW_RANGE;
37 using RAW_RANGE = typename BASE_RANGE::RAW_RANGE;
38 using CONST_RAW_RANGE = typename BASE_RANGE::CONST_RAW_RANGE;
39
40 //using ITEM_POINTER = typename get_type_item_pointer < this_iterator >::type;
41
42 //using ITEM = non_const < dereference < ITEM_POINTER > >;
43
44 using SCOPED_STRING = scoped_string_base<ITERATOR_TYPE>;
45
46
47 using ARG_ITEM = typename BASE_RANGE::ARG_ITEM;
48
49
50 template<::std::size_t count>
51 constexpr mutable_string_range(const ITEM(&array)[count]) : BASE_RANGE(array, array[count - 1] == 0 ? count - 1 : count) {}
52
53 template<prototype_integral INTEGRAL>
54 constexpr mutable_string_range(const_iterator begin, INTEGRAL count) : BASE_RANGE((this_iterator) begin,
55 (this_iterator) (begin + count)) {}
56
57 mutable_string_range(no_initialize_t) : BASE_RANGE(no_initialize_t{}) {}
58
59 mutable_string_range(nullptr_t) : BASE_RANGE(nullptr) {}
60
61 mutable_string_range() {}
62
63 template<typed_range<iterator> RANGE>
64 explicit mutable_string_range(const RANGE &range) : BASE_RANGE(range) {}
65
66 template<typed_range<const_iterator> RANGE>
67 explicit mutable_string_range(const RANGE &range) : BASE_RANGE(range) {}
68
69 mutable_string_range(THIS_RANGE &range) : BASE_RANGE(range) {}
70
71 mutable_string_range(THIS_RANGE &&range) : BASE_RANGE(::transfer(range)) {}
72
73 mutable_string_range(this_iterator begin, this_iterator end) : BASE_RANGE(begin, end) {}
74
75 explicit mutable_string_range(const ::block &block);
76
77 explicit mutable_string_range(ITERATOR_TYPE psz) : STRING_RANGE(psz, 0, string_safe_length(psz)) {}
78
79 mutable_string_range(ITERATOR_TYPE psz, character_count len) : STRING_RANGE(psz, 0, len) {}
80
81 //string_range(const CHARACTER * start, const CHARACTER * end) : BASE_RANGE(start, end) {}
82
83 mutable_string_range(ITERATOR_TYPE psz, character_count start, character_count count) : STRING_RANGE(
84 ::_start_count_string_range(psz, start, count)) {}
85
86
87
88
95 void escape_copy(::i8 escape, const ::const_ansi_range & rangeSource);
96
97
98};
99
100
101
102
103
104
105
106
107
108
109
110
111using mutable_ansi_range = ::mutable_string_range< ::ansi_character *>;
112using mutable_wd16_range = ::mutable_string_range< ::wd16_character *>;
113using mutable_wd32_range = ::mutable_string_range< ::wd32_character *>;
114using mutable_wide_range = ::mutable_string_range< ::wide_character *>;
115
116
117template<prototype_character CHARACTER>
118inline const CHARACTER *
119_unicode_find_first_character_in(const ::range<CHARACTER> &block, const ::range<CHARACTER> &blockBlock) noexcept {
120
121 auto p = block.data();
122
123 auto pEnd = p + block.size();
124
125 auto pBlock = blockBlock.data();
126
127 auto pBlockEnd = pBlock + blockBlock.size();
128
129 ::i32 len1;
130
131 ::i32 len2;
132
133 while (p < pEnd) {
134
135 auto pBlockScan = pBlock;
136
137 auto index = unicode_index_length(p, len1);
138
139 do {
140
141 if (index == unicode_index_length(pBlockScan, len2)) {
142
143 return true;
144
145 }
146
147 pBlockScan += len2;
148
149 } while (pBlockScan < pBlockEnd);
150
151 p += len1;
152
153 }
154
155 return p;
156
157}
158
159
160template<prototype_character CHARACTER>
161inline const CHARACTER *
162unicode_find_first_character_in(const ::range<CHARACTER> &block, const ::range<CHARACTER> &blockBlock) noexcept {
163
164 CHARACTER *p;
165
166 if (_string_find_first_character_in_prefix(p, block, blockBlock)) {
167
168 return p;
169
170 }
171
172 return _unicode_find_first_character_in(block, blockBlock);
173
174}
175
176
177template<prototype_character CHARACTER>
178inline const CHARACTER *
179_unicode_rear_find_first_character_in(const ::range<CHARACTER> &block, const ::range<CHARACTER> &blockBlock) noexcept {
180
181 auto p = block.data();
182
183 auto pEnd = p + block.size();
184
185 auto pBlock = blockBlock.data();
186
187 auto pBlockEnd = pBlock + blockBlock.size();
188
189 //::i32 len1;
190
191 ::i32 len2;
192
193 while (pEnd < p) {
194
195 auto pBlockScan = pBlock;
196
197 auto pPrior = unicode_prior(pEnd, p);
198
199 auto index = unicode_index(pPrior);
200
201 do {
202
203 if (index == unicode_index_length(pBlockScan, len2)) {
204
205 return true;
206
207 }
208
209 pBlockScan += len2;
210
211 } while (pBlockScan < pBlockEnd);
212
213 pEnd = pPrior;
214
215 }
216
217 return pEnd;
218
219}
220
221
222template<prototype_character CHARACTER>
223inline const CHARACTER *
224unicode_rear_find_first_character_in(const ::range<CHARACTER> &block, const ::range<CHARACTER> &blockBlock) noexcept {
225
226 CHARACTER *p;
227
228 if (_string_rear_find_first_character_in_prefix(p, block, blockBlock)) {
229
230 return p;
231
232 }
233
234 return _unicode_rear_find_first_character_in(block, blockBlock);
235
236}
237
238
239using ansi_range = ::string_range< const_char_pointer >;
242
243
244template<prototype_character CHARACTER>
245inline ::hash32 _string_range_u32_hash(::string_range<const CHARACTER *> range) {
246
247 if (range.is_empty()) {
248
249 return {0};
250
251 }
252
253 ::u32 uHash = 0;
254
255 while (range.m_begin < range.m_end) uHash = (uHash << 5) + *(range.m_begin++);
256
257 return {uHash};
258
259}
260
261
262//inline ::hash32 as_hash32(const_ansi_range range)
263//{
264//
265// return _string_range_u32_hash((::string_range<const_char_pointer >) range);
266//
267//}
268//
269//
270//inline ::hash32 as_hash32(const_wd16_range range)
271//{
272//
273// return _string_range_u32_hash((::string_range<const ::wd16_character *>) range);
274//
275//}
276//
277//
278//inline ::hash32 as_hash32(const_wd32_range range)
279//{
280//
281// return _string_range_u32_hash<::wd32_character>((::string_range<const ::wd32_character *>) range);
282//
283//}
284
285
286template<prototype_character CHARACTER>
287constexpr ::character_range<const CHARACTER *> _string_range(const CHARACTER *psz) {
288
289 return {psz, psz + string_safe_length(psz)};
290
291}
292
293
294template<prototype_character CHARACTER>
295constexpr ::character_range<const CHARACTER *>
296_start_count_string_range(const CHARACTER *psz, memsize start, memsize count) {
297
298 auto pend = psz + string_safe_length(psz);
299
300 return {
301 ::clipped_add(psz, start, psz, pend),
302 ((count >= 0) ? ::clipped_add(psz, start + count, psz, pend) :
303 ::clipped_add(pend, count, psz, pend))};
304
305}
306
307
308
309
310template < typename ITERATOR_TYPE >
311template < prototype_integral START, prototype_integral COUNT>
312inline typename const_string_range < ITERATOR_TYPE > ::STRING_RANGE const_string_range < ITERATOR_TYPE > ::operator()(START start, COUNT count) const {
313
314 //return ::_start_count_range(STRING_RANGE(*this), start, count);
315
316 auto sizeThis = this->size();
317
318 auto end = minimum(count < 0 ? sizeThis + count + 1 : start + count, sizeThis);
319
320 return start == 0 && end == sizeThis
321 ?
322 *(string_range < ITERATOR_TYPE >*)this :
323 string_range < ITERATOR_TYPE >
324 {
325 this->m_begin + minimum(start, sizeThis),
326 this->m_begin + end
327 };
328
329
330}
331
332
333//template < typename ITERATOR_TYPE >
334//template < prototype_integral START, typed_character_pointer < typename const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
335//inline typename const_string_range < ITERATOR_TYPE > ::STRING_RANGE const_string_range < ITERATOR_TYPE > ::operator()(START start, CHARACTER_POINTER end) const
336//{
337//
338// return ::_start_end_range(STRING_RANGE(*this), start, end);
339//
340//}
341
342
343//template < typename ITERATOR_TYPE >
344//template < typed_character_pointer < typename const_string_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
345//inline typename const_string_range < ITERATOR_TYPE > ::STRING_RANGE const_string_range < ITERATOR_TYPE > ::operator()(CHARACTER_POINTER start) const
346//{
347//
348// return STRING_RANGE(start, this->end());
349//
350//}
351
352
353template < typename ITERATOR_TYPE >
354template < prototype_integral START >
355inline typename const_string_range < ITERATOR_TYPE > ::STRING_RANGE const_string_range < ITERATOR_TYPE > ::operator()(START start) const {
356
357 return STRING_RANGE(this->begin() + start, this->end());
358
359}
360
361
362template < typename ITERATOR_TYPE >
363inline typename const_string_range < ITERATOR_TYPE > ::STRING_RANGE const_string_range < ITERATOR_TYPE > ::operator()() const {
364
365 return STRING_RANGE(*this);
366
367}
368
369
Definition mutable_string_range.h:12
void escape_copy(::i8 escape, const ::const_ansi_range &rangeSource)
Definition _impl.h:1890
Definition range.h:223
Definition scoped_string_base.h:13
Definition block.h:46
Definition _tags.h:5