acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
array_range.h
1// Created by camilo on 2022-12-05 18:28 <3ThomasBorregaardSorensen!!
2#pragma once
3
4
5#include "iterator.h"
6#include "range.h"
7//#include "array_range.h"
8#include "acme/prototype/mathematics/numeric.h"
9
10//
12template < typename TYPE, typename ARG_TYPE >
14 public ::block_range < TYPE * >
15{
16public:
17
18
19 using BASE_RANGE = ::block_range<TYPE *>;
20 using RAW_BASE_ARRAY = array_range;
21 using BASE_RAW_RANGE = ::range<TYPE *>;
22 using BASE_TYPE = TYPE;
23 using BASE_PAYLOAD = TYPE;
24
25 using BASE_RANGE::BASE_RANGE;
26
27
28 constexpr bool array_range_ok() const { return true; }
29
30
31 ::collection::count size() const { return this->m_end - this->m_begin; }
32 ::collection::count get_count() const { return this->size(); }
33
34
35 inline ::collection::index get_lower_bound(::collection::index i = 0) const;
36 inline ::collection::index get_middle_index(::collection::index i = 0) const;
37 inline ::collection::index get_upper_bound(::collection::index i = -1) const;
38 inline ::collection::index lower_bound(::collection::index i = 0) const { return this->get_lower_bound(i); }
39 inline ::collection::index upper_bound(::collection::index i = -1) const { return this->get_upper_bound(i); }
40 inline ::collection::index first_index(::collection::index i = 0) const { return this->lower_bound(i); }
41 inline ::collection::index middle_index(::collection::index i = 0) const { return this->get_middle_index(i); }
42 inline ::collection::index last_index(::collection::index i = -1) const { return this->get_upper_bound(i); }
43 inline bool bounds(::collection::index i) const;
44 inline bool contains_index(::collection::index i) const { return bounds(i); }
45
46
47 inline bool prepare_first_last(::collection::index& first, ::collection::index& last) const;
48 inline bool prepare_first_in_count_last_out(::collection::index& first, ::collection::count& inCountLastOut) const;
49
50
51 inline const TYPE *ptr_at(::collection::index nIndex) const { return this->m_begin + nIndex; }
52 inline TYPE *ptr_at(::collection::index nIndex) { return this->m_begin + nIndex; }
53
54 inline const TYPE &element_at(::collection::index nIndex) const;
55 inline TYPE &element_at(::collection::index nIndex);
56
57 inline TYPE &first(::collection::index n = 0);
58 inline const TYPE &first(::collection::index n = 0) const;
59
60 inline TYPE &last(::collection::index n = -1);
61 inline const TYPE &last(::collection::index n = -1) const;
62
63 inline TYPE &middle(::collection::index n = 0);
64 inline const TYPE &middle(::collection::index n = 0) const;
65
66
67 TYPE &operator[](::collection::index i) { return this->m_begin[i]; }
68 const TYPE &operator[](::collection::index i) const { return this->m_begin[i]; }
69
70
71 auto &payloads() { return *this; }
72 auto &payloads() const { return *this; }
73
74};
75//
76
77//template < prototype_character CHARACTER >
78//inline bool _string_scan_prefix(const CHARACTER *& p, const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockBlock) noexcept
79//{
80//
81// if (block.is_empty())
82// {
83//
84// p = block.data();
85//
86// return true;
87//
88// }
89//
90// if(blockBlock.is_empty())
91// {
92//
93// p = block.data();
94//
95// return true;
96//
97// }
98//
99// return false;
100//
101//}
102
103//
104//template < prototype_character CHARACTER >
105//inline bool _string_rear_scan_prefix(const CHARACTER *& p, const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockBlock) noexcept
106//{
107//
108// if (block.is_empty())
109// {
110//
111// p = block.data() + block.size();
112//
113// return true;
114//
115// }
116//
117// if (blockBlock.is_empty())
118// {
119//
120// p = block.data() + block.size();
121//
122// return true;
123//
124// }
125//
126// return false;
127//
128//}
129
130
131
132//
133//template < prototype_character CHARACTER >
134//inline const CHARACTER * _string_rear_scan(const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockBlock) noexcept
135//{
136//
137// auto p = block.data();
138//
139// auto pEnd = p + block.size();
140//
141// auto pBlock = blockBlock.data();
142//
143// auto pBlockEnd = pBlock + blockBlock.size();
144//
145// while (pEnd > p)
146// {
147//
148// auto pBlockScan = pBlock;
149//
150// do
151// {
152//
153// if (*pEnd == *pBlockScan)
154// {
155//
156// return pEnd;
157//
158// }
159//
160// pBlockScan++;
161//
162// } while (pBlockScan < pBlockEnd);
163//
164// pEnd--;
165//
166// }
167//
168// return pEnd;
169//
170//}
171
172//
173//template < prototype_character CHARACTER >
174//inline const CHARACTER * string_rear_scan(const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockBlock) noexcept
175//{
176//
177// CHARACTER * p;
178//
179// if (_string_rear_scan_prefix(p, block, blockBlock))
180// {
181//
182// return p;
183//
184// }
185//
186// return _string_rear_scan(block, blockBlock);
187//
188//}
189
190
191//template < prototype_character CHARACTER >
192//inline const CHARACTER * _unicode_find_first_character_in(const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockSeparators)
193//{
194//
195// auto p = block.data();
196//
197// auto pEndExclusive = p + block.size();
198//
199// auto pSeparators = blockSeparators.data();
200//
201// auto pSeparatorsEndExclusive = pSeparators + blockSeparators.size();
202//
203// ::i32 len1;
204//
205// ::i32 len2;
206//
207// while (p < pEndExclusive)
208// {
209//
210// auto index = unicode_index_length(p, len1);
211//
212// auto pSeparatorsScan = pSeparators;
213//
214// do
215// {
216//
217// if (index == unicode_index_length(pSeparatorsScan, len2))
218// {
219//
220// return p;
221//
222// }
223//
224// pSeparatorsScan += len2;
225//
226// } while (pSeparatorsScan < pSeparatorsEndExclusive);
227//
228// p += len1;
229//
230// }
231//
232// return p;
233//
234//}
235
236
237//template < prototype_character CHARACTER >
238//const CHARACTER * unicode_token(const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockSeparators)
239//{
240//
241// if (block.is_empty())
242// {
243//
244// return block.data();
245//
246// }
247//
248// if (blockSeparators.is_empty())
249// {
250//
251// return block.data();
252//
253// }
254//
255// return _unicode_token(block, blockSeparators);
256//
257//}
258//
259//
260//template < prototype_character CHARACTER >
261//inline const CHARACTER * _string_find_first_character_in(const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockSeparators)
262//{
263//
264// auto p = block.data();
265//
266// auto pEndExclusive = p + block.size();
267//
268// auto pSeparators = blockSeparators.data();
269//
270// auto pSeparatorsEndExclusive = pSeparators + blockSeparators.size();
271//
272// while (p < pEndExclusive)
273// {
274//
275// auto ch = *p;
276//
277// auto pSeparatorsScan = pSeparators;
278//
279// do
280// {
281//
282// if (ch == *pSeparatorsScan)
283// {
284//
285// return p;
286//
287// }
288//
289// pSeparatorsScan++;
290//
291// } while (pSeparatorsScan < pSeparatorsEndExclusive);
292//
293// p++;
294//
295// }
296//
297// return p;
298//
299//}
300//
301//
302//template < prototype_character CHARACTER >
303//const CHARACTER * string_token(const ::range < CHARACTER > & block, const ::range < CHARACTER > & blockSeparators)
304//{
305//
306// if (block.is_empty())
307// {
308//
309// return block.data();
310//
311// }
312//
313// if (blockSeparators.is_empty())
314// {
315//
316// return block.data();
317//
318// }
319//
320// return _string_token(block, blockSeparators);
321//
322//}
323
324
325//
326//template < prototype_character CHARACTER >
327//inline const CHARACTER * _block_rear_find_character(const ::range < CHARACTER > & block, CHARACTER ch) noexcept
328//{
329//
330// auto pBegin = block.begin();
331//
332// auto pEnd = block.end() - 1;
333//
334// while (pEnd >= pBegin)
335// {
336//
337// if (*pEnd == ch)
338// {
339//
340// return pEnd;
341//
342// }
343//
344// }
345//
346// return nullptr;
347//
348//}
349
350//
351//template < prototype_character CHARACTER >
352//bool _string_compare_prefix(::i32 & iCompare, const ::range < CHARACTER > & blockA, const ::range < CHARACTER > & blockB)
353//{
354//
355// if (blockA.is_empty())
356// {
357//
358// if (blockB.is_empty())
359// {
360//
361// iCompare = 0;
362//
363// return true;
364//
365// }
366// else
367// {
368//
369// iCompare = 1;
370//
371// return true;
372//
373// }
374//
375// }
376// else if (blockB.is_empty())
377// {
378//
379// iCompare = -1;
380//
381// return true;
382//
383// }
384//
385// return false;
386//
387//}
388
389//
390//template < prototype_character CHARACTER >
391//const CHARACTER * _string_compare(const ::range < CHARACTER > & blockA, const ::range < CHARACTER > & blockB)
392//{
393//
394// auto pA = blockA.begin();
395//
396// auto pAEnd = blockA.end();
397//
398// auto pB = blockB.begin();
399//
400// auto pBEnd = blockB.end();
401//
402// ::i32 iCompare;
403//
404// while (pA < pAEnd && pB < pBEnd)
405// {
406//
407// iCompare = *pA - *pB;
408//
409// }
410//
411//
412//}
413
414//
415//template < prototype_character CHARACTER >
416//const CHARACTER * string_compare(const CHARACTER * pA, character_count sizeA, const CHARACTER * pB, character_count sizeB)
417//{
418//
419// ::i32 iCompare;
420//
421// if (_string_compare_prefix(iCompare, blockA, blockB))
422// {
423//
424// return iCompare;
425//
426// }
427//
428// return _string_compare(blockA, blockB);
429//
430//}
431//
432//
433//
434
435
436
437
438
439
440template<typename TYPE, typename ARG_TYPE>
441inline ::collection::index array_range<TYPE, ARG_TYPE>::get_lower_bound(::collection::index i) const
442{
443 return i < this->size() ? i : -1;
444}
445
446template<typename TYPE, typename ARG_TYPE>
447inline ::collection::index
448array_range<TYPE, ARG_TYPE>::get_middle_index(::collection::index iIndex) const
449{
450 return this->size() / 2 + iIndex;
451}
452
453
454template<typename TYPE, typename ARG_TYPE>
455inline ::collection::index
456array_range<TYPE, ARG_TYPE>::get_upper_bound(::collection::index iIndex) const
457{
458 return this->size() + iIndex;
459}
460
461template<typename TYPE, typename ARG_TYPE>
462inline bool array_range<TYPE, ARG_TYPE>::bounds(::collection::index i) const
463{
464 return i >= 0 && i < this->size();
465}
466
467
468
469template<typename TYPE, typename ARG_TYPE>
470bool array_range<TYPE, ARG_TYPE>::prepare_first_last(::collection::index& first,
471 ::collection::index& last) const
472{
473
474 if (first < 0)
475 {
476
477 first += this->array_get_count();
478
479 }
480
481 if (last < 0)
482 {
483
484 last += this->array_get_count();
485
486 }
487
488 return last >= first;
489}
490
491
492template<typename TYPE, typename ARG_TYPE>
493bool array_range<TYPE, ARG_TYPE >::prepare_first_in_count_last_out(
494 ::collection::index& first, ::collection::count& in_count_out_last) const
495{
496
497 if (first < 0)
498 {
499
500 first += this->array_get_count();
501
502 }
503
504 if (first < 0)
505 {
506
507 first = 0;
508
509 }
510
511 if (in_count_out_last < 0)
512 {
513
514 in_count_out_last += this->array_get_count();
515
516 }
517 else
518 {
519
520 in_count_out_last = first + in_count_out_last - 1;
521
522 }
523
524 return in_count_out_last >= first;
525
526}
527
528
529 template<typename TYPE, typename ARG_TYPE>
530inline const TYPE &array_range<TYPE, ARG_TYPE>::element_at(::collection::index nIndex) const
531{
532
533 ASSERT(nIndex >= 0 && nIndex < this->size());
534
535 return this->m_begin[nIndex];
536
537 }
538
539
540 template<typename TYPE, typename ARG_TYPE>
541 inline TYPE &array_range<TYPE, ARG_TYPE>::element_at(::collection::index nIndex)
542 {
543
544 ASSERT(nIndex >= 0 && nIndex < this->size());
545
546 return this->m_begin[nIndex];
547
548 }
549
550
551template<typename TYPE, typename ARG_TYPE>
552inline const TYPE &array_range<TYPE, ARG_TYPE>::first(::collection::index nIndex) const
553{
554
555 return this->element_at(nIndex);
556}
557
558
559template<typename TYPE, typename ARG_TYPE>
560inline TYPE &array_range<TYPE, ARG_TYPE>::first(::collection::index nIndex)
561{
562
563 return this->element_at(nIndex);
564}
565
566
567template<typename TYPE, typename ARG_TYPE>
568inline const TYPE &array_range<TYPE, ARG_TYPE>::last(::collection::index i) const
569{
570
571 return element_at(this->get_upper_bound(i));
572}
573
574
575template<typename TYPE, typename ARG_TYPE>
576inline TYPE &array_range<TYPE, ARG_TYPE>::last(::collection::index i)
577{
578
579 return element_at(this->get_upper_bound(i));
580}
581
582
583template<typename TYPE, typename ARG_TYPE>
584inline const TYPE &array_range<TYPE, ARG_TYPE>::middle(::collection::index i) const
585{
586
587 return element_at(this->get_middle_index(i));
588}
589
590
591template<typename TYPE, typename ARG_TYPE>
592inline TYPE &array_range<TYPE, ARG_TYPE>::middle(::collection::index i)
593{
594
595 return element_at(this->get_middle_index(i));
596}
Definition array_range.h:15