4#include "acme/prototype/comparison/equals.h"
7template <
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE >
8class comparable_eq_array_base:
16 using BASE_ARRAY = ARRAY_TYPE;
17 using RAW_BASE_ARRAY =
typename BASE_ARRAY::RAW_BASE_ARRAY;
19 using BASE_RANGE =
typename BASE_ARRAY::BASE_RAW_RANGE;
21 using CONST_RAW_RANGE =
typename BASE_ARRAY::CONST_RAW_RANGE;
23 using iterator =
typename ARRAY_TYPE::iterator;
24 using const_iterator =
typename ARRAY_TYPE::const_iterator;
26 using this_iterator =
typename BASE_ARRAY::this_iterator;
30 using BASE_ARRAY::BASE_ARRAY;
31 using BASE_ARRAY::operator =;
32 using BASE_ARRAY::operator +=;
34 comparable_eq_array_base(
const RAW_BASE_ARRAY& a) : BASE_ARRAY(a) {}
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;
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
63 cMinCount += a.get_count() + 1;
65 for(::collection::index i = 0; cMinCount > 0 && i < a.get_count(); i++)
67 if(!this->contains(a[i]))
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)
87 ::collection::count c = 0;
89 for(
auto p = start; p != end; p++)
101 bool add_unique(ARG_TYPE t);
102 ::collection::count append_unique(
const ARRAY_TYPE & a);
103 TYPE & insert_unique(ARG_TYPE t);
106 bool insert_unique_at(::collection::index i, ARG_TYPE t);
108 ::collection::count add_erase(
bool bAdd, ARG_TYPE t);
112 void merge(
const comparable_eq_array_base & a);
113 void intersect(
const comparable_eq_array_base & a);
115 comparable_eq_array_base & operator -= (
const TYPE & t)
125 template < prototype_range RANGE >
126 comparable_eq_array_base & operator -= (
const RANGE &
range)
141 comparable_eq_array_base & operator -= (
const std::initializer_list < TYPE > & initializer_list)
144 for (
auto &
item : initializer_list)
186 comparable_eq_array_base & transfer(comparable_eq_array_base && array)
189 BASE_ARRAY::transfer(::transfer(array));
198 TYPE get_next(ARG_TYPE t)
201 auto iFind = this->find_first(t);
203 if (this->is_empty())
213 return this->first();
217 return this->operator % (iFind + 1);
221 using BASE_ARRAY::equals;
223 bool equals(CONST_RAW_RANGE a)
const
226 return BASE_ARRAY::equals(a, ::comparison::comparison < TYPE >());
231 bool operator ==(CONST_RAW_RANGE a)
const
234 return this->equals(a);
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
270 ::collection::index find = 0;
271 ::collection::index c = this->get_size();
272 for(; find < c; find++)
274 if(EqualElements(this->element_at(find),t))
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
284 ::collection::index find = this->get_upper_bound();
285 for(; find >= 0; find--)
287 if(EqualElements(this->element_at(find),t))
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
297 ::collection::index find = this->get_upper_bound();
298 for (; find >= 0; find--)
300 if (!EqualElements(this->element_at(find), t))
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
311 find += this->get_count();
313 last += this->get_count();
314 for(; find <= last; find++)
316 if(EqualElements(this->element_at(find), t))
322template <
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE >
323inline ::collection::count comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::
327 return ARRAY_TYPE::get_count();
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
337 ::collection::count count = 0;
339 while((countMax < 0 || count <= countMax) && (find = find_first(t, find, last)) >= 0)
353template <
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE >
354bool comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
355contains(ARG_TYPE t)
const
358 return find_first(t) >= 0;
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
368 ::collection::count count = 0;
370 while((count < countMin || (countMax >= 0 && count <= countMax)) && (find = find_first(t, find, last)) >= 0)
377 return count >= countMin && ::conditional(countMax >= 0, count <= countMax);
382template <
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE >
383bool comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::add_unique(ARG_TYPE t)
392template <
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE >
393TYPE & comparable_eq_array_base < TYPE, ARG_TYPE, ARRAY_TYPE >::insert_unique(ARG_TYPE t)
396 auto iIndex = this->find_first(t);
401 iIndex = this->add(t);
405 return this->element_at(iIndex);
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)
414 return this->add_unique(t) ? 1 : 0;
416 return this->erase(t);
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)
423 ::collection::count ca = 0;
425 ::collection::count cAdd = a.get_count();
427 for(::i32 i = 0; i < cAdd; i++)
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)
442 for(::collection::index i = 0; i < this->get_size();)
444 if(a.contains(this->element_at(i)))
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)
461 for(::collection::index i = 0; i < a.get_size(); i++)
464 if(!contains(a.element_at(i)))
467 this->add(a.element_at(i));
476template < prototype_container CONTAINER, prototype_container CONTAINER2 >
477inline CONTAINER& operator |= (CONTAINER& container,
const CONTAINER& container2)
480 container.merge(container);
487template < prototype_container CONTAINER, prototype_container CONTAINER2 >
488inline CONTAINER& operator &= (CONTAINER& container,
const CONTAINER& container2)
491 container.intersect(container2);
521template < prototype_container CONTAINER1, prototype_container CONTAINER2 >
522CONTAINER1 operator - (
const CONTAINER1 & container1,
const CONTAINER2 & container2)
525 auto container = container1;
527 container.erase_container(container2);
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)
562 ::collection::index find;
564 if((find = find_last(t)) >= 0)
567 this->erase_at(find);
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)
580 ::collection::index find;
581 if((find = find_first(t)) >= 0)
583 this->erase_at(find);
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)
593 if((find = find_first(t, find, last)) >= 0)
595 this->erase_at(find);
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)
606 ::collection::count count = 0;
608 if(contains(t, find, last, countMin, countMax))
611 while(::conditional(countMax >= 0, count < countMax) && (find = erase_first(t, find, last)) >= 0)
625template <
class TYPE,
class ARG_TYPE,
class ARRAY_TYPE >
626::collection::count comparable_eq_array_base < TYPE,ARG_TYPE, ARRAY_TYPE >::
630 ::collection::count count = 0;
632 while (erase_last(t) >= 0)
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)
672 ::collection::count count = 0;
677 count = this->get_size();
685 for(
auto &
item : container)
688 count += erase(
item);
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)
703 if (i < 0 || i > this->get_size())
706 throw_exception(error_bad_argument);
710 auto iFind = this->find_first(t);
715 this->insert_at(i, t);
724 this->erase_at(iFind);
726 this->insert_at(i - 1, t);
732 this->erase_at(iFind);
734 this->insert_at(i, t);