acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
comparable_eq_array.h
1#pragma once
2
3
4#include "acme/prototype/comparison/equals.h"
5
6
7template < class TYPE, class ARG_TYPE, class ARRAY_TYPE >
8class comparable_eq_array_base:
9 //public comparable_eq_range < ARRAY_TYPE >
10 public ARRAY_TYPE
11{
12public:
13
14
15 //using BASE_RANGE = comparable_eq_range < ARRAY_TYPE >;
16 using BASE_ARRAY = ARRAY_TYPE;
17 using RAW_BASE_ARRAY = typename BASE_ARRAY::RAW_BASE_ARRAY;
18
19 using BASE_RANGE = typename BASE_ARRAY::BASE_RAW_RANGE;
20
21 using CONST_RAW_RANGE = typename BASE_ARRAY::CONST_RAW_RANGE;
22
23 using iterator = typename ARRAY_TYPE::iterator;
24 using const_iterator = typename ARRAY_TYPE::const_iterator;
25
26 using this_iterator = typename BASE_ARRAY::this_iterator;
27
28
29
30 using BASE_ARRAY::BASE_ARRAY;
31 using BASE_ARRAY::operator =;
32 using BASE_ARRAY::operator +=;
33
34 comparable_eq_array_base(const RAW_BASE_ARRAY& a) : BASE_ARRAY(a) {}
35
36 // comparable_eq_array_base(no_initialize_t):BASE_RANGE(no_initialize_t{}){}
37 // comparable_eq_array_base(nullptr_t):BASE_RANGE(nullptr){}
38 // comparable_eq_array_base():BASE_RANGE(){}
39 // comparable_eq_array_base(::std::initializer_list < TYPE > initializer_list) { this->add_initializer_list(initializer_list); }
40 // comparable_eq_array_base(const comparable_eq_array_base & array) : BASE_RANGE(array) {}
41 // comparable_eq_array_base(comparable_eq_array_base && array) noexcept : BASE_RANGE(::transfer(array)) { }
42 // comparable_eq_array_base(::range < const_iterator > constrange) : BASE_RANGE(constrange) {}
43 // template < prototype_integral INTEGRAL >
44 // comparable_eq_array_base(const_iterator begin, INTEGRAL count) : BASE_RANGE(begin, count) {}
45 // comparable_eq_array_base(const_iterator begin, const_iterator end) : BASE_RANGE(begin, end) {}
46 // comparable_eq_array_base(const_iterator begin) : BASE_RANGE(begin, find_first_null_character(begin)) {}
47
48
49 ::collection::index find_first(ARG_TYPE t) const;
50 ::collection::index find_first(ARG_TYPE t, ::collection::index find, ::collection::index last = -1) const;
51 ::collection::index find_last(ARG_TYPE t) const;
52 ::collection::index find_last_not(ARG_TYPE t) const;
53 ::collection::count get_count() const;
54 ::collection::count get_count(ARG_TYPE t, ::collection::index start = 0, ::collection::index last = -1, ::collection::count countMax = -1) const;
55 //bool has(ARG_TYPE t) const { return contains(t); }
56 bool contains(ARG_TYPE t) const;
57 bool has(ARG_TYPE t) const { return contains(t); }
58 bool contains(ARG_TYPE t, ::collection::index start, ::collection::index last = -1, ::collection::count countMin = 1, ::collection::count countMax = -1) const;
59 bool contains(comparable_eq_array_base & a, ::collection::count cMinCount = -1) const
60 {
61 if(cMinCount < 0)
62 {
63 cMinCount += a.get_count() + 1;
64 }
65 for(::collection::index i = 0; cMinCount > 0 && i < a.get_count(); i++)
66 {
67 if(!this->contains(a[i]))
68 return false;
69 cMinCount--;
70 }
71 return true;
72 }
73
74
75 using BASE_ARRAY::erase_first;
76 using BASE_ARRAY::erase_last;
77 ::collection::index erase_last(ARG_TYPE t);
78 ::collection::index erase_first(ARG_TYPE t);
79 ::collection::index erase_first(ARG_TYPE t, ::collection::index find, ::collection::index last = -1);
80 ::collection::count erase(ARG_TYPE t);
81 ::collection::count erase(ARG_TYPE t, ::collection::index find, ::collection::index last = -1, ::collection::count countMin = 0, ::collection::count countMax = -1);
82 template < prototype_container CONTAINER>
83 ::collection::count erase(const CONTAINER & container);
84 ::collection::count erase(iterator start, iterator end)
85 {
86
87 ::collection::count c = 0;
88
89 for(auto p = start; p != end; p++)
90 {
91
92 c+=this->erase(*p);
93
94 }
95
96 return c;
97
98 }
99
100
101 bool add_unique(ARG_TYPE t);
102 ::collection::count append_unique(const ARRAY_TYPE & a);
103 TYPE & insert_unique(ARG_TYPE t);
104
105
106 bool insert_unique_at(::collection::index i, ARG_TYPE t);
107
108 ::collection::count add_erase(bool bAdd, ARG_TYPE t);
109
110
111 // set
112 void merge(const comparable_eq_array_base & a);
113 void intersect(const comparable_eq_array_base & a);
114
115 comparable_eq_array_base & operator -= (const TYPE & t)
116 {
117
118 this->erase(t);
119
120 return *this;
121
122 }
123
124
125 template < prototype_range RANGE >
126 comparable_eq_array_base & operator -= (const RANGE & range)
127 {
128
129 for (auto & item : range)
130 {
131
132 this->erase(item);
133
134 }
135
136 return *this;
137
138 }
139
140
141 comparable_eq_array_base & operator -= (const std::initializer_list < TYPE > & initializer_list)
142 {
143
144 for (auto & item : initializer_list)
145 {
146
147 this->erase(item);
148
149 }
150
151 return *this;
152
153 }
154
155
156 // set operators
157 //comparable_eq_array_base & operator -= (const TYPE & t);
158 //comparable_eq_array_base & operator &= (const comparable_eq_array_base & a);
159 //comparable_eq_array_base & operator -= (const comparable_eq_array_base & a);
160 //comparable_eq_array_base& operator |= (const comparable_eq_array_base & a);
161
162 //comparable_eq_array_base operator -(const comparable_eq_array_base & a) const;
163
164
165 // using ARRAY_TYPE::operator =;
166 // comparable_eq_array_base & operator = (const comparable_eq_array_base & array)
167 // {
168 //
169 // BASE_ARRAY::operator =(array);
170 //
171 // return *this;
172 //
173 // }
174 //
175 //
176 // comparable_eq_array_base & operator = (comparable_eq_array_base && array)
177 // {
178 //
179 // BASE_ARRAY::operator = (::transfer(array));
180 //
181 // return *this;
182 //
183 // }
184 //
185
186 comparable_eq_array_base & transfer(comparable_eq_array_base && array)
187 {
188
189 BASE_ARRAY::transfer(::transfer(array));
190
191 return *this;
192
193 }
194
195
196
197
198 TYPE get_next(ARG_TYPE t)
199 {
200
201 auto iFind = this->find_first(t);
202
203 if (this->is_empty())
204 {
205
206 return TYPE();
207
208 }
209
210 if (iFind < 0)
211 {
212
213 return this->first();
214
215 }
216
217 return this->operator % (iFind + 1);
218
219 }
220
221 using BASE_ARRAY::equals;
222
223 bool equals(CONST_RAW_RANGE a) const
224 {
225
226 return BASE_ARRAY::equals(a, ::comparison::comparison < TYPE >());
227
228 }
229
230
231 bool operator ==(CONST_RAW_RANGE a) const
232 {
233
234 return this->equals(a);
235
236 }
237
238
239};
240
241
242
243
244//template < class TYPE, class ARG_TYPE, class ARRAY_TYPE>
245//comparable_eq_array_base< TYPE, ARG_TYPE, ARRAY_TYPE>::
246//comparable_eq_array_base()
247//{
248//}
249//template < class TYPE, class ARG_TYPE, class ARRAY_TYPE>
250//comparable_eq_array_base< TYPE, ARG_TYPE, ARRAY_TYPE>::
251//comparable_eq_array_base(const comparable_eq_array_base< TYPE, ARG_TYPE, ARRAY_TYPE> & a)
252//{
253// this->ARRAY_TYPE::operator = (a);
254//}
255//
256//
257//template < class TYPE,class ARG_TYPE,class ARRAY_TYPE>
258//comparable_eq_array_base< TYPE,ARG_TYPE,ARRAY_TYPE>::
259//comparable_eq_array_base( comparable_eq_array_base< TYPE,ARG_TYPE,ARRAY_TYPE> && a)
260//{
261//
262// transfer(::transfer(a));
263//
264//}
265
266template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
267::collection::index comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
268find_first(ARG_TYPE t) const
269{
270 ::collection::index find = 0;
271 ::collection::index c = this->get_size();
272 for(; find < c; find++)
273 {
274 if(EqualElements(this->element_at(find),t))
275 return find;
276 }
277 return -1;
278}
279
280template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
281::collection::index comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
282find_last(ARG_TYPE t) const
283{
284 ::collection::index find = this->get_upper_bound();
285 for(; find >= 0; find--)
286 {
287 if(EqualElements(this->element_at(find),t))
288 return find;
289 }
290 return -1;
291}
292
293template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
294::collection::index comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
295find_last_not(ARG_TYPE t) const
296{
297 ::collection::index find = this->get_upper_bound();
298 for (; find >= 0; find--)
299 {
300 if (!EqualElements(this->element_at(find), t))
301 return find;
302 }
303 return -1;
304}
305
306template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
307::collection::index comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
308find_first(ARG_TYPE t, ::collection::index find, ::collection::index last) const
309{
310 if(find < 0)
311 find += this->get_count();
312 if(last < 0)
313 last += this->get_count();
314 for(; find <= last; find++)
315 {
316 if(EqualElements(this->element_at(find), t))
317 return find;
318 }
319 return -1;
320}
321
322template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
323inline ::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
324get_count() const
325{
326
327 return ARRAY_TYPE::get_count();
328
329}
330
331
332template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
333::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
334get_count(ARG_TYPE t, ::collection::index find, ::collection::index last, ::collection::count countMax) const
335{
336
337 ::collection::count count = 0;
338
339 while((countMax < 0 || count <= countMax) && (find = find_first(t, find, last)) >= 0)
340 {
341
342 count++;
343
344 find++;
345
346 }
347
348 return count;
349
350}
351
352
353template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
354bool comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
355contains(ARG_TYPE t) const
356{
357
358 return find_first(t) >= 0;
359
360}
361
362
363template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
364bool comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
365contains(ARG_TYPE t, ::collection::index find, ::collection::index last, ::collection::count countMin, ::collection::count countMax) const
366{
367
368 ::collection::count count = 0;
369
370 while((count < countMin || (countMax >= 0 && count <= countMax)) && (find = find_first(t, find, last)) >= 0)
371 {
372
373 count++;
374
375 }
376
377 return count >= countMin && ::conditional(countMax >= 0, count <= countMax);
378
379}
380
381
382template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
383bool comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::add_unique(ARG_TYPE t)
384{
385 if(contains(t))
386 return false;
387 this->add(t);
388 return true;
389}
390
391
392template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
393TYPE & comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::insert_unique(ARG_TYPE t)
394{
395
396 auto iIndex = this->find_first(t);
397
398 if (iIndex < 0)
399 {
400
401 iIndex = this->add(t);
402
403 }
404
405 return this->element_at(iIndex);
406
407}
408
409
410template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
411::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::add_erase(bool bAdd, ARG_TYPE t)
412{
413 if (bAdd)
414 return this->add_unique(t) ? 1 : 0;
415 else
416 return this->erase(t);
417}
418
419template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
420::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::append_unique(const ARRAY_TYPE & a)
421{
422
423 ::collection::count ca = 0;
424
425 ::collection::count cAdd = a.get_count();
426
427 for(::i32 i = 0; i < cAdd; i++)
428 {
429 if(add_unique(a[i]))
430 ca++;
431 }
432
433 return ca;
434
435}
436
437
438template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
439void comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
440intersect(const comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE > & a)
441{
442 for(::collection::index i = 0; i < this->get_size();)
443 {
444 if(a.contains(this->element_at(i)))
445 {
446 i++;
447 }
448 else
449 {
450 this->erase_at(i);
451 }
452 }
453}
454
455
456template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
457void comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
458merge(const comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE > & a)
459{
460
461 for(::collection::index i = 0; i < a.get_size(); i++)
462 {
463
464 if(!contains(a.element_at(i)))
465 {
466
467 this->add(a.element_at(i));
468
469 }
470
471 }
472
473}
474
475
476template < prototype_container CONTAINER, prototype_container CONTAINER2 >
477inline CONTAINER& operator |= (CONTAINER& container, const CONTAINER& container2)
478{
479
480 container.merge(container);
481
482 return container;
483
484}
485
486
487template < prototype_container CONTAINER, prototype_container CONTAINER2 >
488inline CONTAINER& operator &= (CONTAINER& container, const CONTAINER& container2)
489{
490
491 container.intersect(container2);
492
493 return container;
494
495}
496
497
498// template < prototype_container CONTAINER >
499// inline CONTAINER & operator -= (CONTAINER & container, const typename CONTAINER::CONTAINER_ITEM_TYPE& t)
500// {
501//
502// container.erase(t);
503//
504// return container;
505//
506// }
507//
508//
509// template < prototype_container CONTAINER, prototype_container CONTAINER2 >
510// inline CONTAINER& operator -= (CONTAINER& container, const CONTAINER2& container2)
511// {
512//
513// container.erase_container(container2);
514//
515// return container;
516//
517// }
518
519
520
521template < prototype_container CONTAINER1, prototype_container CONTAINER2 >
522CONTAINER1 operator - (const CONTAINER1 & container1, const CONTAINER2 & container2)
523{
524
525 auto container = container1;
526
527 container.erase_container(container2);
528
529 return container;
530
531}
532
533//template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
534//inline bool comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
535//operator == (const comparable_eq_array_base & a) const
536//{
537//
538// if(this == &a)
539// {
540//
541//
542//
543// }
544//
545// if(this->size() != a.size())
546// {
547//
548// return false;
549//
550// }
551//
552//
553//
554//}
555
556
557
558template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
559::collection::index comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::erase_last(ARG_TYPE t)
560{
561
562 ::collection::index find;
563
564 if((find = find_last(t)) >= 0)
565 {
566
567 this->erase_at(find);
568
569 }
570
571 return find;
572
573}
574
575
576template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
577::collection::index comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
578erase_first(ARG_TYPE t)
579{
580 ::collection::index find;
581 if((find = find_first(t)) >= 0)
582 {
583 this->erase_at(find);
584 }
585 return find;
586}
587
588
589template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
590::collection::index comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
591erase_first(ARG_TYPE t, ::collection::index find, ::collection::index last)
592{
593 if((find = find_first(t, find, last)) >= 0)
594 {
595 this->erase_at(find);
596 }
597 return find;
598}
599
600
601template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
602::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
603erase(ARG_TYPE t, ::collection::index find, ::collection::index last, ::collection::count countMin, ::collection::count countMax)
604{
605
606 ::collection::count count = 0;
607
608 if(contains(t, find, last, countMin, countMax))
609 {
610
611 while(::conditional(countMax >= 0, count < countMax) && (find = erase_first(t, find, last)) >= 0)
612 {
613
614 count++;
615
616 }
617
618 }
619
620 return count;
621
622}
623
624
625template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
626::collection::count comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
627erase(ARG_TYPE t)
628{
629
630 ::collection::count count = 0;
631
632 while (erase_last(t) >= 0)
633 {
634
635 count++;
636
637 }
638
639 return count;
640
641}
642
643
644//template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
645//::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
646//erase(ARG_TYPE t, ::collection::index find, ::collection::index last, ::collection::count countMin, ::collection::count countMax)
647//{
648// return erase(t, find, last, countMin, countMax);
649//}
650
651
652//template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
653//typename ARRAY_TYPE::iterator comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
654//erase(typename ARRAY_TYPE::iterator it)
655//{
656// return ARRAY_TYPE::erase(it);
657//}
658//
659//template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
660//typename ARRAY_TYPE::iterator comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
661//erase(typename ARRAY_TYPE::iterator first, typename ARRAY_TYPE::iterator last)
662//{
663// return ARRAY_TYPE::erase(first, last);
664//}
665
666template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
667template < prototype_container CONTAINER>
668::collection::index comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
669erase(const CONTAINER & container)
670{
671
672 ::collection::count count = 0;
673
674 if((::quantum *) this == (::quantum *)&container)
675 {
676
677 count = this->get_size();
678
679 this->erase_all();
680
681 }
682 else
683 {
684
685 for(auto & item : container)
686 {
687
688 count += erase(item);
689
690 }
691
692 }
693
694 return count;
695
696}
697
698
699template <class TYPE,class ARG_TYPE, class ARRAY_TYPE >
700bool comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::insert_unique_at(::collection::index i, ARG_TYPE t)
701{
702
703 if (i < 0 || i > this->get_size())
704 {
705
706 throw_exception(error_bad_argument);
707
708 }
709
710 auto iFind = this->find_first(t);
711
712 if (iFind < 0)
713 {
714
715 this->insert_at(i, t);
716
717 return true;
718
719 }
720
721 if (iFind < i)
722 {
723
724 this->erase_at(iFind);
725
726 this->insert_at(i - 1, t);
727
728 }
729 else if (iFind > i)
730 {
731
732 this->erase_at(iFind);
733
734 this->insert_at(i, t);
735
736 }
737
738 return false;
739
740}
Definition item.h:93
Definition quantum.h:22
Definition range.h:223