acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
base_array.h
1#pragma once
2
3
4#include "_iterator.h"
5#include "acme/memory/typed.h"
6#include "acme/memory/typed_memory.h"
7#include "acme/memory/operation.h"
8#include "acme/prototype/prototype/particle.h"
9
10
11template < typename TYPE >
12const TYPE * find_first_non_null(const TYPE * p)
13{
14
15 while (*p) p++;
16
17 return p;
18
19}
20
21
22CLASS_DECL_ACME ::string get_task_object_name();
23
24#ifdef _DEBUG
25
26CLASS_DECL_ACME ::string get_task_object_debug();
27
28#endif
29
30
31#define __default_array_base_array_non_particle(TYPE) ::base_array < TYPE, const TYPE &, ::allocator::def < TYPE > >
32
33
34#define DECLARE_TYPED_ARRAY_ACCESSOR_OF(ITEM, CONTAINER, TYPE, CONTAINER_TYPE) \
35::pointer<TYPE>& ITEM ## _at(::collection::index i) { return CONTAINER[i]; } \
36const TYPE * ITEM ## _at(::collection::index i) const { return CONTAINER[i]; } \
37::pointer<TYPE>* ITEM ## _data() { return CONTAINER.data(); } \
38::pointer<TYPE>const * ITEM ## _data() const { return CONTAINER.data(); } \
39TYPE * get_ ## ITEM(::collection::index i) const { return CONTAINER.bounds(i) ? CONTAINER[i] : nullptr; } \
40::collection::count ITEM ## _count() const { return CONTAINER.get_count(); } \
41bool has_ ## ITEM() const { return CONTAINER.has_element(); } \
42const CONTAINER_TYPE & ITEM ## a() const { return CONTAINER; } \
43CONTAINER_TYPE & ITEM ## a() { return CONTAINER; } \
44bool contains_ ## ITEM(const TYPE * p) const { return CONTAINER.contains(p); } \
45bool is_there_no_ ## ITEM() const { return CONTAINER.is_empty(); } \
46bool has_no_ ## ITEM() const { return is_there_no_ ## ITEM(); } \
47::collection::index find_first_ ## ITEM(const TYPE * p, ::collection::index iStart = 0, ::collection::count nCount = -1) const { return CONTAINER.find_first(p, iStart, nCount); } \
48::pointer<TYPE>& first_ ## ITEM() { return CONTAINER.first_pointer(); } \
49::pointer<TYPE>& last_ ## ITEM() { return CONTAINER.last_pointer(); } \
50TYPE * get_first_ ## ITEM() const { return CONTAINER.get_first_pointer(); } \
51TYPE * get_last_ ## ITEM() const { return CONTAINER.get_last_pointer(); } \
52::collection::index ITEM ## _first_index(::collection::index i = 0) const { return CONTAINER.first_index(i); } \
53::collection::index ITEM ## _last_index(::collection::index i = -1) const { return CONTAINER.last_index(i); } \
54CONTAINER_TYPE CONTAINER
55
56#define DECLARE_ARRAY_ACCESSOR_OF(ITEM, CONTAINER, TYPE) \
57DECLARE_TYPED_ARRAY_ACCESSOR_OF(ITEM, CONTAINER, TYPE, pointer_array_base < TYPE >)
58
59#define DECLARE_TYPED_ARRAY_OF(ITEM, CONTAINER, TYPE, CONTAINER_TYPE) \
60::collection::index add_ ## ITEM(TYPE * p) { return CONTAINER.add_item(p); } \
61::collection::index add_ ## ITEM ## _array(const CONTAINER_TYPE & a) { return CONTAINER.append(a); } \
62::collection::index add_unique_ ## ITEM(TYPE * p) { return CONTAINER.add_unique(p); } \
63::collection::index add_unique_ ## ITEM ## _array(const CONTAINER_TYPE & a) { return CONTAINER.add_unique(a); } \
64::collection::index erase_ ## ITEM(TYPE * p) { return CONTAINER.erase(p); } \
65CONTAINER_TYPE ITEM ## a_section(::collection::index iStart = 0, ::collection::count nCount = -1){return CONTAINER.slice < CONTAINER_TYPE >(iStart, nCount);} \
66template < typename ARRAY > \
67void ITEM ## a_slice(ARRAY & a, ::collection::index iStart = 0, ::collection::count nCount = -1){ CONTAINER.slice(a, iStart, nCount);} \
68DECLARE_TYPED_ARRAY_ACCESSOR_OF(ITEM, CONTAINER, TYPE, CONTAINER_TYPE)
69
70#define HAVE_ARRAY_OF(ITEM, CONTAINER, TYPE) \
71DECLARE_TYPED_ARRAY_OF(ITEM, CONTAINER, TYPE, pointer_array_base < TYPE >)
72
73#define DECLARE_ARRAY_CONTAINER_OF(ARRAY, ITEM, CONTAINER, TYPE) \
74ARRAY(const ::std::initializer_list < ::pointer<TYPE >>& list_base) : CONTAINER(list_base) { } \
75DECLARE_TYPED_ARRAY_OF(ITEM, CONTAINER, TYPE, pointer_array_base < TYPE >)
76
77#define DECLARE_ARRAY_OF(ARRAY, ITEM, TYPE) \
78DECLARE_ARRAY_CONTAINER_OF(ARRAY, ITEM, m_ ## ITEM ## a, TYPE)
79
80
81#include "acme/prototype/collection/rear_iterator.h"
82
83//DECLARE_C_FLAG(e_array, enum_array);
84
85
86template < typename A, typename B >
87auto distance(const pointer_rear_iterator < A > & a, const pointer_rear_iterator < B > & b) { return (a < b) ? (b - a) : (a - b); }
88template < typename A, typename B >
89auto distance(const A * pa, const B * pb) { return (pa < pb) ? (pb - pa) : (pa - pb); }
90
91// struct array_flags
92// {
93// bool m_bZeroeOnAllocation : 1 = false;
94//
95// };
96
97//struct array_flags_t {};
98//struct pre_allocate_t {};
99//struct zeroe_on_allocation_t {};
101//struct range_t {};
102//struct set_size_t {};
103
104// raw_array is an array that does not call constructors or destructor in elements
105// array is an array that call only copy constructor and destructor in elements
106// array is an array that call default constructors, copy constructs and destructors in elements
107template < class TYPE, class ARG_TYPE, class TYPED, class MEMORY, ::enum_type t_etypeContainer >
108class base_array :
109 public ::array_range < TYPE, ARG_TYPE >,
110 public TYPED,
111 public MEMORY
112{
113public:
114
115
116 using THIS_ARRAY = base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >;
117 using RAW_BASE_ARRAY = THIS_ARRAY;
118
119 using rear_iterator = ::pointer_rear_iterator<TYPE>;
120 using const_rear_iterator = ::pointer_rear_iterator<const TYPE>;
121
122 //using ARRAY_RANGE = ::array_range < ::range < TYPE * > >;
123 using ARRAY_RANGE = ::array_range < TYPE, ARG_TYPE >;
124 using BASE_RAW_RANGE = ::range < TYPE * >;
125 //using array_range = ::range < TYPE * >;
126
127 using PRIMITIVE_CONTAINER_TAG = PRIMITIVE_CONTAINER_TAG_TYPE;
128
129 using CONTAINER_ITEM_TYPE = TYPE;
130 using TYPE_IS_PTR = TYPE;
131
132 using this_iterator = typename ARRAY_RANGE::this_iterator;
133 using iterator = typename ARRAY_RANGE::iterator;
134 using const_iterator = typename ARRAY_RANGE::const_iterator;
135
136
137 //e_array m_earray;
138 ::collection::count m_countAllocation;
139 ::collection::count m_countAddUp;
140 ::collection::count m_countAllocationOffset;
141
142
143 //using ::range < TYPE * >::range;
144
145
146 //base_array(const ::e_array & earray = e_array_none, const ::e_flag & eflag = e_flag_none, const ::e_status & estatus = undefined);
147 base_array();
148 base_array(nullptr_t) : base_array() {}
149 //base_array(array_flags_t, const ::e_array& earray);
150
151
157 base_array(const ::enum_range & erange, ::collection::count c);
158
159
160 //base_array(pre_allocate_t, ::collection::count n) : base_array() { this->m_countAddUp = n; }
161 //base_array(zeroe_on_allocation_t, ::collection::count n) : base_array() { this->m_erange |= e_array_zeroe_on_allocation; this->m_countAddUp = n; }
162
163 //base_array(const ::e_array& earray, ::collection::count c);
164 base_array(const std::initializer_list < TYPE > & initializer_list);
165 base_array(const base_array< TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > & array);
166 base_array(base_array< TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > && array) noexcept;
167 //template < prototype_array ARRAY >
168 //base_array(const ARRAY & a) : base_array() {
169 // this->set_size(a.size());
170 // for (::collection::index i = 0; i < this->size(); i++) this->element_at(i) = a.element_at(i);
171 //}
172 base_array(::collection::count c) : base_array() { this->set_size(c); }
173 template < typename OTHER_TYPE >
174 base_array(::collection::count c, const OTHER_TYPE * p)
175 requires (::std::is_convertible_v < OTHER_TYPE, CONTAINER_ITEM_TYPE >);
176 //template < typename OTHER_RANGE >
177 //base_array(range_t, const OTHER_RANGE& range) :
178 // base_array(range.begin(), range.end())
179 //{
180 //}
181
182 //template < typename OTHER_CONTAINER >
183 //base_array(const OTHER_CONTAINER& container) requires
184 // (prototype_container < OTHER_CONTAINER >
185 // && !::std::is_base_of_v<base_array, ::std::remove_cvref_t < OTHER_CONTAINER > >) :
186 // base_array()
187 //{
188 // this->set_size(container.size());
189 // ::collection::index i = 0;
190 // for (auto& item : container) this->element_at(i++) = item;
191 //}
192
193 template < typename OTHER_RANGE >
194 base_array(const OTHER_RANGE & range) requires
195 (container_range < OTHER_RANGE >
196 && !::std::is_base_of_v < base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >, ::std::remove_cvref_t < OTHER_RANGE > >);
197 // : base_array(range.begin(), range.end())
198 //{ }
199
200 template < prototype_integral INTEGRAL >
201 base_array(const_iterator begin, INTEGRAL count) : base_array(begin, begin + count) {}
202 base_array(const_iterator begin, const_iterator end)
203 {
204 auto p = this->begin();
205 while (p != end) add(*p);
206 }
207 template < typename SOME_TYPE >
208 base_array(null_terminated_t, const SOME_TYPE *begin) : base_array(begin, find_first_non_null(begin))
209 {
210 }
211 ~base_array();
212
213
214 void array_base_ok() const;
215
216 void container_ok() const
217 {
218
219 array_base_ok();
220
221 }
222
223
224
225 void defer_erase_allocation_offset();
226
227 void defer_destroy()
228 {
229
230 if (this->m_begin != nullptr)
231 {
232
233 destroy();
234
235 }
236
237 }
238
239
240 base_array & operator += (const TYPE & t)
241 {
242
243 this->add_item(t);
244
245 return *this;
246
247 }
248
249
250 base_array & operator += (const base_array & a)
251 {
252
253 if (this != &a)
254 {
255
256 auto i = this->size();
257
258 auto add = a.size();
259
260 auto c = i + add;
261
262 set_size(c);
263
264 auto ptarget = this->data() + i;
265
266 auto psource = a.data();
267
268 while(add > 0)
269 {
270
271 *ptarget = *psource;
272
273 ptarget++;
274
275 psource++;
276
277 add--;
278
279 }
280
281 }
282
283 return *this;
284
285 }
286
287
288 base_array & operator += (base_array && base_array)
289 {
290
291 if (this != &base_array)
292 {
293
294 auto i = this->size();
295
296 auto add = base_array.size();
297
298 transfer(i, add, ::transfer(base_array));
299
300 }
301
302 return *this;
303
304 }
305
306
307 template < prototype_array ARRAY >
308 base_array & operator += (const ARRAY & a)
309 {
310
311 auto i = this->size();
312
313 auto add = a.size();
314
315 auto c = i + add;
316
317 this->set_size(c);
318
319 //::collection::index j = 0;
320
321 auto p = a.data();
322
323 for (; i < c; i++, p++)
324 {
325
326 this->element_at(i) = *p;
327
328 }
329
330 return *this;
331
332 }
333
334
335 base_array & operator += (const std::initializer_list < TYPE > & initializer_list)
336 {
337
338 for (auto & item : initializer_list)
339 {
340
341 this->add(item);
342
343 }
344
345 return *this;
346
347 }
348
349
350 base_array & operator = (const base_array & a)
351 {
352
353 if (this != &a)
354 {
355
356 auto c = a.size();
357
358 set_size(c);
359
360 auto ptarget = this->data();
361
362 auto psource = a.data();
363
364 TYPED::copy_count(ptarget, psource, c);
365
366 }
367
368 return *this;
369
370 }
371
372
373 base_array & operator = (base_array && base_array)
374 {
375
376 if (this != &base_array)
377 {
378
379 transfer(::transfer(base_array));
380
381 }
382
383 return *this;
384
385 }
386
387
388 template < prototype_container CONTAINER >
389 base_array & assign_a_container(const CONTAINER & container)
390 {
391
392 this->set_size(container.size());
393
394 auto p = container.begin();
395
396 ::collection::index i = 0;
397
398 while (!container.is_end(p))
399 {
400
401 this->element_at(i) = *p;
402
403 i++;
404
405 p++;
406
407 }
408
409 return *this;
410
411 }
412
413
414 template < prototype_container CONTAINER >
415 base_array & copy(const CONTAINER & container)
416 {
417
418 this->set_size(container.size());
419
420 auto p = container.begin();
421
422 ::collection::index i = 0;
423
424 while (!container.is_end(p))
425 {
426
427 ::copy(&this->element_at(i), &(*p));
428
429 i++;
430
431 p++;
432
433 }
434
435 return *this;
436
437 }
438
439
440 template < std_range STDRANGE >
441 base_array & assign_a_std_range (const STDRANGE & range)
442 {
443
444 this->clear();
445
446 for (auto & item : range)
447 {
448
449 this->add(item);
450
451 }
452
453 return *this;
454
455 }
456
457
458 template < prototype_container CONTAINER >
459 base_array & operator = (const CONTAINER & container)
460 requires (!::std::is_base_of<base_array, CONTAINER >::value)
461 {
462
463 return this->assign_a_container(container);
464
465 }
466
467
468 template < std_range STDRANGE >
469 base_array & operator = (const STDRANGE & range)
470 requires (!::std::is_base_of<base_array, STDRANGE >::value
472 {
473
474 return this->assign_a_std_range(range);
475
476 }
477
478
479 base_array & operator = (const std::initializer_list<TYPE> & initializerlist)
480 {
481
482 return this->assign_a_std_range(initializerlist);
483
484 }
485
486 // Forwarding constructor arguments to T's constructor
487 template<typename... Args>
488 TYPE& add_construct(Args&&... args)
489 {
490 return this->add(TYPE(std::forward<Args>(args)...));
491 }
492 TYPE& add_construct()
493 {
494 return this->add(TYPE());
495 }
496
497
498 TYPE& øadd()
499 {
500 TYPE t;
501 memset(&t, 0, sizeof(TYPE));
502 return this->add(t);
503 }
504
505
506
507 void add_initializer_list(const ::std::initializer_list < TYPE > & initializer_list)
508 {
509
510 for (auto & item : initializer_list)
511 {
512
513 add_item(item);
514
515 }
516
517 }
518
519
520 inline base_array & transfer(base_array && a)
521 {
522
523 if (this != &a)
524 {
525
526 destroy();
527
528 ARRAY_RANGE::operator=(::transfer(a));
529
530 m_countAddUp = a.m_countAddUp;
531
532 m_countAllocation = a.m_countAllocation;
533
534 }
535
536 return *this;
537
538 }
539
540
541 inline base_array & transfer(::collection::index i, ::collection::count add, base_array && a, collection::index j = 0)
542 {
543
544 if (this != &a)
545 {
546
547 auto c = i + add;
548
549 set_size(c);
550
551 for (; i < c; i++, j++)
552 {
553
554 this->element_at(i) = a[j];
555
556 }
557
558 }
559
560 return *this;
561
562 }
563
564
565 inline ::range<rear_iterator> rear_payloads()
566 {
567
568 return ::range<rear_iterator>(this->rear_begin(), this->rear_end());
569
570 }
571
572
573 inline ::range<const_rear_iterator> rear_payloads() const
574 {
575
576 return ::range<const_rear_iterator>(this->rear_begin(), this->rear_end());
577
578 }
579
580
581 ::block as_block()const
582 {
583
584 return { (const void*)this->data(), this->get_size_in_bytes() };
585
586 }
587
588
589 //template < typename iterator >
590 //struct make_iterator : iterator
591 //{
592
593 // using CONTAINER = typename iterator::CONTAINER;
594
595
596 // make_iterator()
597 // {
598 // this->m_pelementBeg = (TYPE *)nullptr;
599 // this->m_pelementEnd = (TYPE *)nullptr;
600 // this->m_pcontainer = (CONTAINER *)nullptr;
601 // this->m_pelement = this->m_pelementBeg;
602 // }
603
604 // make_iterator(::collection::index iStart, ::collection::index iEnd, const CONTAINER * parray = nullptr)
605 // {
606 // this->m_pelementBeg = (TYPE *)(parray->m_begin + iStart);
607 // this->m_pelementEnd = (TYPE *)(parray->m_begin + (iEnd < 0 ? parray->size() + iEnd + 1 : iEnd));
608 // this->m_pcontainer = (CONTAINER *)parray;
609 // this->m_pelement = this->m_pelementBeg;
610 // }
611
612 // make_iterator(const CONTAINER * parray, const TYPE * pmatter = nullptr, const TYPE * pelementEnd = nullptr)
613 // {
614 // this->m_pelementBeg = (TYPE *)pmatter;
615 // this->m_pelementEnd = (TYPE *)pelementEnd;
616 // this->m_pcontainer = (CONTAINER *)parray;
617 // this->m_pelement = this->m_pelementBeg;
618 // }
619
620
621 // make_iterator(const make_iterator & iterator)
622 // {
623 // this->m_pelementBeg = (TYPE *)iterator.m_pelementBeg;
624 // this->m_pelementEnd = (TYPE *)iterator.m_pelementEnd;
625 // this->m_pelement = iterator.m_pelement;
626 // this->m_pcontainer = iterator.m_pcontainer;
627 // }
628
629
630 // make_iterator begin()
631 // {
632
633 // return make_iterator(this->m_pcontainer, this->m_pelementBeg, this->m_pelementEnd);
634
635 // }
636
637
638 // make_iterator end()
639 // {
640
641 // return make_iterator(this->m_pcontainer, this->m_pelementEnd, this->m_pelementEnd);
642
643 // }
644
645
646 // make_iterator & operator ++ ()
647 // {
648
649 // this->m_pelement++;
650 // return *this;
651
652 // }
653
654
655 // make_iterator operator ++ (::i32)
656 // {
657
658 // auto it = *this;
659
660 // this->m_pelement++;
661 // return it;
662
663 // }
664
665
666 // make_iterator operator + (::collection::count c) const
667 // {
668
669 // return { this->m_pcontainer, this->m_pelement + c };
670
671 // }
672
673
674 // make_iterator operator - (const make_iterator & it) const
675 // {
676
677 // return { this->m_pcontainer, this->m_pelement - it.index() };
678
679 // }
680
681
682 // bool operator == (const make_iterator & it) const
683 // {
684
685
686 // if (this->m_pcontainer != it.m_pcontainer)
687 // {
688
689 // return false;
690
691 // }
692
693 // return this->m_pelement == it.m_pelement;
694
695 // }
696
697
698 // bool operator >= (const make_iterator & it) const
699 // {
700
701
702 // if (this->m_pcontainer != it.m_pcontainer)
703 // {
704
705 // return false;
706
707 // }
708
709 // return this->m_pelement >= it.m_pelement;
710
711 // }
712
713
714 // bool operator > (const make_iterator & it) const
715 // {
716
717 // if (this->m_pcontainer != it.m_pcontainer)
718 // {
719
720 // return false;
721
722 // }
723
724 // return this->m_pelement > it.m_pelement;
725
726 // }
727
728
729 // bool operator != (const make_iterator & it) const
730 // {
731
732 // if (this->m_pcontainer != it.m_pcontainer)
733 // {
734
735 // return true;
736
737 // }
738
739 // return this->m_pelement != it.m_pelement;
740
741 // }
742
743 // bool operator < (const make_iterator & it) const
744 // {
745
746 // if (this->m_pcontainer != it.m_pcontainer)
747 // {
748
749 // return false;
750
751 // }
752
753 // return this->m_pelement < it.m_pelement;
754
755
756 // }
757
758 // bool operator <= (const make_iterator & it) const
759 // {
760
761 // if (this->m_pcontainer != it.m_pcontainer)
762 // {
763
764 // return false;
765
766 // }
767
768 // return this->m_pelement <= it.m_pelement;
769
770
771 // }
772
773
774 // bool operator == (const TYPE * pmatter) const
775 // {
776
777
778 // if (!this->m_pcontainer->contains(pmatter))
779 // {
780
781 // return false;
782
783 // }
784
785 // return this->m_pelement == pmatter;
786
787 // }
788
789
790 // bool operator >= (const TYPE * pmatter) const
791 // {
792
793
794 // if (!this->m_pcontainer->contains(pmatter))
795 // {
796
797 // return false;
798
799 // }
800
801 // return this->m_pelement >= pmatter;
802
803 // }
804
805
806 // bool operator > (const TYPE * pmatter) const
807 // {
808
809 // if (!this->m_pcontainer->contains(pmatter))
810 // {
811
812 // return false;
813
814 // }
815
816 // return this->m_pelement > pmatter;
817
818 // }
819
820
821 // bool operator != (const TYPE * pmatter) const
822 // {
823
824 // if (!this->m_pcontainer->contains(pmatter))
825 // {
826
827 // return true;
828
829 // }
830
831 // return this->m_pelement != pmatter;
832
833 // }
834
835 // bool operator < (const TYPE * pmatter) const
836 // {
837
838 // if (!this->m_pcontainer->contains(pmatter))
839 // {
840
841 // return false;
842
843 // }
844
845 // return this->m_pelement < pmatter;
846
847
848 // }
849
850 // bool operator <= (const TYPE * pmatter) const
851 // {
852
853 // if (!this->m_pcontainer->contains(pmatter))
854 // {
855
856 // return false;
857
858 // }
859
860 // return this->m_pelement <= pmatter;
861
862
863 // }
864
865 // make_iterator & operator = (const make_iterator & it)
866 // {
867
868 // if (this != &it)
869 // {
870
871 // this->m_pcontainer = it.m_pcontainer;
872
873 // this->m_pelement = it.m_pelement;
874
875 // }
876
877 // return *this;
878
879 // }
880
881 // ::collection::index index() const { return this->m_pelement - this->m_pcontainer->m_begin; }
882
883 //};
884
885 //__declare_iterator(iterator, this->m_pelement);
886 //__declare_iterator(ref_iterator, *this->m_pelement);
887
888 //void this_is_a_container() {}
889
890 //enum_type get_payload_type() const override { return t_etypeContainer; }
891
892
893 inline memsize length_in_bytes() const { return this->size() * sizeof(TYPE); }
894
895 //inline auto values(::collection::index iStart = 0, ::collection::index iEnd = -1) const { return iterator(iStart, iEnd, this); }
896
897
898 //inline iterator begin()
899 //{
900
901 // return iterator(0, (::collection::index)this->size(), this);
902
903 //}
904
905
906 //inline iterator end()
907 //{
908
909 // return iterator((::collection::index)this->size(), (::collection::index)this->size(), this);
910
911 //}
912
913
914
915
916
917 //inline const TYPE * get_data() const { return this->begin(); }
918 //inline TYPE * get_data() { return this->begin(); }
919
920
921
922
923 inline bool contains_address(const TYPE * pmatter) const { return pmatter >= this->m_begin && pmatter < this->end(); }
924
925
926 inline ::collection::count get_size() const;
927 inline ::collection::count get_size_in_bytes() const;
928 inline ::collection::count get_count() const;
929 inline ::collection::count get_byte_count() const;
930 inline ::collection::count get_length() const;
931 //inline ::collection::count size() const;
932 inline ::collection::count count() const;
933 inline ::collection::count length() const;
934 inline ::collection::count byte_count() const { return get_byte_count(); }
935
936
937 inline bool has_element() const noexcept { return this->size() > 0; }
938 inline bool is_empty(::collection::count countMinimum = 0) const noexcept { return this->size() <= countMinimum; }
939 inline bool empty(::collection::count countMinimum = 0) const noexcept { return this->size() <= countMinimum; }
940 inline bool has_elements(::collection::count countMinimum = 1) const noexcept { return this->size() >= countMinimum; }
941
942
943 inline this_iterator back(::collection::index i = -1) { return (this_iterator)(this->begin() + this->get_upper_bound(i)); }
944 inline const_iterator back(::collection::index i = -1) const { return (const_iterator)(this->begin() + this->get_upper_bound(i)); }
945
946 void ensure_index_ok(::collection::index nIndex) const { if (nIndex < 0 || nIndex >= this->size()) throw_exception(error_index_out_of_bounds); }
947
948
949 inline const TYPE& at(::collection::index nIndex) const { ensure_index_ok(nIndex); return this->element_at(nIndex); }
950 inline TYPE& at(::collection::index nIndex) { ensure_index_ok(nIndex); return this->element_at(nIndex); }
951
952 inline void set_at_grow(::collection::index nIndex, ARG_TYPE newElement);
953 inline TYPE & element_at_grow(::collection::index nIndex);
954 inline TYPE & atø(::collection::index nIndex) { return this->element_at_grow(nIndex); }
955
956 inline void set_each(ARG_TYPE element, ::collection::index iStart = 0, ::collection::count c = -1);
957
958 template < ::std::size_t N >
959 TYPE & get() { return this->element_at(N); }
960
961
962 void reserve(::collection::count newAllocationSize);
963
964
965 ::collection::count set_size(::collection::count nNewSize);
966
967
968 //::collection::count set_size(::collection::count nNewSize, ::collection::count nGrowBy = -1); // does not call default constructors on ___new items/elements
969
971 template < pointer_not_castable_to < TYPE * > P >
972 ::collection::count allocate(::collection::count nNewSize, bool bShrink, bool bRaw, P & p)
973 {
974 TYPE t(p);
975 return _allocate(nNewSize, bShrink, bRaw, false, &t);
976 }
977 template < pointer_castable_to < TYPE * > T >
978 ::collection::count allocate(::collection::count nNewSize, bool bShrink, bool bRaw, T & t)
979 {
980 return _allocate(nNewSize, bShrink, bRaw, false, &t);
981 }
982 ::collection::count allocate(::collection::count nNewSize, bool bShrink, bool bRaw)
983 {
984 return _allocate(nNewSize, bShrink, bRaw, false, nullptr);
985 }
986 ::collection::count _allocate(::collection::count nNewSize, bool bShrink, bool bRaw, bool bFollowingIsArray, const TYPE * type);
987
988 //::collection::count allocate(::collection::count nNewSize, bool bShrink, const TYPE * ptype = nullptr);
989
990 ::collection::count allocate_in_bytes(::collection::count nNewSize, bool bShrink, bool bRaw);
991
992// ::collection::count set_raw_size(::collection::count nNewSize, ::collection::count nGrowBy = -1); // does not call constructors and destructors on items/elements
993
994 ::collection::count resize(::collection::count nNewSize) { return set_size(nNewSize); }
995 ::collection::count resize(::collection::count nNewSize, ARG_TYPE t);
996
997 void free_extra();
998 void destroy();
999
1000 inline void __swap(::collection::index index1, ::collection::index index2);
1001 inline void __swap(iterator index1, iterator index2);
1002 inline void __swap(const_iterator index1, const_iterator index2);
1003
1004
1005 void set_all(const TYPE & t);
1006
1007
1008 rear_iterator rear_begin()
1009 {
1010 return this->m_end - 1;
1011 }
1012
1013 rear_iterator rear_end()
1014 {
1015 return this->m_begin - 1;
1016 }
1017
1018 const_rear_iterator rear_begin() const
1019 {
1020 return (const_rear_iterator&)this->m_end - 1;
1021 }
1022
1023 const_rear_iterator rear_end() const
1024 {
1025 return (const_rear_iterator&)this->m_begin - 1;
1026 }
1027
1028
1029 void zero(::collection::index iStart = 0, ::collection::count c = -1);
1030
1031 //template < prototype_array ARRAY >
1032 //void _001RemoveIndexes(ARRAY & ia);
1033
1034 template < prototype_array ARRAY >
1035 void erase_indexes(const ARRAY & ia);
1036
1037 template < prototype_array ARRAY >
1038 void erase_descending_indexes(const ARRAY & ia);
1039
1040
1041
1042
1043 inline void erase_first(::collection::count c = 1);
1044 inline void erase_last(::collection::count c = 1);
1045 inline ::collection::count erase_all();
1046 inline void clear();
1047
1048
1049 void on_construct_element(TYPE * p) { TYPED::construct(p); }
1050 void on_construct_element(TYPE * p, ::collection::count c) { TYPED::construct_count(p, c); }
1051 void on_destruct_element(TYPE * p) { TYPED::destruct(p); }
1052 void on_copy_element(::collection::index i, const TYPE * p) { TYPED::copy(&this->m_begin[i], p); }
1053
1054
1055 // FISC - Flaw in some compiler
1056 //inline operator TYPE *() { return this->m_begin; }
1057 //inline operator const TYPE *() const { return this->m_begin; }
1058
1059
1060 inline const TYPE & operator[](::collection::index i) const { return this->m_begin[i]; }
1061 inline TYPE & operator[](::collection::index i) { return this->m_begin[i]; }
1062
1063
1064 TYPE * raw_allocate_at(::collection::index i, ::collection::count c);
1065
1066
1067 TYPE & insert_at(::collection::index nIndex, const TYPE & newElement, ::collection::count nCount = 1);
1068 TYPE * insert_at(::collection::index nStartIndex, const TYPE * p, ::collection::count nCount = 1);
1069
1070 TYPE & insert_at_grow(::collection::index nIndex, const TYPE &newElement, ::collection::count nCount = 1);
1071 TYPE * insert_at_grow(::collection::index nStartIndex, const TYPE *p, ::collection::count nCount = 1);
1072
1073 TYPE * insert_array_at(::collection::index nStartIndex, const base_array * pNewArray);
1074
1075
1076 ::collection::index erase_at(::collection::index nIndex, ::collection::count nCount = 1);
1077
1078
1079 template < typename EQUAL_TYPE >
1080 ::collection::index erase_at(const EQUAL_TYPE *p, ::collection::count nCount = 1)
1081 requires(::std::is_same < EQUAL_TYPE, TYPE >::value) {
1082 return this->erase_at(index_of(p), nCount);
1083 }
1084
1085
1086 //::collection::index allocate_at(::collection::index nIndex, ::collection::count nCount = 1);
1087
1088
1089 TYPE pick_at(::collection::index nIndex);
1090 TYPE pick_first(::collection::index nIndex = 0) { return ::transfer(pick_at(nIndex)); }
1091 TYPE pick_last(::collection::index nIndex = -1) { return ::transfer(pick_at(this->size() + nIndex)); }
1092 base_array pick_at(::collection::index nIndex, ::collection::count nCount);
1093
1094
1095 ::collection::index index_of(const TYPE * p) const { auto i = p - this->m_begin; return i >= 0 && i < this->size() ? i : -1; }
1096
1097
1098 bool erase(const TYPE * p) { auto i = index_of(p); if (not_found(i)) return false; return found(erase_at(i)); }
1099 ::collection::count erase(const TYPE * begin, const TYPE * end);
1100
1101 iterator erase(iterator p)
1102 {
1103
1104 this->erase_at(index_of(p));
1105
1106 return p;
1107
1108 }
1109
1110 template < typename ITERATOR2 >
1111 inline void erase(const ITERATOR2 & begin, const ITERATOR2 & last);
1112
1113
1114 inline TYPE pop(::collection::index i = -1);
1115 inline ::collection::index push(ARG_TYPE newElement);
1116 inline void pop_last(::collection::index i = -1);
1117 inline TYPE & add_item(ARG_TYPE newElement);
1118 inline TYPE & add(ARG_TYPE newElement) { return this->add_item(newElement); }
1119 inline TYPE& add_new();
1120
1121
1122 inline TYPE pop_first(::collection::index i = 0);
1123
1124 inline TYPE takeAt(::collection::index i);
1125 inline TYPE takeFirst(::collection::index i = 0);
1126 inline TYPE takeLast(::collection::index i = -1);
1127
1128
1129 template < typename CONTAINER >
1130 ::collection::count append_container(const CONTAINER & container);
1131 ::collection::count append_initializer_list(const ::std::initializer_list < TYPE > & list_base);
1132 ::collection::count append(const TYPE * p, ::collection::count c);
1133 ::collection::count append_element(const TYPE & t, ::collection::count c);
1134 ::collection::count append(const base_array & src); // return old i32_size
1135 ::collection::count rear_append(const TYPE * p, ::collection::count c);
1136 ::collection::count rear_append(const base_array & src); // return old i32_size
1137 template < typename CONTAINER >
1138 void copy_container(const CONTAINER & container);
1139 void copy_initializer_list(const ::std::initializer_list < TYPE > & list_base);
1140 void copy_element(const TYPE & t, ::collection::count c);
1141 void copy(const TYPE * p, ::collection::count c);
1142 void copy(const base_array & src);
1143
1144 void assign_element(const TYPE & t, ::collection::count c)
1145 {
1146 this->copy_element(t, c);
1147
1148 }
1149
1150 void assign(const TYPE * p, ::collection::count c);
1151
1152
1153
1154 //template < prototype_container CONTAINER >
1155 //::collection::count append(const CONTAINER & container)
1156 //{
1157
1158 // ::collection::count c = 0;
1159
1160 // for (auto& item : container)
1161 // {
1162
1163 // add(item);
1164
1165 // c++;
1166
1167 // }
1168
1169 // return c;
1170
1171 //}
1172
1173
1174
1175 //void on_after_read();
1176
1177 template < typename PRED >
1178 ::collection::count predicate_each(PRED pred, ::collection::index iStart = 0, ::collection::count c = -1)
1179 {
1180
1181 ::collection::index iEnd = c < 0 ? get_count() + c : iStart + c - 1;
1182
1183 ::i32 cProcessed = 0;
1184
1185 for (::collection::index i = iStart; i <= iEnd; i++)
1186 {
1187
1188 pred(this->m_begin[i]);
1189
1190 cProcessed++;
1191
1192 }
1193
1194 return cProcessed;
1195
1196 }
1197
1198 template < typename PRED >
1199 ::collection::count predicate_each(PRED pred, ::collection::index iStart = 0, ::collection::count c = -1) const
1200 {
1201
1202 return ((base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >*)this)->predicate_each(pred, iStart, c);
1203
1204 }
1205
1206
1207 inline bool is_index_ok(::collection::index iIndex) const { return iIndex >= 0 && iIndex < get_count(); }
1208
1209
1210 inline bool is_last_index(::collection::index iIndex) const { return iIndex >= this->get_upper_bound(); }
1211
1212
1213 template < typename PRED >
1214 bool predicate_contains(PRED pred, ::collection::index iStart = 0, ::collection::index iEnd = -1) const
1215 {
1216
1217 return this->predicate_find_first(pred, iStart, iEnd) >= 0;
1218
1219 }
1220
1221 template < typename OTHER_IS_PTR >
1222 TYPE_IS_PTR get_existing_defer_add(const OTHER_IS_PTR & p)
1223 {
1224
1225 for (::collection::index i = 0; i < this->get_count(); i++)
1226 {
1227
1228 auto & pelementHere = this->element_at(i);
1229
1230 if (pelementHere == p)
1231 {
1232
1233 return pelementHere;
1234
1235 }
1236 else if (*pelementHere == *p)
1237 {
1238
1239 return pelementHere;
1240
1241 }
1242
1243 }
1244
1245 this->add(p);
1246
1247 return p;
1248
1249 }
1250
1251
1252 template < typename OTHER_IS_PTR >
1253 void defer_use_existing(OTHER_IS_PTR & p)
1254 {
1255
1256 for (::collection::index i = 0; i < this->get_count(); i++)
1257 {
1258
1259 auto & pelementHere = this->element_at(i);
1260
1261 if (pelementHere == p)
1262 {
1263
1264 return;
1265
1266 }
1267 else if (*pelementHere == *p)
1268 {
1269
1270 p = pelementHere;
1271
1272 return;
1273
1274 }
1275
1276 }
1277
1278 this->add(p);
1279
1280 }
1281
1282
1283 template < typename OTHER_IS_PTR >
1284 TYPE_IS_PTR get_existing(const OTHER_IS_PTR & p) const
1285 {
1286
1287 for (::collection::index i = 0; i < this->get_count(); i++)
1288 {
1289
1290 auto & pelementHere = this->element_at(i);
1291
1292 if (pelementHere == p)
1293 {
1294
1295 return pelementHere;
1296
1297 }
1298 else if (*pelementHere == *p)
1299 {
1300
1301 return pelementHere;
1302
1303 }
1304
1305 }
1306
1307 return p;
1308
1309 }
1310
1311
1312 template < typename OBJECT, typename ATTRIBUTE >
1313 TYPE_IS_PTR merge_get_existing(const TYPE_IS_PTR & p, const OBJECT& pparticle, const ATTRIBUTE& attribute)
1314 {
1315
1316 auto pModified = allocateø typename TYPE_IS_PTR::TYPE (*p);
1317
1318 pModified->process(pparticle, attribute);
1319
1320 return this->get_existing(pModified);
1321
1322 }
1323
1324
1325 template < typename PRED >
1326 ::collection::index predicate_find_first(PRED pred, ::collection::index iStart = 0, ::collection::index iEnd = -1) const
1327 {
1328
1329 if (iEnd < 0)
1330 {
1331
1332 iEnd += get_count();
1333
1334 }
1335
1336 if (iEnd >= get_count())
1337 {
1338
1339 iEnd = get_count() - 1;
1340
1341 }
1342
1343 for (::collection::index i = iStart; i <= iEnd; i++)
1344 {
1345
1346 if (pred(this->m_begin[i]))
1347 {
1348
1349 return i;
1350
1351 }
1352
1353 }
1354
1355 return -1;
1356
1357 }
1358
1359
1360 template < typename PRED >
1361 ::collection::index predicate_find_last(PRED pred, ::collection::index iLast = -1)
1362 {
1363
1364 if (iLast < 0)
1365 {
1366
1367 iLast += get_count();
1368
1369 }
1370
1371 for (::collection::index i = iLast; i >= 0; i--)
1372 {
1373
1374 if (pred(this->m_begin[i]))
1375 {
1376
1377 return i;
1378
1379 }
1380
1381 }
1382
1383 return -1;
1384
1385 }
1386
1387
1388 template < typename PRED >
1389 TYPE * predicate_get_first(PRED pred)
1390 {
1391
1392 for (::i32 i = 0; i < get_count(); i++)
1393 {
1394
1395 if (pred(this->m_begin[i]))
1396 {
1397
1398 return &this->element_at(i);
1399
1400 }
1401
1402 }
1403
1404 return nullptr;
1405
1406 }
1407
1408
1409 template < typename PRED >
1410 ::collection::count predicate_get_count(PRED pred)
1411 {
1412
1413 ::collection::count c = 0;
1414
1415 for (::i32 i = 0; i < get_count(); i++)
1416 {
1417
1418 if (pred(this->m_begin[i]))
1419 {
1420
1421 c++;
1422
1423 }
1424
1425 }
1426
1427 return c;
1428
1429 }
1430
1431
1432 template < typename PRED >
1433 ::collection::count predicate_erase(PRED pred)
1434 {
1435
1436 ::collection::count cTotal = 0;
1437
1438 for (::i32 i = 0; i < get_count();)
1439 {
1440
1441 if (!pred(this->m_begin[i]))
1442 {
1443
1444 i++;
1445
1446 }
1447 else
1448 {
1449
1450 ::i32 iStart = i;
1451
1452 ::i32 iCount = 1;
1453
1454 i++;
1455
1456 for (; i < get_count();)
1457 {
1458
1459 if (!pred(this->m_begin[i]))
1460 {
1461
1462 break;
1463
1464 }
1465
1466 iCount++;
1467
1468 i++;
1469
1470 }
1471
1472 erase_at(iStart, iCount);
1473
1474 cTotal += iCount;
1475
1476 i = iStart;
1477
1478 }
1479
1480 }
1481
1482 return cTotal;
1483
1484 }
1485
1486
1487 template < typename F >
1488 void each(F f)
1489 {
1490
1491 for (::collection::index i = 0; i < get_count(); i++)
1492 {
1493
1494 f(this->m_begin[i]);
1495
1496 }
1497
1498 }
1499
1500
1501 template < typename PRED >
1502 void predicate_sort(PRED pred);
1503
1504
1505 template < typename T, typename PRED >
1506 ::collection::index predicate_binary_search(const T & t, PRED pred) const;
1507
1508
1509 inline bool valid_iter(iterator first, iterator last)
1510 {
1511
1512 return first < last;
1513
1514 }
1515
1516
1517 inline bool rvalid_iter(iterator first, iterator last)
1518 {
1519
1520 return first > last;
1521
1522 }
1523
1524
1525 inline TYPE& operator%(::collection::index nIndex)
1526 {
1527
1528 return this->element_at(nIndex% this->get_size());
1529
1530 }
1531
1532
1533 inline const TYPE& operator%(::collection::index nIndex) const
1534 {
1535
1536 return this->element_at(nIndex% this->get_size());
1537
1538 }
1539
1540
1541 bool is_version(::collection::index i)
1542 {
1543
1544 return true;
1545
1546 //if (!m_pvarOptions)
1547 //{
1548
1549 // return i <= 0;
1550
1551 //}
1552
1553 //return i <= options()["version"].as_i32();
1554
1555 }
1556
1557
1558};
1559
1560
1561//template < class TYPE, class ARG_TYPE, class TYPED, class MEMORY, ::enum_type t_etypeContainer >
1562//class base_array :
1563// virtual public ::particle,
1564// public base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >
1565//{
1566//public:
1567//
1568//
1569// using BASE_ARRAY = base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >;
1570//
1571//
1572// //base_array() : base_array< TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >() {}
1573// //template < typename ...Args >
1574// //base_array(Args&&... args) :
1575// // base_array< TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >(::std::forward < Args >(args)...)
1576// //{
1577// //}
1578//
1579// base_array() {}
1580// base_array(std::initializer_list < TYPE > initializer_list) :BASE_ARRAY(initializer_list) {}
1581// base_array(const BASE_ARRAY & a) :BASE_ARRAY(a) {}
1582// base_array(BASE_ARRAY && a) noexcept :BASE_ARRAY(a) {}
1583// base_array(const TYPE * p, ::collection::count c) :BASE_ARRAY(p, c) {}
1584// base_array(::range < typename BASE_ARRAY::const_iterator > constrange) :
1585// BASE_ARRAY(constrange.begin(), constrange.end()) {}
1586// template < prototype_integral INTEGRAL >
1587// base_array(typename BASE_ARRAY::const_iterator begin, INTEGRAL count) :
1588// BASE_ARRAY(begin, begin + count) {}
1589// base_array(typename BASE_ARRAY::const_iterator begin, typename BASE_ARRAY::const_iterator end)
1590// {
1591// auto p = this->begin();
1592// while (p != end) add(*p);
1593// }
1594//
1595//
1596// void destroy()
1597// {
1598//
1599// particle::destroy();
1600//
1601// BASE_ARRAY::destroy();
1602//
1603// }
1604//
1605//
1606//};
1607
1608
1609template < prototype_integral INTEGRAL, class TYPE, class ARG_TYPE, class TYPED = ::typed::nodef < TYPE >, class MEMORY = ::heap::typed_memory < TYPE, ::heap::e_memory_array >, ::enum_type t_etypeContainer = e_type_element >
1610inline TYPE& operator%(INTEGRAL nIndex, const base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > & a)
1611{
1612
1613 return (TYPE &) (a % nIndex);
1614
1615}
1616
1617
1618
1619
1620template<typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer>
1621// base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(const ::e_array & earray, const ::e_flag &
1622// eflag, const ::e_status & estatus) :
1623base_array<TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer>::base_array() :
1624 //::particle(eflag, estatus),
1625 ARRAY_RANGE()
1626{
1627
1628 m_countAddUp = 0;
1629 m_countAllocation = 0;
1630 m_countAllocationOffset = 0;
1631}
1632
1633
1634template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1635//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(const ::e_array & earray, const ::e_flag & eflag, const ::e_status & estatus) :
1636//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(array_flags_t, const ::e_array & earray) :
1637base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(const ::enum_range & erange, ::collection::count c) :
1638 ARRAY_RANGE(nullptr, nullptr, erange)
1639{
1640
1641 m_countAddUp = c;
1642 m_countAllocation = 0;
1643 m_countAllocationOffset = 0;
1644
1645}
1646
1647
1648//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1649//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(base_array && array) noexcept :
1650// ARRAY_RANGE(array)
1651//{
1652//
1653// this->m_countAddUp = array.m_countAddUp;
1654// this->m_countAllocation = array.m_countAllocation;
1655// this->m_countAllocationOffset = array.m_countAllocationOffset;
1656//
1657// array.m_begin = nullptr;
1658// array.m_end = 0;
1659// array.m_countAllocation = 0;
1660//
1661//}
1662
1663
1664template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1665base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(const std::initializer_list < TYPE > & initializer_list) :
1666 base_array()
1667{
1668
1669 for (auto & item : initializer_list)
1670 {
1671
1672 add(item);
1673
1674 }
1675
1676}
1677
1678
1679//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1680//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(const base_array & array)
1681//{
1682//
1683// m_countAddUp = 0;
1684// this->m_begin = nullptr;
1685// this->m_end = nullptr;
1686// m_countAllocation = 0;
1687// m_countAllocationOffset = 0;
1688// set_size(array.get_size());
1689//
1690// for (::collection::index i = 0; i < array.get_size(); i++)
1691// {
1692//
1693// element_at(i) = array[i];
1694//
1695// }
1696//
1697//}
1698
1699
1700
1701template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1702base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::~base_array ()
1703{
1704
1705 defer_destroy();
1706
1707}
1708
1709
1710template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1711::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::resize(::collection::count nNewSize, ARG_TYPE t)
1712{
1713
1714 return allocate(nNewSize, false, false, t);
1715
1716}
1717
1718
1719template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1720::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::allocate_in_bytes(::collection::count nNewSize, bool bShrink, bool bRaw)
1721{
1722
1723 return allocate((nNewSize + sizeof(TYPE)) / sizeof(TYPE), bShrink, bRaw);
1724
1725}
1726
1727
1728template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1729::collection::index base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::erase_at(::collection::index first, ::collection::count in_count_out_last)
1730{
1731
1732 if (!this->prepare_first_in_count_last_out(first, in_count_out_last))
1733 {
1734
1735 //throw_exception(error_bad_argument);
1736
1737 return -1;
1738
1739 }
1740
1741 // abcde size 5;
1742 // erase a erase_at 0;
1743 // size 4; need to transfer 4 from 1 to 0
1744 // abcde size 5;
1745 // erase b erase_at 1;
1746 // size 4; need to transfer 3 from 2 to 1
1747
1748 auto nEraseCount = in_count_out_last - first + 1;
1749
1750 auto sizeOld = this->size();
1751
1756 //if (!(this->m_erange & e_range_array_allocate))
1757 //{
1758
1759 TYPED::destruct_count(this->m_begin + first, nEraseCount);
1760
1761 //}
1762
1763
1764 if (first == 0 && sizeOld > nEraseCount)
1765 {
1766
1767 m_countAllocationOffset -= nEraseCount;
1768
1769 this->m_begin += nEraseCount;
1770
1771 }
1772 else
1773 {
1774
1775 //if (this->m_erange & e_range_array_allocate)
1776 //{
1777
1778 // for (auto i = first + nEraseCount; i <= in_count_out_last; i++)
1779 // {
1780
1781 // element_at(i - nEraseCount) = this->element_at(i);
1782
1783 // }
1784
1785 //}
1786 //else
1787 {
1788
1789 auto nTransferCount = sizeOld - (first + nEraseCount);
1790
1791 if (nTransferCount > 0)
1792 {
1793
1794 ::safe_memory_transfer2(this->m_begin + first, nTransferCount, this->m_begin + first + nEraseCount,
1795 (memsize)nTransferCount);
1796 }
1797
1798 }
1799
1800 this->m_end -= nEraseCount;
1801
1802 }
1803
1804 return first;
1805
1806}
1807
1808
1809template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1810void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::defer_erase_allocation_offset()
1811{
1812
1813 if (this->m_countAllocationOffset >= 0)
1814 {
1815
1816 return;
1817
1818 }
1819
1820 auto size = this->size();
1821 auto pNewBeg = this->m_begin + this->m_countAllocationOffset;
1822 auto pNewEnd = this->m_end + this->m_countAllocationOffset;
1823
1824 ::safe_memory_transfer2(pNewBeg, this->m_countAllocation, this->m_begin, size);
1825
1826 this->m_begin = pNewBeg;
1827 this->m_end = pNewEnd;
1828 this->m_countAllocationOffset = 0;
1829
1830}
1831
1832
1833template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1834void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::free_extra()
1835{
1836
1837 auto size = this->size();
1838
1839 auto sizeNew = size;
1840
1841 //if(!(this->m_erange & e_range_array_allocate))
1842 {
1843
1844 if(sizeNew != m_countAllocation)
1845 {
1846
1847 // shrink to desired size
1848
1849#ifdef SIZE_T_MAX
1850
1851 ASSERT(sizeNew <= SIZE_T_MAX / sizeof(TYPE)); // no overflow
1852
1853#endif
1854
1855 TYPE* pNewData = nullptr;
1856
1857 if(sizeNew != 0)
1858 {
1859
1860 TYPE * pNewData;
1861
1862#if defined(__MCRTDBG) || MEMDLEAK
1863
1864#ifdef __MCRTDBG
1865
1866 if (::get_task() != nullptr)
1867 {
1868
1869 if (::get_task()->m_strFile.has_character())
1870 {
1871
1872 pNewData = MEMORY::allocate(size, ::get_task()->m_strFile, ::get_task()->m_iLine);
1873
1874 }
1875 else
1876 {
1877
1878 pNewData = MEMORY::allocate(size, __FILE__, __LINE__);
1879
1880 }
1881
1882 }
1883 else
1884 {
1885
1886 pNewData = MEMORY::allocate(size, __FILE__, __LINE__);
1887
1888 }
1889
1890#else
1891
1892 if (::get_task_object_debug().has_character())
1893 {
1894
1895 pNewData = MEMORY::allocate(size, ::get_task_object_debug(), 0);
1896
1897 }
1898 else
1899 {
1900
1901 pNewData = MEMORY::allocate(size, __FILE__, __LINE__);
1902
1903 }
1904
1905#endif
1906
1907#else
1908
1909 pNewData = MEMORY::allocate(sizeNew, &sizeNew);
1910
1911#endif
1912
1913 // copy ___new data from old
1914 ::safe_memory_copy2(pNewData, (size_t)size,this->m_begin, (size_t)size);
1915
1916 }
1917
1918 // get rid of old stuff (note: no destructors called)
1919 MEMORY::free(this->m_begin);
1920
1921 this->m_begin = pNewData;
1922
1923 m_countAllocation = sizeNew;
1924
1925 this->m_end = this->m_begin + size;
1926
1927 }
1928
1929 }
1930
1931}
1932
1933
1934
1935template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1936void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::destroy()
1937{
1938
1939 if(this->m_begin != nullptr)
1940 {
1941
1942 auto size = this->size();
1943
1944 TYPED::destruct_count(this->m_begin, size);
1945
1946 //if(!(this->m_erange & e_range_array_allocate))
1947 {
1948
1949 MEMORY::free(this->m_begin + this->m_countAllocationOffset);
1950 this->m_begin = nullptr;
1951 this->m_end = nullptr;
1952 this->m_countAllocation = 0;
1953 this->m_countAllocationOffset = 0;
1954
1955 }
1956 //else
1957 //{
1958 // TYPED::construct_count(this->m_begin, size);
1959 // this->m_end = this->m_begin;
1960 // this->m_countAllocationOffset = 0;
1961 //}
1962
1963
1964 }
1965
1966}
1967
1968
1969template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1970TYPE * base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::raw_allocate_at(::collection::index i, ::collection::count c)
1971{
1972
1973 auto newSize = this->size() + c;
1974
1975 auto nMove = this->size() - i;
1976
1977 this->allocate(newSize, false, true);
1978
1979 ::safe_memory_transfer2(this->m_begin + i + c, (size_t) (nMove), this->m_begin + i, (size_t) (nMove));
1980
1981 return this->m_begin + i;
1982
1983}
1984
1985
1986template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
1987TYPE & base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::insert_at(::collection::index i, const TYPE & element, ::collection::count c)
1988{
1989
1990 auto p = this->raw_allocate_at(i, c);
1991
1992 TYPED::copy_construct_count(p, c, element);
1993
1994 return *p;
1995
1996}
1997
1998
1999template<typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer>
2000TYPE * base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::insert_at(::collection::index i, const TYPE * pelements, ::collection::count c)
2001{
2002
2003 auto p = this->raw_allocate_at(i, c);
2004
2005 TYPED::copy_construct_array(p, c, pelements);
2006
2007 return p;
2008
2009}
2010
2011
2012template<typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer>
2013TYPE &base_array<TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer>::insert_at_grow(::collection::index i, const TYPE &element,
2014 ::collection::count c)
2015{
2016
2017 ASSERT(i >= 0);
2018
2019 if (i > this->size())
2020 {
2021
2022 this->set_size(i);
2023
2024 }
2025
2026 return this->insert_at(i, element, c);
2027
2028}
2029
2030
2031template<typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer>
2032TYPE *base_array<TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer>::insert_at_grow(::collection::index i,
2033 const TYPE *pelements,
2034 ::collection::count c)
2035{
2036
2037 ASSERT(i >= 0);
2038
2039 if (i > this->size())
2040 {
2041
2042 this->set_size(i);
2043 }
2044
2045 return this->insert_at(i, pelements, c);
2046}
2047
2048
2049template<typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer>
2050TYPE * base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::insert_array_at(::collection::index i, const base_array * p)
2051{
2052
2053 return this->insert_at(i, p->m_begin, p->size());
2054
2055}
2056
2057
2058//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2059//::collection::index base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::allocate_at(::collection::index nIndex, ::collection::count nCount)
2060//{
2061//
2062// if(nCount <= 0)
2063// {
2064//
2065// return -1;
2066//
2067// }
2068//
2069// if(nIndex < 0)
2070// {
2071//
2072// throw_exception(error_bad_argument);
2073//
2074// }
2075//
2076// if(nIndex >= this->size())
2077// {
2078//
2079// // adding after the end of the array
2080// set_size(nIndex + nCount, -1); // grow so nIndex is valid
2081//
2082// }
2083// else
2084// {
2085//
2086// // inserting in the middle of the array
2087// ::collection::count nOldSize = (::collection::count) this->size();
2088//
2089// // grow it to ___new size
2090// set_size((::collection::count) this->size() + nCount, -1);
2091//
2092// // shift old data up to fill gap
2093// ::safe_memory_transfer(this->m_begin + nIndex + nCount, (size_t) ((nOldSize - nIndex) * sizeof(TYPE)), this->m_begin + nIndex, (size_t) ((nOldSize - nIndex) * sizeof(TYPE)));
2094//
2095// ::zero(this->m_begin + nIndex, nCount * sizeof(TYPE));
2096//
2097// TYPED::construct_count(this->m_begin + nIndex, nCount);
2098//
2099// }
2100//
2101// // insert ___new value in the gap
2102// ASSERT(nIndex + nCount <= this->size());
2103//
2104// return nIndex;
2105//
2106//}
2107
2108template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2109template < typename CONTAINER >
2110::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::append_container(const CONTAINER & container)
2111{
2112
2113 ::collection::count nOldSize = this->size();
2114
2115 for (auto& item : container)
2116 {
2117
2118 add((ARG_TYPE) item);
2119
2120 }
2121
2122 return nOldSize;
2123
2124}
2125
2126
2127template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2128::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::append_initializer_list(const ::std::initializer_list < TYPE >& list_base)
2129{
2130
2131 return append_container(list_base);
2132
2133}
2134
2135
2136template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2137::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::append_element(const TYPE & t, ::collection::count c)
2138{
2139
2140 ::collection::count nOldSize = this->size();
2141
2142 ::collection::count nSrcSize = c;
2143
2144 allocate(nOldSize + nSrcSize, false, true);
2145
2146 TYPED::copy_construct_count((this->m_begin + nOldSize), nSrcSize, t);
2147
2148 return nOldSize;
2149
2150}
2151
2152
2153template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2154::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::append(const TYPE * p, ::collection::count c)
2155{
2156
2157 ::collection::count nOldSize = this->size();
2158
2159 ::collection::count nSrcSize = c;
2160
2161 allocate(nOldSize + nSrcSize, false, true);
2162
2163 TYPED::copy_construct_array((this->m_begin + nOldSize), nSrcSize, p);
2164
2165 return nOldSize;
2166
2167}
2168
2169
2170template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2171void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::assign(const TYPE * p, ::collection::count c)
2172{
2173
2174 ::collection::count nOldSize = this->size();
2175
2176 ::collection::count nSrcSize = c;
2177
2178 allocate(nOldSize + nSrcSize, false, true);
2179
2180 TYPED::copy_construct_array((this->m_begin + nOldSize), nSrcSize, p);
2181
2182 //return nOldSize;
2183
2184}
2185
2186
2187
2188template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2189::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::append(const base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > & src)
2190{
2191
2192 return append(src.data(), src.size());
2193
2194}
2195
2196
2197template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2198::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::rear_append(const TYPE * p, ::collection::count c)
2199{
2200
2201 ::collection::count nOldSize = this->size();
2202
2203 ::collection::count nSrcSize = c;
2204
2205 allocate(nOldSize + nSrcSize, false, true);
2206
2207 TYPED::rear_copy_construct_count((this->m_begin + nOldSize), nSrcSize, p);
2208
2209 return nOldSize;
2210
2211}
2212
2213
2214template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2215::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::rear_append(const base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > & src)
2216{
2217
2218 return rear_append(src.data(), src.size());
2219
2220}
2221
2222
2223template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2224template < typename CONTAINER >
2225void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::copy_container(const CONTAINER & container)
2226{
2227
2228 clear();
2229
2230 append_initializer_list(container);
2231
2232}
2233
2234
2235template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2236void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::copy_initializer_list(const ::std::initializer_list < TYPE >& list_base)
2237{
2238
2239 copy_container(list_base);
2240
2241}
2242
2243
2244template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2245void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::copy(const TYPE * p, ::collection::count c)
2246{
2247
2248 if(this->data() == p)
2249 {
2250
2251 if (c > this->size())
2252 {
2253
2254 throw_exception(error_wrong_state);
2255
2256 }
2257 else if (c < this->size())
2258 {
2259
2260 set_size(c);
2261
2262 }
2263
2264 return;
2265
2266 }
2267
2268 erase_all();
2269
2270 append(p, c);
2271
2272}
2273
2274
2275template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2276void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::copy_element(const TYPE & t, ::collection::count c)
2277{
2278
2279 if(this->data() == &t)
2280 {
2281
2282 if (c > this->size())
2283 {
2284
2285 throw_exception(error_wrong_state);
2286
2287 }
2288 else if (c < this->size())
2289 {
2290
2291 set_size(c);
2292
2293 }
2294
2295 return;
2296
2297 }
2298
2299 erase_all();
2300
2301 append_element(t, c);
2302
2303}
2304
2305
2306template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2307void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::copy(const base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >& src)
2308{
2309
2310 assign(src.data(), src.size());
2311
2312}
2313
2314
2315
2316//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2317//template < prototype_container CONTAINER >
2318//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >
2319//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::operator + (const CONTAINER & array) const
2320//{
2321//
2322// auto a = *this;
2323//
2324// a.append(array);
2325//
2326// return ::transfer(a);
2327//
2328//}
2329
2330//#include "sort.h"
2331
2332
2333template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2334template < prototype_array ARRAY >
2335void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::erase_indexes(const ARRAY & ia)
2336{
2337
2338
2339 // erase indexes
2340 for(::collection::index i = ia.get_upper_bound(); i >= 0; i--)
2341 {
2342
2343 erase_at(ia[i]);
2344
2345 }
2346
2347}
2348
2349
2350template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2351template < prototype_array ARRAY >
2352void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::erase_descending_indexes(const ARRAY & ia)
2353{
2354
2355 for(::collection::index i = 0; i < ia.get_count(); i++)
2356 {
2357
2358 erase_at(ia[i]);
2359
2360 }
2361
2362}
2363
2364
2365
2366//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2367//TYPE * base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::insert_at(::collection::index nIndex,base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > * pNewArray)
2368//{
2369//
2370// ASSERT(pNewArray != nullptr);
2371// ASSERT(nIndex >= 0); // will expand to meet need
2372//
2373// ::collection::count nCount = pNewArray->get_size();
2374//
2375// if (nCount <= 0)
2376// return this->end();
2377//
2378// if (nIndex < 0)
2379// throw_exception(error_bad_argument);
2380//
2381// if (nIndex >= this->size())
2382// {
2383//
2384// // adding after the end of the array
2385// set_size(nIndex + nCount, -1); // grow so nIndex is valid
2386//
2387// }
2388// else
2389// {
2390//
2391// // inserting in the middle of the array
2392// ::collection::count nOldSize = (::collection::count) this->size();
2393//
2394// set_size((::collection::count) (this->size() + nCount), -1); // grow it to ___new i32_size
2395// // destroy intial data before copying over it
2396// // shift old data up to fill gap
2397// ::safe_memory_transfer(this->m_begin + nIndex + nCount, (size_t) ((nOldSize - nIndex) * sizeof(TYPE)), this->m_begin + nIndex, (size_t) ((nOldSize - nIndex) * sizeof(TYPE)));
2398//
2399// ::zero(this->m_begin + nIndex, nCount* sizeof(TYPE));
2400//
2401// TYPED::construct_count(this->m_begin + nIndex, nCount);
2402//
2403// }
2404//
2405// // insert ___new value in the gap
2406// ASSERT(nIndex + nCount <= this->size());
2407//
2408// ::collection::index nIndexParam = nIndex;
2409//
2410// ::collection::index i = 0;
2411//
2412// while (nCount--)
2413// {
2414//
2415// TYPED::copy(this->m_begin + nIndex, pNewArray->m_begin + i);
2416//
2417// nIndex++;
2418//
2419// }
2420//
2421// return this->m_begin + nIndexParam;
2422//
2423//
2424//}
2425
2426
2427template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2428TYPE base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::pick_at(::collection::index nIndex)
2429{
2430
2431 ::collection::count nCount = 1;
2432
2433 ::collection::index nUpperBound = nIndex + nCount;
2434
2435 if (nIndex < 0 || nCount < 0 || (nUpperBound > this->size()) || (nUpperBound < nIndex) || (nUpperBound < nCount))
2436 {
2437
2438 throw_exception(error_bad_argument);
2439
2440 }
2441
2442 ::collection::count nMoveCount = this->size() - (nUpperBound);
2443
2444 auto t = ::transfer(this->m_begin[nIndex]);
2445
2446 //TYPED::destruct_count(this->m_begin + nIndex, nCount REFERENCING_DEBUGGING_COMMA_THIS);
2447
2448 if (nMoveCount)
2449 {
2450
2451 ::safe_memory_transfer2(this->m_begin + nIndex, (size_t)nMoveCount, this->m_begin + nUpperBound, (size_t)nMoveCount);
2452
2453 }
2454
2455 this->m_end -= nCount;
2456
2457 return ::transfer(t);
2458
2459}
2460
2461
2462template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2463base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::pick_at(::collection::index nIndex, ::collection::count nCount)
2464{
2465
2466 //ASSERT_OK(this);
2467
2468 ::collection::index nUpperBound = nIndex + nCount;
2469
2470 if (nIndex < 0 || nCount < 0 || (nUpperBound > this->size()) || (nUpperBound < nIndex) || (nUpperBound < nCount))
2471 {
2472
2473 throw_exception(error_bad_argument);
2474
2475 }
2476
2477 ::collection::count nMoveCount = this->size() - (nUpperBound);
2478
2479 base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > a(this->m_begin + nIndex, (size_t)nMoveCount);
2480
2481 TYPED::destruct_count(this->m_begin + nIndex, nCount);
2482
2483 //if (this->m_erange == e_range_array_allocate)
2484 //{
2485
2486 // TYPED::construct_count(this->m_begin + nIndex, nCount);
2487
2488 //}
2489
2490 if (nMoveCount)
2491 {
2492
2493 ::safe_memory_transfer2(this->m_begin + nIndex, (size_t)nMoveCount, this->m_begin + nUpperBound, (size_t)nMoveCount);
2494
2495 }
2496
2497 this->m_end -= nCount;
2498
2499 return a;
2500
2501}
2502
2503
2504//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2505//::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::set_raw_size(::collection::count nNewSize,::collection::count nGrowBy)
2506//{
2507//
2508// ::collection::count countOld = get_count();
2509//
2510// ASSERT(nNewSize >= 0);
2511//
2512// if(nNewSize < 0)
2513// throw_exception(error_bad_argument);
2514//
2515// if(nGrowBy >= 0)
2516// m_countAddUp = nGrowBy; // set ___new i32_size
2517//
2518// if(nNewSize == 0)
2519// {
2520//
2521// // shrink to nothing
2522// if(this->m_begin != nullptr)
2523// {
2524//
2525// MEMORY::free(this->m_begin);
2526//
2527// this->m_begin = nullptr;
2528//
2529// }
2530//
2531// this->m_end = nullptr;
2532// m_countAllocation = 0;
2533// }
2534// else if (this->m_begin == nullptr)
2535// {
2536// // create buffer big enough to hold number of requested elements or
2537// // m_countAddUp elements, whichever is larger.
2538//#ifdef SIZE_T_MAX
2539// if (nNewSize > SIZE_T_MAX / sizeof(TYPE))
2540// throw_exception(error_no_memory);
2541// ASSERT(nNewSize <= SIZE_T_MAX / sizeof(TYPE)); // no overflow
2542//#endif
2543// ::collection::count nAllocSize = (::collection::count) maximum(nNewSize, m_countAddUp);
2544//#if defined(__MCRTDBG) || MEMDLEAK
2545// if (::get_task() != nullptr)
2546// {
2547//#if defined(MEMDLEAK)
2548//
2549// if (::get_task()->m_strFile.has_character())
2550// {
2551//
2552// this->m_begin = MEMORY::allocate(nAllocSize, ::get_task()->m_strFile, 0);
2553//
2554// }
2555// else
2556// {
2557//
2558// this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
2559//
2560// }
2561//
2562//#else
2563//
2564// if (::get_task_object_debug().has_character())
2565// {
2566//
2567// this->m_begin = MEMORY::allocate(nAllocSize, ::get_task_object_debug(), ::get_task()->m_iLine);
2568//
2569// }
2570// else
2571// {
2572//
2573// this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
2574//
2575// }
2576//
2577//#endif
2578//
2579// }
2580// else
2581// {
2582//
2583// this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
2584//
2585// }
2586//
2587//#else
2588//
2589// this->m_begin = MEMORY::allocate(nAllocSize);
2590//
2591//#endif
2592//
2593// this->m_end = this->m_begin+ nNewSize;
2594// m_countAllocation = nAllocSize;
2595// }
2596// else if(nNewSize <= m_countAllocation)
2597// {
2598// this->m_end = this->m_begin+nNewSize;
2599// }
2600// else
2601// {
2602// // otherwise, grow aaa_base_array
2603// nGrowBy = (::collection::count) m_countAddUp;
2604// if(nGrowBy == 0)
2605// {
2606// // heuristically determine growth when nGrowBy == 0
2607// // (this avoids heap fragmentation in many situations)
2608// nGrowBy = (::collection::count) this->size();
2609// nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
2610// }
2611// ::collection::count nNewMax;
2612// if(nNewSize < m_countAllocation + nGrowBy)
2613// nNewMax = (::collection::count) (m_countAllocation + nGrowBy); // granularity
2614// else
2615// nNewMax = nNewSize; // no slush
2616//
2617// ASSERT(nNewMax >= m_countAllocation); // no wrap around
2618//
2619// if(nNewMax < m_countAllocation)
2620// throw_exception(error_bad_argument);
2621//
2622//#ifdef SIZE_T_MAX
2623// ASSERT(nNewMax <= SIZE_T_MAX / sizeof(TYPE)); // no overflow
2624//#endif
2625// TYPE * pNewData;
2626//#if defined(__MCRTDBG) || MEMDLEAK
2627// #ifdef __MCRTDBG
2628//
2629// if (::get_task() != nullptr)
2630// {
2631//
2632// if (::get_task()->m_strFile.has_character())
2633// {
2634//
2635// pNewData = MEMORY::allocate(nNewMax, ::get_task()->m_strFile, ::get_task()->m_iLine);
2636//
2637// }
2638// else
2639// {
2640//
2641// pNewData = MEMORY::allocate(nNewMax, __FILE__, __LINE__);
2642//
2643// }
2644//
2645// }
2646// else
2647// {
2648//
2649// pNewData = MEMORY::allocate(nNewMax, __FILE__, __LINE__);
2650//
2651// }
2652//
2653//#else
2654//
2655// if (::get_task_object_debug().has_character())
2656// {
2657//
2658// pNewData = MEMORY::allocate(nNewMax, ::get_task_object_debug(), ::get_task()->m_iLine);
2659//
2660// }
2661// else
2662// {
2663//
2664// pNewData = MEMORY::allocate(nNewMax, __FILE__, __LINE__);
2665//
2666// }
2667//
2668//#endif
2669//
2670//#else
2671//
2672// pNewData = MEMORY::allocate(nNewMax);
2673//
2674//#endif // copy ___new data from old
2675//
2676// ::safe_memory_copy(pNewData,(size_t)nNewMax * sizeof(TYPE),this->m_begin,(size_t)this->size() * sizeof(TYPE));
2677//
2678// ///for(::i32 i = 0; i < nNewSize - this->size(); i++)
2679// // get rid of old stuff (note: no destructors called)
2680// MEMORY::free(this->m_begin);
2681//
2682// this->m_begin = pNewData;
2683//
2684// this->m_end = this->m_begin + nNewSize;
2685//
2686// m_countAllocation = nNewMax;
2687//
2688// }
2689//
2690// return countOld;
2691//
2692//}
2693
2694
2695template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2696void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::reserve(::collection::count newAllocationSize)
2697{
2698
2699 if(newAllocationSize <= m_countAllocation)
2700 {
2701
2702 return;
2703
2704 }
2705
2706 if(m_countAllocation <= 0)
2707 {
2708
2709 ASSERT(this->m_begin == nullptr && this->m_end == nullptr);
2710
2711 if(newAllocationSize > UPTR_MAXIMUM / sizeof(TYPE))
2712 {
2713
2714 throw_exception(error_no_memory);
2715
2716 }
2717
2718 newAllocationSize = maximum(newAllocationSize, m_countAddUp);
2719
2720#if MEMDLEAK || defined(__MCRTDBG)
2721
2722 if(::get_task() != nullptr)
2723 {
2724
2725#if defined(__MCRTDBG)
2726
2727 if(::get_task()->m_strFile.has_character())
2728 {
2729
2730 this->m_begin = MEMORY::allocate(newAllocationSize, ::get_task()->m_strFile, ::get_task()->m_iLine);
2731
2732 }
2733 else
2734 {
2735
2736 this->m_begin = MEMORY::allocate(newAllocationSize, __FILE__, __LINE__);
2737
2738 }
2739
2740#else
2741
2742 if (::get_task_object_debug().has_character())
2743 {
2744
2745 this->m_begin = MEMORY::allocate(newAllocationSize, "thread://" + ::get_task_object_name() + ", " + ::get_task_object_debug() + ", " + string(__FILE__), __LINE__);
2746
2747 }
2748 else
2749 {
2750
2751 this->m_begin = MEMORY::allocate(newAllocationSize, "thread://" + ::get_task_object_name() + ", " + string(__FILE__), __LINE__);
2752
2753 }
2754
2755#endif
2756
2757 }
2758 else
2759 {
2760
2761 this->m_begin = MEMORY::allocate(newAllocationSize, __FILE__, __LINE__);
2762
2763 }
2764
2765#else
2766
2767 this->m_begin = MEMORY::allocate(newAllocationSize, &newAllocationSize);
2768
2769#endif
2770
2771 this->m_end = this->m_begin;
2772
2773 }
2774 else
2775 {
2776
2777 auto countOld = this->size();
2778
2779 auto countAddUp = m_countAddUp;
2780
2781 if(countAddUp <= 0)
2782 {
2783
2784 countAddUp = this->size();
2785
2786 constrain(countAddUp, 4, 1024);
2787
2788 }
2789
2790 if(newAllocationSize < m_countAllocation + countAddUp)
2791 {
2792
2793 newAllocationSize = m_countAllocation + countAddUp;
2794
2795 }
2796
2797 if(newAllocationSize > UPTR_MAXIMUM / sizeof(TYPE))
2798 {
2799
2800 throw_exception(error_no_memory);
2801
2802 }
2803
2804#if MEMDLEAK || defined(__MCRTDBG)
2805
2806 TYPE* pNewData = nullptr;
2807
2808 if(::get_task() != nullptr)
2809 {
2810
2811#if defined(__MCRTDBG)
2812
2813 if(::get_task()->m_strFile.has_character())
2814 {
2815
2816 pNewData = MEMORY::allocate(newAllocationSize, ::get_task()->m_strFile,::get_task()->m_iLine);
2817
2818 }
2819 else
2820 {
2821
2822 pNewData = MEMORY::allocate(newAllocationSize, __FILE__, __LINE__);
2823
2824 }
2825
2826#else
2827
2828 if (::get_task_object_debug().has_character())
2829 {
2830
2831 pNewData = MEMORY::allocate(newAllocationSize, "thread://" + ::get_task_object_name() + ", " + ::get_task_object_debug() + ", " + string(__FILE__), __LINE__);
2832
2833 }
2834 else
2835 {
2836
2837 pNewData = MEMORY::allocate(newAllocationSize, "thread://" + ::get_task_object_name() + ", " + string(__FILE__), __LINE__);
2838
2839 }
2840
2841#endif
2842
2843 }
2844 else
2845 {
2846
2847 pNewData = MEMORY::allocate(newAllocationSize, __FILE__, __LINE__);
2848
2849 }
2850
2851#else
2852
2853 TYPE * pNewData = MEMORY::allocate(newAllocationSize, &newAllocationSize);
2854
2855#endif
2856
2857 // copy ___new data from old
2858 ::safe_memory_copy2(pNewData, (size_t)newAllocationSize, this->m_begin, (size_t) this->size());
2859
2860 // get rid of old stuff (note: no destructors called)
2861 //if(!(this->m_erange & e_range_array_allocate))
2862 {
2863 MEMORY::free(this->m_begin);
2864 }
2865 //else
2866 //{
2867 // this->m_erange = (::enum_range) (this->m_erange & ~e_range_array_allocate);
2868 //}
2869
2870 this->m_begin = pNewData;
2871
2872 this->m_end = this->m_begin + countOld;
2873
2874 }
2875
2876 m_countAllocation = newAllocationSize;
2877
2878}
2879
2880
2881
2882
2883//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
2884//::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::allocate(::collection::count nNewSize, bShrink, const TYPE * ptype)
2885//{
2886//
2887// ::collection::count countOld = get_count();
2888//
2889// auto countOldRawAllocate = raw_allocate_at(nNewSize, bShrink);
2890//
2891// if(countOldRawAllocate == countOld)
2892// {
2893//
2894// return countOld;
2895//
2896// }
2897//
2898// if(nNewSize == 0)
2899// {
2900//
2901// // shrink to nothing
2902// if(this->m_begin != nullptr)
2903// {
2904//
2905// TYPED::destruct_count(this->m_begin, this->size() REFERENCING_DEBUGGING_COMMA_THIS);
2906//
2907// MEMORY::free(this->m_begin);
2908//
2909// this->m_begin = nullptr;
2910//
2911// }
2912//
2913// this->m_end = nullptr;
2914//
2915// m_countAllocation = 0;
2916//
2917// }
2918// else if(this->m_begin == nullptr)
2919// {
2920//
2921// // create buffer big enough to hold number of requested elements or
2922// // m_countAddUp elements, whichever is larger.
2923//#ifdef SIZE_T_MAX
2924// if(::comparison::gt(nNewSize, SIZE_T_MAX / sizeof(TYPE)))
2925// throw_exception(error_no_memory);
2926// ASSERT(::comparison::lt(nNewSize, SIZE_T_MAX / sizeof(TYPE))); // no overflow
2927//#endif
2928//
2929// auto nAllocSize = maximum(nNewSize, m_countAddUp);
2930//
2931//#if MEMDLEAK || defined(__MCRTDBG)
2932//
2933// if(::get_task() != nullptr)
2934// {
2935//
2936//#if defined(__MCRTDBG)
2937//
2938// if(::get_task()->m_strFile.has_character())
2939// {
2940//
2941// this->m_begin = MEMORY::allocate(nAllocSize, ::get_task()->m_strFile, ::get_task()->m_iLine);
2942//
2943// }
2944// else
2945// {
2946//
2947// this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
2948//
2949// }
2950//
2951//#else
2952//
2953// if (::get_task_object_debug().has_character())
2954// {
2955//
2956// this->m_begin = MEMORY::allocate(nAllocSize, "thread://" + ::get_task_object_name() + ", " + ::get_task_object_debug() + ", " + string(__FILE__), __LINE__;
2957//
2958// }
2959// else
2960// {
2961//
2962// this->m_begin = MEMORY::allocate(nAllocSize, "thread://" + ::get_task_object_name() + ", " + string(__FILE__), __LINE__;
2963//
2964// }
2965//
2966//#endif
2967//
2968// }
2969// else
2970// {
2971//
2972// this->m_begin = MEMORY::allocate(nAllocSize, __FILE__, __LINE__);
2973//
2974// }
2975//
2976//#else
2977//
2978// this->m_begin = MEMORY::allocate(nAllocSize);
2979//
2980//#endif
2981//
2982// if (::is_null(ptype))
2983// {
2984//
2985// TYPED::construct_count(this->m_begin, nNewSize);
2986//
2987// }
2988// else
2989// {
2990//
2991// TYPED::copy_construct_count(this->m_begin, nNewSize, *ptype);
2992//
2993// }
2994//
2995// this->m_end = this->m_begin + nNewSize;
2996//
2997// m_countAllocation = nAllocSize;
2998//
2999// }
3000// else if(nNewSize <= m_countAllocation)
3001// {
3002//
3003// if(nNewSize > this->size())
3004// {
3005//
3006// if (::is_null(ptype))
3007// {
3008//
3009// TYPED::construct_count(this->end(), nNewSize - this->size());
3010//
3011// }
3012// else
3013// {
3014//
3015// TYPED::copy_construct_count(this->end(), nNewSize - this->size(), *ptype);
3016//
3017// }
3018//
3019// }
3020// else if(this->size() > nNewSize)
3021// {
3022//
3023// TYPED::destruct_count(this->m_begin + nNewSize,this->size() - nNewSize REFERENCING_DEBUGGING_COMMA_THIS);
3024//
3025// }
3026//
3027// this->m_end = this->m_begin + nNewSize;
3028//
3029// }
3030// else
3031// {
3032//
3033// // otherwise, grow aaa_base_array
3034// nGrowBy = m_countAddUp;
3035//
3036// if(nGrowBy == 0)
3037// {
3038//
3039// // heuristically determine growth when nGrowBy == 0
3040// // (this avoids heap fragmentation in many situations)
3041// nGrowBy = this->size();
3042// nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
3043//
3044// }
3045//
3046// ::collection::count nNewMax;
3047//
3048// if(nNewSize < m_countAllocation+ nGrowBy)
3049// {
3050//
3051// nNewMax = m_countAllocation+ nGrowBy; // granularity
3052//
3053// }
3054// else
3055// {
3056//
3057// nNewMax = nNewSize; // no slush
3058//
3059// }
3060//
3061// ASSERT(nNewMax >= m_countAllocation); // no wrap around
3062//
3063// if(nNewMax < m_countAllocation)
3064// {
3065//
3066// throw_exception(error_bad_argument);
3067//
3068// }
3069//
3070//#ifdef SIZE_T_MAX
3071//
3072// ASSERT(::comparison::lt(nNewMax, SIZE_T_MAX / sizeof(TYPE))); // no overflow
3073//
3074//#endif
3075//
3076//#if MEMDLEAK || defined(__MCRTDBG)
3077//
3078// TYPE* pNewData = nullptr;
3079//
3080// if(::get_task() != nullptr)
3081// {
3082//
3083//#if defined(__MCRTDBG)
3084//
3085// if(::get_task()->m_strFile.has_character())
3086// {
3087//
3088// pNewData = MEMORY::allocate(nNewMax, ::get_task()->m_strFile,::get_task()->m_iLine);
3089//
3090// }
3091// else
3092// {
3093//
3094// pNewData = MEMORY::allocate(nNewMax, __FILE__, __LINE__);
3095//
3096// }
3097//
3098//#else
3099//
3100// if (::get_task_object_debug().has_character())
3101// {
3102//
3103// pNewData = MEMORY::allocate(nNewMax, "thread://" + ::get_task_object_name() + ", " + ::get_task_object_debug() + ", " + string(__FILE__), __LINE__;
3104//
3105// }
3106// else
3107// {
3108//
3109// pNewData = MEMORY::allocate(nNewMax, "thread://" + ::get_task_object_name() + ", " + string(__FILE__), __LINE__;
3110//
3111// }
3112//
3113//#endif
3114//
3115// }
3116// else
3117// {
3118//
3119// pNewData = MEMORY::allocate(nNewMax, __FILE__, __LINE__);
3120//
3121// }
3122//
3123//
3124//#else
3125//
3126// TYPE* pNewData = MEMORY::allocate(nNewMax);
3127//
3128//#endif
3129//
3130// // copy ___new data from old
3131// ::safe_memory_copy(pNewData,(size_t)nNewMax * sizeof(TYPE),this->m_begin,(size_t)this->size() * sizeof(TYPE));
3132//
3133// // construct remaining elements
3134// ASSERT(nNewSize > this->size());
3135//
3136// if (nNewSize > this->size())
3137// {
3138//
3139// if (::is_null(ptype))
3140// {
3141//
3142// TYPED::construct_count(pNewData + this->size(), nNewSize - this->size());
3143//
3144// }
3145// else
3146// {
3147//
3148// TYPED::copy_construct_count(pNewData + this->size(), nNewSize - this->size(), *ptype);
3149//
3150// }
3151//
3152// }
3153//
3154// // get rid of old stuff (note: no destructors called)
3155// MEMORY::free(this->m_begin);
3156//
3157// this->m_begin = pNewData;
3158//
3159// this->m_end = this->m_begin + nNewSize;
3160//
3161// m_countAllocation = nNewMax;
3162//
3163// }
3164//
3165// return countOld;
3166//
3167//}
3168
3169
3170//
3171// template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3172// void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::on_after_read()
3173// {
3174//
3175//
3176// }
3177//
3178
3179
3180
3181
3182template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3183inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::set_at_grow(::collection::index nIndex, ARG_TYPE newElement)
3184{
3185
3186 ASSERT(nIndex >= 0);
3187
3188 if (nIndex >= this->size())
3189 {
3190
3191 this->set_size(nIndex + 1);
3192
3193 }
3194
3195 this->m_begin[nIndex] = newElement;
3196
3197}
3198
3199
3200template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3201inline TYPE & base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::element_at_grow(::collection::index nIndex)
3202{
3203
3204 ASSERT(nIndex >= 0);
3205
3206 if (nIndex >= this->size())
3207 {
3208
3209 this->set_size(nIndex + 1);
3210
3211 }
3212
3213 return this->m_begin[nIndex];
3214
3215}
3216
3217
3218template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3219inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::set_each(ARG_TYPE element, ::collection::index first, ::collection::count in_count_out_last)
3220{
3221
3222 this->prepare_first_in_count_last_out(first, in_count_out_last);
3223
3224 for(::collection::index i = first; i <= in_count_out_last; i++)
3225 {
3226
3227 this->m_begin[i] = element;
3228
3229 }
3230
3231}
3232
3233
3234template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3235template < typename ITERATOR2 >
3236inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::erase(const ITERATOR2 & begin, const ITERATOR2 & last)
3237{
3238
3239 auto start = this->index_of(begin);
3240
3241 auto end = this->index_of(last);
3242
3243 if(start < 0 || (end <= start && end >= 0))
3244 {
3245
3246 return;
3247
3248 }
3249
3250 auto count = end > start ? end - start : -1;
3251
3252 erase_at(start, count);
3253
3254}
3255
3256
3257
3258
3259//
3260// see collection_array_decl.h for declaration
3261//
3262// raw_array is an array that does not call constructors or destructor in elements
3263// array is an array that call only copy constructor and destructor in elements
3264// array is an array that call default constructors, copy constructs and destructors in elements
3265
3266template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3267inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_size() const
3268{
3269 return (::collection::count) this->size();
3270}
3271
3272
3273template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3274inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_count() const
3275{
3276 return (::collection::count) this->size();
3277}
3278
3279
3280template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3281inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_length() const
3282{
3283 return (::collection::count) this->size();
3284}
3285
3286
3287template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3288inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_size_in_bytes() const
3289{
3290 return (::collection::count)this->size() * sizeof(TYPE);
3291}
3292
3293
3294template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3295inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_byte_count() const
3296{
3297 return (::collection::count) (this->size() * sizeof(TYPE));
3298}
3299
3300
3301//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3302//inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::size() const
3303//{
3304// return this->get_size();
3305//}
3306//
3307
3308template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3309inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::count() const
3310{
3311 return this->get_count();
3312}
3313
3314template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3315inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::length() const
3316{
3317 return this->get_length();
3318}
3319
3320//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3321//inline bool base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::is_empty(::collection::count countMinimum) const
3322//{
3323// return this->size() < countMinimum;
3324//}
3325
3326
3327//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3328//inline bool base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::empty(::collection::count countMinimum) const
3329//{
3330// return is_empty(countMinimum);
3331//}
3332
3333//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3334//inline bool base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::isEmpty(::collection::count countMinimum) const
3335//{
3336// return empty(countMinimum);
3337//}
3338
3339//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3340//inline bool base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::has_elements(::collection::count countMinimum) const
3341//{
3342// return this->size() >= countMinimum;
3343//}
3344
3345
3346template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3347inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::erase_all()
3348{
3349
3350 return allocate(0, false, false);
3351
3352}
3353
3354
3355template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3356inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::set_size(::collection::index nNewSize)
3357{
3358
3359 return allocate(nNewSize, false, false);
3360
3361}
3362
3363
3364template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3365inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::clear()
3366{
3367
3368 erase_all();
3369
3370}
3371
3372
3373template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3374inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::erase_first(::collection::count c)
3375{
3376
3377 ASSERT(this->size() >= c);
3378
3379 erase_at(0, c);
3380
3381}
3382
3383
3384template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3385inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::erase_last(::collection::count c)
3386{
3387
3388 ASSERT(this->size() >= c);
3389
3390 this->erase_at(this->get_upper_bound(-c), c);
3391
3392}
3393
3394
3395template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3396inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::zero(::collection::index iStart,::collection::count c)
3397{
3398 if(c < 0)
3399 {
3400 c = get_size() - iStart;
3401 }
3402 ::zero(&this->m_begin[iStart],c * sizeof(TYPE));
3403}
3404
3405
3406//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3407//inline const TYPE& base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::element_at(::collection::index nIndex) const
3408//{
3409//
3410// ASSERT(nIndex >= 0 && nIndex < this->size());
3411//
3412// return this->m_begin[nIndex];
3413//
3414//}
3415//
3416//
3417//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3418//inline TYPE& base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::element_at(::collection::index nIndex)
3419//{
3420//
3421// ASSERT(nIndex >= 0 && nIndex < this->size());
3422//
3423// return this->m_begin[nIndex];
3424//
3425//}
3426
3427//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3428//inline const TYPE& array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::first(::collection::index nIndex) const
3429//{
3430// return this->element_at(nIndex);
3431//}
3432//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3433//inline TYPE& array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::first(::collection::index nIndex)
3434//{
3435// return this->element_at(nIndex);
3436//}
3437//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3438//inline const TYPE& array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::last(::collection::index i) const
3439//{
3440// return this->element_at(this->get_upper_bound(i);
3441//}
3442//
3443//
3444//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3445//inline TYPE& array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::last(::collection::index i)
3446//{
3447// return this->element_at(this->get_upper_bound(i);
3448//}
3449
3450
3451
3452
3453//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3454//inline const TYPE* array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_data() const
3455//{
3456// return (const TYPE*)this->m_begin;
3457//}
3458//
3459//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3460//inline TYPE* array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::get_data()
3461//{
3462// return (TYPE*)this->m_begin;
3463//}
3464
3465//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3466//inline const TYPE& base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::operator[](::collection::index i) const
3467//{
3468//
3469// return this->m_begin[i];
3470//
3471//}
3472
3473
3474//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3475//inline TYPE& base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::operator[](::collection::index i)
3476//{
3477//
3478// return this->m_begin[i];
3479//
3480//}
3481
3482
3483template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3484inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::__swap(::collection::index index1, ::collection::index index2)
3485{
3486
3487 ::__swap(this->m_begin[index1], this->m_begin[index2]);
3488
3489}
3490
3491
3492template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3493inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::__swap(iterator it1, iterator it2)
3494{
3495
3496 TYPE t = *it1;
3497
3498 *it1 = *it2;
3499
3500 *it2 = t;
3501
3502}
3503
3504
3505
3506template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3507inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::__swap(const_iterator it1, const_iterator it2)
3508{
3509
3510 auto t = (TYPE) *it1;
3511
3512 ((TYPE &)*it1) = (const TYPE &) *it2;
3513
3514 ((TYPE &)*it2) = t;
3515
3516}
3517
3518
3519
3520template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3521void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::set_all(const TYPE & t)
3522{
3523
3524 for (::collection::index i = 0; i < get_count(); i++)
3525 {
3526
3527 this->m_begin[i] = t;
3528
3529 }
3530
3531}
3532
3533
3534//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3535//template < typename VAR >
3536//inline base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > & base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::operator = (const payload_type < VAR > & a)
3537//{
3538//
3539// ::collection::count c = a.this_var()->array_get_count();
3540//
3541// for(::collection::index i = 0; i < c; i++)
3542// {
3543//
3544// add((ARG_TYPE)(payload_cast)a.this_var()->at(i));
3545//
3546// }
3547//
3548// return *this;
3549//
3550//}
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3561inline TYPE base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::pop(::collection::index n)
3562{
3563
3564 ::collection::index i = this->get_upper_bound(n);
3565
3566 TYPE t = this->element_at(i);
3567
3568 this->erase_at(i);
3569
3570 return t;
3571
3572}
3573
3574template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3575inline TYPE base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::pop_first(::collection::index i)
3576{
3577
3578 auto t = ::transfer(this->first(i));
3579
3580 this->erase_at(i);
3581
3582 return t;
3583
3584}
3585
3586
3587template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3588inline void base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::pop_last(::collection::index n)
3589{
3590
3591 erase_at(this->get_upper_bound(n));
3592
3593}
3594
3595
3596template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3597inline ::collection::index base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::push(ARG_TYPE newElement)
3598{
3599
3600 return index_of(&insert_at(this->size(), newElement));
3601
3602}
3603
3604
3605template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3606inline TYPE& base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::add_item(ARG_TYPE newElement)
3607{
3608
3609 auto nIndex = this->size();
3610
3611 this->allocate(nIndex + 1, false, false, newElement);
3612
3613 return this->element_at(nIndex);
3614
3615}
3616
3617
3618template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3619TYPE& base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::add_new()
3620{
3621
3622 auto nIndex = this->size();
3623
3624 this->allocate(nIndex + 1, false, false);
3625
3626 return this->last();
3627
3628}
3629
3630
3631//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3632//inline TYPE & base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::add_item(ARG_TYPE newElement)
3633//{
3634//
3635// return insert_at(this->size(), newElement);
3636//
3637//}
3638
3639
3640template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3641inline TYPE base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::takeAt(::collection::index i)
3642{
3643
3644 TYPE t = this->element_at(i);
3645
3646 this->erase_at(i);
3647
3648 return t;
3649
3650}
3651
3652
3653template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3654inline TYPE base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::takeFirst(::collection::index i)
3655{
3656
3657 TYPE t = this->element_at(i);
3658
3659 this->erase_at(i);
3660
3661 return t;
3662
3663}
3664
3665
3666template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3667inline TYPE base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::takeLast(::collection::index n)
3668{
3669
3670 ::collection::index i = this->get_upper_bound(n);
3671
3672 TYPE t = this->element_at(i);
3673
3674 this->erase_at(i);
3675
3676 return t;
3677
3678}
3679
3680
3681//template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3682//base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(set_size_t, ::collection::count c) :
3683// base_array()
3684//{
3685//
3686// set_size(c);
3687//
3688//}
3689
3690
3691template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3692template < typename OTHER_TYPE >
3693base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer >::base_array(::collection::count c, const OTHER_TYPE * p)
3694 requires (::std::is_convertible_v < OTHER_TYPE, CONTAINER_ITEM_TYPE >) :
3695 base_array()
3696{
3697
3698 set_size(c);
3699
3700 for (::collection::index i = 0; i < c; i++)
3701 {
3702
3703 this->element_at(i) = p[i];
3704
3705 }
3706
3707}
3708
3709
3710
3711
3712
3713template < typename TYPE, typename ARG_TYPE, typename TYPED, typename MEMORY, ::enum_type t_etypeContainer >
3714inline ::collection::count base_array < TYPE, ARG_TYPE, TYPED, MEMORY, t_etypeContainer > ::erase(const TYPE * begin, const TYPE * last)
3715{
3716
3717 auto iStart = index_of(begin);
3718
3719 auto iEnd = index_of(last);
3720
3721 // iEnd exclusive
3722 return erase_at(iStart, iEnd - iStart);
3723
3724}
3725
3726//template < typename TYPE1, typename TYPE2 >
3727//concept is_same_family = ::std::is_base_of<TYPE1, TYPE2> || ::std::is_base_of<TYPE2, TYPE1>;
3729
3730
3731
3732//template < typename ARRAY_BASE, ::i32 t_preallocated_array_size = 5 >
3733//class preallocated_array_base :
3734// public ARRAY_BASE
3735//{
3736//public:
3737//
3738//
3739// using BASE_ARRAY = ARRAY_BASE;
3740//
3741// using CONTAINER_ITEM_TYPE = ARRAY_BASE::CONTAINER_ITEM_TYPE;
3742//
3743//
3744// CONTAINER_ITEM_TYPE m_elementaPreallocated[t_preallocated_array_size];
3745//
3746//
3747// using BASE_ARRAY::operator =;
3748//
3749// preallocated_array_base()
3750// {
3751//
3752// this->m_erange = (::enum_range)(this->m_erange | e_range_array_allocate);
3753// this->m_begin = m_elementaPreallocated;
3754// this->m_end = m_elementaPreallocated;
3755// this->m_countAllocation = t_preallocated_array_size;
3756//
3757// }
3758//
3759//
3760//};
Definition array_range.h:15
Definition base_array.h:112
::collection::count allocate(::collection::count nNewSize, bool bShrink, bool bRaw, P &p)
if bRaw is true does not call default constructors on ___new elements
Definition base_array.h:972
::collection::index erase_at(::collection::index nIndex, ::collection::count nCount=1)
Definition aaa__array_base_impl.h:62
Definition item.h:93
Definition list.h:33
Definition rear_iterator.h:9
Definition _initial_concepts.h:1023
Definition _forward_declaration.h:1308
Definition base_array.h:3728
Definition std_iterator.h:49
Definition base_array.h:100