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