acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
comparable_eq_list.h
1#pragma once
2
3
4#include "list.h"
5
6
7template < class TYPE, class ARG_TYPE = const TYPE&, class LIST_BASE = ::list_base < TYPE, ARG_TYPE > >
9 public LIST_BASE
10{
11public:
12
13
14 using BASE_LIST = LIST_BASE;
15 using node = typename BASE_LIST::NODE;
16 using iterator = typename BASE_LIST::iterator;
17 using const_iterator = typename BASE_LIST::const_iterator;
18
19
20 using BASE_LIST::BASE_LIST;
21 using BASE_LIST::operator =;
22 //comparable_eq_list_base();
23 //comparable_eq_list_base(const comparable_eq_list_base & array);
24
25
26 iterator find_first_item(const TYPE &t, iterator start = nullptr, iterator end = nullptr) const;
27 iterator find_last_item(const TYPE &t, iterator start = nullptr, iterator end = nullptr) const;
28 ::collection::count get_count() const;
29 ::collection::count get_count(const TYPE & t, iterator start = nullptr, iterator end = nullptr, ::collection::count countMax = -1) const;
30 bool contains(const TYPE & t, iterator start = nullptr, iterator end = nullptr, ::collection::count countMin = 1, ::collection::count countMax = -1) const;
31 bool rear_contains(const TYPE & t, iterator start = nullptr, iterator end = nullptr, ::collection::count countMin = 1, ::collection::count countMax = -1) const;
32 bool erase_first(const TYPE & t);
33 bool erase_last(const TYPE & t);
34 bool erase_first(const TYPE & t, iterator & p, iterator end = nullptr);
35 bool erase_last(const TYPE & t, iterator & p, iterator end = nullptr);
36
37 using BASE_LIST::erase;
38 //::collection::count erase(const TYPE & t, iterator start = nullptr, iterator end = nullptr, ::collection::count countMin = 0, ::collection::count countMax = -1);
39 ::collection::count erase(const TYPE & t, iterator start = nullptr, iterator end = nullptr);
40 //::collection::count rear_erase(const TYPE & t, iterator start = nullptr, iterator end = nullptr, ::collection::count countMin = 0, ::collection::count countMax = -1);
41 template < prototype_container CONTAINER >
42 ::collection::count erase(const CONTAINER & container);
43
44
45 bool add_tail_unique(ARG_TYPE t);
46 bool add_head_unique(ARG_TYPE t);
47
48
49 bool add_unique(ARG_TYPE t)
50 {
51
52 auto pFind = this->find_first_item(t);
53
54 if (pFind)
55 {
56
57 return false;
58
59 }
60
61 this->add_tail(t);
62
63 return true;
64
65 }
66
67
68 void change(ARG_TYPE t, bool bAdd)
69 {
70
71 auto pFind = this->find_first_item(t);
72
73 if(pFind)
74 {
75
76 if (!bAdd)
77 {
78
79 this->erase(pFind);
80
81 }
82
83 }
84 else
85 {
86
87 if (bAdd)
88 {
89
90 this->add(t);
91
92 }
93
94 }
95
96 }
97
98
99 void toggle(ARG_TYPE t)
100 {
101
102 auto pFind = this->find_first_item(t);
103
104 if (pFind)
105 {
106
107 this->erase(pFind);
108
109 }
110 else
111 {
112
113 this->add(t);
114
115 }
116
117 }
118
119
120 template < prototype_container CONTAINER >
121 void merge_tail(const CONTAINER & container);
122 template < prototype_container CONTAINER >
123 void merge_head(const CONTAINER & container);
124 template < prototype_container CONTAINER >
125 void intersect(const CONTAINER & container);
126
127
128 comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE > & operator -= (const TYPE & t);
129 template < prototype_container CONTAINER >
130 comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE > & operator &= (const CONTAINER & container);
131 template < prototype_container CONTAINER >
132 comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE > & operator -= (const CONTAINER & container);
133 template < prototype_container CONTAINER >
134 comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE > & operator |= (const CONTAINER & container);
135
136 template < prototype_container CONTAINER >
137 comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE > operator -(const CONTAINER & container) const;
138
139
140};
141
142
143//template < class TYPE, class ARG_TYPE, class LIST_BASE>
144//comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE>::
145//comparable_eq_list_base()
146//{
147//
148//}
149
150
151//template < class TYPE, class ARG_TYPE, class LIST_BASE>
152//comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE>::
153//comparable_eq_list_base(const comparable_eq_list_base< TYPE, ARG_TYPE, LIST_BASE> & l) :
154//LIST_BASE(l)
155//{
156//
157//}
158
159
160template <class TYPE, class ARG_TYPE, class LIST_BASE>
161typename comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::iterator comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::
162find_first_item(const TYPE & t, iterator p, iterator end) const
163{
164
165 if(!p)
166 {
167
168 p = this->begin();
169
170 }
171
172 while(!::iterator_is_end(p, end))
173 {
174
175 if(*p == t)
176 {
177
178 return p;
179
180 }
181
182 p++;
183
184 }
185
186 return nullptr;
187
188}
189
190
191template <class TYPE, class ARG_TYPE, class LIST_BASE>
192typename comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::iterator comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::
193find_last_item(const TYPE & t, iterator start, iterator p) const
194{
195
196 if(!p)
197 {
198
199 p = this->end();
200
201 }
202
203 while(p && p != start)
204 {
205
206 if(*p == t)
207 {
208
209 return p;
210
211 }
212
213 p--;
214 }
215
216 return nullptr;
217
218}
219
220
221template <class TYPE, class ARG_TYPE, class LIST_BASE>
222inline ::collection::count comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::
223get_count() const
224{
225
226 return LIST_BASE::get_count();
227
228}
229
230
231template <class TYPE, class ARG_TYPE, class LIST_BASE>
232::collection::count comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::
233get_count(const TYPE & t, iterator start, iterator end, ::collection::count countMax) const
234{
235
236 ::collection::count count = 0;
237
238 while((countMax >= 0 && count <= countMax) && (start = find_first_item(t, start, end)))
239 {
240
241 count++;
242
243 }
244
245 return count;
246
247}
248
249
250template <class TYPE, class ARG_TYPE, class LIST_BASE>
251bool comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::
252contains(const TYPE & t, iterator p, iterator end, ::collection::count countMin, ::collection::count countMax) const
253{
254
255 ::collection::count count = 0;
256
257 while((count < countMin || (countMax >= 0 && count <= countMax)) && (p = find_first_item(t, p, end)))
258 {
259
260 count++;
261
262 }
263
264 return count >= countMin && conditional(countMax >= 0, count <= countMax);
265
266}
267
268
269template <class TYPE, class ARG_TYPE, class LIST_BASE>
270bool comparable_eq_list_base < TYPE, ARG_TYPE, LIST_BASE >::
271rear_contains(const TYPE & t, iterator p, iterator end, ::collection::count countMin, ::collection::count countMax) const
272{
273
274 ::collection::count count = 0;
275
276 while((count < countMin || (countMax >= 0 && count <= countMax)) && (p = find_last_item(t, p, end)))
277 {
278
279 count++;
280
281 }
282
283 return count >= countMin && conditional(countMax >= 0, count <= countMax);
284
285}
286
287
288template <class TYPE, class ARG_TYPE, class LIST_BASE>
289bool comparable_eq_list_base<TYPE, ARG_TYPE, LIST_BASE>::add_tail_unique(ARG_TYPE t)
290{
291
292 if(contains(t))
293 {
294
295 return false;
296
297 }
298
299 this->add_tail(t);
300
301 return true;
302
303}
304
305
306template <class TYPE, class ARG_TYPE, class LIST_BASE>
307bool comparable_eq_list_base<TYPE, ARG_TYPE, LIST_BASE>::add_head_unique(ARG_TYPE t)
308{
309
310 if(contains(t))
311 {
312
313 return false;
314
315 }
316
317 this->add_head(t);
318
319 return true;
320
321}
322
323
324template <class TYPE, class ARG_TYPE, class LIST_BASE>
325template < prototype_container CONTAINER >
327intersect(const CONTAINER & container)
328{
329
330 auto p = this->begin();
331
332 while(p)
333 {
334
335 if (!::contains(container, *p))
336 {
337
338 this->erase_defer_next(p);
339
340 }
341 else
342 {
343
344 p++;
345
346 }
347
348 }
349
350}
351
352
353template <class TYPE, class ARG_TYPE, class LIST_BASE>
354template < prototype_container CONTAINER >
356merge_tail(const CONTAINER & container)
357{
358
359 for (auto& item : container)
360 {
361
362 this->add_tail_unique(item);
363
364 }
365
366}
367
368
369template <class TYPE, class ARG_TYPE, class LIST_BASE>
370template < prototype_container CONTAINER >
372merge_head(const CONTAINER & container)
373{
374
375 for (auto& item : container)
376 {
377
378 this->add_head_unique(item);
379
380 }
381
382}
383
384
385
386template <class TYPE, class ARG_TYPE, class LIST_BASE>
387template < prototype_container CONTAINER >
389operator &= (const CONTAINER & container)
390{
391
392 this->intersect(container);
393
394 return *this;
395
396}
397
398
399template <class TYPE, class ARG_TYPE, class LIST_BASE>
401operator -= (const TYPE & t)
402{
403
404 this->erase(t);
405
406 return *this;
407
408}
409
410
411template <class TYPE, class ARG_TYPE, class LIST_BASE>
412template < prototype_container CONTAINER >
414operator -= (const CONTAINER & container)
415{
416
417 this->erase(container);
418
419 return *this;
420
421}
422
423
424template <class TYPE, class ARG_TYPE, class LIST_BASE>
425template < prototype_container CONTAINER >
427operator - (const CONTAINER & container) const
428{
429
430 auto list = *this;
431
432 list.erase(container);
433
434 return ::transfer(list);
435
436}
437
438
439template <class TYPE, class ARG_TYPE, class LIST_BASE>
440template < prototype_container CONTAINER >
442operator |= (const CONTAINER & container)
443{
444
445 this->merge_tail(container);
446
447 return *this;
448
449}
450
451
452template <class TYPE, class ARG_TYPE, class LIST_BASE>
453bool comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::
454erase_first(const TYPE & t)
455{
456
457 iterator p = this->find_first_item(t);
458
459 if (!p)
460 {
461
462 return false;
463
464 }
465
466 this->erase(p);
467
468 return true;
469
470}
471
472
473template <class TYPE, class ARG_TYPE, class LIST_BASE>
474bool comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::erase_first(const TYPE & t, iterator & p, iterator end)
475{
476
477 if((p = this->find_first_item(t, p, end)))
478 {
479
480 auto pErase = p;
481
482 p++;
483
484 this->erase(pErase);
485
486 return true;
487
488 }
489
490 return false;
491
492}
493
494
495//template <class TYPE, class ARG_TYPE, class LIST_BASE>
496//::collection::count comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::
497//erase(const TYPE & t, iterator p, iterator end, ::collection::count countMin, ::collection::count countMax)
498//{
499//
500// ::collection::count count = 0;
501//
502// if(contains(t, p, end, countMin, countMax))
503// {
504//
505// while (conditional(countMax >= 0, count < countMax) && erase_first(t, p, end))
506// {
507//
508// count++;
509//
510// }
511//
512// }
513//
514// return count;
515//
516//}
517
518
519
520template<class TYPE, class ARG_TYPE, class LIST_BASE>
521::collection::count comparable_eq_list_base<TYPE, ARG_TYPE, LIST_BASE>::erase(const TYPE &t, iterator start, iterator end)
522{
523
524 auto p = start;
525
526 auto begin = this->m_begin;
527
528 if (!p)
529 {
530
531 p = begin;
532
533 }
534
535 ::collection::count count = 0;
536
537 while (!::iterator_is_end(p, end))
538 {
539
540 if (*p == t)
541 {
542
543 auto pNext = p + 1;
544
545 this->erase(p);
546
547 p = pNext;
548
549 count++;
550
551 }
552 else
553 {
554
555 p++;
556
557 }
558
559 }
560
561 return count;
562
563}
564
565
566template <class TYPE, class ARG_TYPE, class LIST_BASE>
567bool comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::
568erase_last(const TYPE & t)
569{
570
571 auto p = find_last_item(t);
572
573 if(p)
574 {
575
576 this->erase(p);
577
578 return true;
579
580 }
581
582 return false;
583
584}
585
586
587template <class TYPE, class ARG_TYPE, class LIST_BASE>
588bool comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::
589erase_last(const TYPE & t, iterator & p, iterator end)
590{
591
592 if((p = find_last_item(t, p, end)))
593 {
594
595 auto pErase = p;
596
597 p--;
598
599 this->erase(pErase);
600
601 return true;
602
603 }
604
605 return false;
606
607}
608
609
610//template <class TYPE, class ARG_TYPE, class LIST_BASE>
611//::collection::count comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::
612//rear_erase(const TYPE & t, iterator p, iterator end, ::collection::count countMin, ::collection::count countMax)
613//{
614//
615// ::collection::count count = 0;
616//
617// if(contains(t, p, end, countMin, countMax))
618// {
619//
620// while (conditional(countMax >= 0, count < countMax) && erase_last(t, p, end))
621// {
622//
623// count++;
624//
625// }
626//
627// }
628//
629// return count;
630//
631//}
632
633
634template <class TYPE, class ARG_TYPE, class LIST_BASE>
635template < prototype_container CONTAINER >
636::collection::count comparable_eq_list_base < TYPE, ARG_TYPE , LIST_BASE >::erase(const CONTAINER & container)
637{
638
639 ::collection::count count = 0;
640
641 for(auto & item : container)
642 {
643
644 count += this->erase_item(item);
645
646 }
647
648 return count;
649
650}
651
652
653
Definition comparable_eq_list.h:10
Definition item.h:93
Definition std_iterator.h:49