aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
list_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
49
50// to ease parser
52
53namespace gum {
54
55 // ===========================================================================
56 // ===========================================================================
57 // === BUCKET IMPLEMENTATION ===
58 // ===========================================================================
59 // ===========================================================================
60
61 // default constructor
62 template < typename Val >
63 INLINE ListBucket< Val >::ListBucket(const Val& v) : _val_{v} {
64 // for debugging purposes
65 GUM_CONSTRUCTOR(ListBucket);
66 }
67
68 // constructor for Val rvalues
69 template < typename Val >
70 INLINE ListBucket< Val >::ListBucket(Val&& v) noexcept : _val_{std::move(v)} {
71 // for debugging purposes
72 GUM_CONSTRUCTOR(ListBucket);
73 }
74
75 // emplace constructor
76 template < typename Val >
77 template < typename... Args >
79 _val_(std::forward< Args >(args)...) {
80 // for debugging purposes
81 GUM_CONSTRUCTOR(ListBucket);
82 }
83
84 // copy constructor
85 template < typename Val >
87 // for debugging purposes
88 GUM_CONS_CPY(ListBucket);
89 }
90
91 // copy operator
92 template < typename Val >
94 // for debugging purposes
95 GUM_OP_CPY(ListBucket);
96
97 // no need to avoid self assignment
98 _val_ = src._val_;
99 return *this;
100 }
101
102 // WARNING: during its deletion, the bucket does not take care of properly
103 // re-chaining the chained list. This should be done by the Lists themselves
104 template < typename Val >
106 // for debugging purposes
107 GUM_DESTRUCTOR(ListBucket);
108 }
109
110 // equality check
111 template < typename Val >
112 INLINE bool ListBucket< Val >::operator==(const ListBucket< Val >& src) const {
113 return (src._val_ == _val_);
114 }
115
116 // inequality check
117 template < typename Val >
118 INLINE bool ListBucket< Val >::operator!=(const ListBucket< Val >& src) const {
119 return (src._val_ != _val_);
120 }
121
122 // dereferencing operator
123 template < typename Val >
124 INLINE const Val& ListBucket< Val >::operator*() const noexcept {
125 return _val_;
126 }
127
128 // dereferencing operator
129 template < typename Val >
130 INLINE Val& ListBucket< Val >::operator*() noexcept {
131 return _val_;
132 }
133
134 // returns the bucket toward the next element
135 template < typename Val >
136 INLINE const ListBucket< Val >* ListBucket< Val >::next() const noexcept {
137 return _next_;
138 }
139
140 // returns the bucket toward the preceding element
141 template < typename Val >
142 INLINE const ListBucket< Val >* ListBucket< Val >::previous() const noexcept {
143 return _prev_;
144 }
145
146 // ===========================================================================
147 // ===========================================================================
148 // === UNSAFE_CONST_LIST_ITERATOR IMPLEMENTATION ===
149 // ===========================================================================
150 // ===========================================================================
151
152 // default constructor
153 template < typename Val >
155 // for debugging purposes
156 GUM_CONSTRUCTOR(ListConstIterator);
157 }
158
159 // default constructor
160 template < typename Val >
162 _bucket_{theList._deb_list_} {
163 // for debugging purposes
164 GUM_CONSTRUCTOR(ListConstIterator);
165 }
166
167 // copy constructor
168 template < typename Val >
170 _bucket_{src._bucket_} {
171 // for debugging purposes
172 GUM_CONS_CPY(ListConstIterator);
174
175 // move constructor
176 template < typename Val >
178 _bucket_{std::move(src._bucket_)} {
179 // for debugging purposes
180 GUM_CONS_MOV(ListConstIterator);
181 }
182
183 // Constructor for an iterator pointing to the \e ind_eltth element of a
184 // List.
185 template < typename Val >
187 // for debugging purposes
188 GUM_CONSTRUCTOR(ListConstIterator);
189
190 // check if the index ind_elt passed as parameter is valid
191 if (ind_elt >= theList._nb_elements_) {
192 GUM_ERROR(UndefinedIteratorValue, "Not enough elements in the list")
193 }
194
195 // check if it is faster to find the indexth element from the start or
196 // from the end of the list
197 if (ind_elt < (theList._nb_elements_ >> 1)) {
198 // find the element we shall point to src the start of the list
199 for (_bucket_ = theList._deb_list_; ind_elt; --ind_elt, _bucket_ = _bucket_->_next_) {}
200 } else {
201 // find the element we shall point to src the end of the list
202 for (_bucket_ = theList._end_list_, ind_elt = theList._nb_elements_ - ind_elt - 1; ind_elt;
203 --ind_elt, _bucket_ = _bucket_->_prev_) {}
204 }
205 }
206
207 // Destructor
208 template < typename Val >
210 // for debugging purposes
211 GUM_DESTRUCTOR(ListConstIterator);
212 }
213
214 // Copy operator
215 template < typename Val >
218 // for debugging purposes
219 GUM_OP_CPY(ListConstIterator);
220
221 _bucket_ = src._bucket_;
222 return *this;
223 }
224
225 // move operator
226 template < typename Val >
229 // for debugging purposes
230 GUM_OP_MOV(ListConstIterator);
231 _bucket_ = src._bucket_;
232 return *this;
233 }
234
235 // returns the bucket the iterator is pointing to
236 template < typename Val >
238 return _bucket_;
239 }
240
241 // Makes the iterator point toward nothing
242 template < typename Val >
243 INLINE void ListConstIterator< Val >::clear() noexcept {
244 _bucket_ = nullptr;
245 }
246
247 // positions the iterator to the end of the list
248 template < typename Val >
249 INLINE void ListConstIterator< Val >::setToEnd() noexcept {
250 _bucket_ = nullptr;
251 }
252
253 // returns a bool indicating whether the iterator points to the end of the
254 // list
255 template < typename Val >
256 INLINE bool ListConstIterator< Val >::isEnd() const noexcept {
257 return (_bucket_ == nullptr);
258 }
259
260 // makes the iterator point to the next element in the List
261 template < typename Val >
263 // if we are pointing to an element of the chained list, just
264 // point on the next bucket in this list
265 if (_bucket_ != nullptr) { _bucket_ = _bucket_->_next_; }
266
267 return *this;
268 }
269
270 // makes the iterator point to the next element in the List
271 template < typename Val >
273 typename ListConstIterator< Val >::difference_type i) noexcept {
274 if (i >= 0) {
275 for (; i && (_bucket_ != nullptr); --i, _bucket_ = _bucket_->_next_) {}
276 } else {
277 for (; i && (_bucket_ != nullptr); ++i, _bucket_ = _bucket_->_prev_) {}
278 }
279 return *this;
280 }
281
282 // makes the iterator point to the preceding element in the List
283 template < typename Val >
285 // if we are pointing to an element of the chained list, just
286 // point on the preceding bucket in this list
287 if (_bucket_ != nullptr) { _bucket_ = _bucket_->_prev_; }
288
289 return *this;
290 }
291
292 // makes the iterator point to i elements before in the list
293 template < typename Val >
295 typename ListConstIterator< Val >::difference_type i) noexcept {
296 if (i >= 0) {
297 for (; i && (_bucket_ != nullptr); --i, _bucket_ = _bucket_->_prev_) {}
298 } else {
299 for (; i && (_bucket_ != nullptr); ++i, _bucket_ = _bucket_->_next_) {}
300 }
301 return *this;
302 }
303
304 // returns a new iterator
305 template < typename Val >
310
311 // returns a new iterator
312 template < typename Val >
317
318 // checks whether two iterators point toward different elements
319 template < typename Val >
320 INLINE bool
322 return (_bucket_ != src._bucket_);
323 }
324
325 // checks whether two iterators point toward the same elements.
326 template < typename Val >
327 INLINE bool
329 return (_bucket_ == src._bucket_);
330 }
331
332 // dereferences the value pointed to by the iterator
333 template < typename Val >
334 INLINE const Val* ListConstIterator< Val >::operator->() const {
335 if (_bucket_ != nullptr) return &(_bucket_->_val_);
336 else { GUM_ERROR(UndefinedIteratorValue, "Accessing a NULL object") }
337 }
338
339 // gives access to the content of the iterator
340 template < typename Val >
341 INLINE const Val& ListConstIterator< Val >::operator*() const {
342 if (_bucket_ != nullptr) return _bucket_->_val_;
343 else { GUM_ERROR(UndefinedIteratorValue, "Accessing a NULL object") }
344 }
345
346 // for STL compliance, a distance operator
347 template < typename Val >
351
352 for (ListConstIterator< Val > iter3 = iter2; iter1 != iter3; ++iter3, ++res) {}
353
354 return res;
355 }
356
357 // ===========================================================================
358 // ===========================================================================
359 // === UNSAFE_LIST_ITERATOR IMPLEMENTATION ===
360 // ===========================================================================
361 // ===========================================================================
362
363 // basic constructor
364 template < typename Val >
366 GUM_CONSTRUCTOR(ListIterator);
367 }
368
369 // constructor for a begin
370 template < typename Val >
371 INLINE ListIterator< Val >::ListIterator(const List< Val >& theList) noexcept :
372 ListConstIterator< Val >(theList) {
373 GUM_CONSTRUCTOR(ListIterator);
374 }
375
376 // copy constructor
377 template < typename Val >
380 GUM_CONS_CPY(ListIterator);
381 }
382
383 // move constructor
384 template < typename Val >
386 ListConstIterator< Val >(std::move(src)) {
387 GUM_CONS_MOV(ListIterator);
388 }
389
390 // Constructor for an iterator pointing to the \e ind_eltth element of a
391 // List.
392 template < typename Val >
393 INLINE ListIterator< Val >::ListIterator(const List< Val >& theList, Size ind_elt) :
394 ListConstIterator< Val >(theList, ind_elt) {
395 GUM_CONSTRUCTOR(ListIterator);
396 }
397
398 // Copy operator
399 template < typename Val >
400 INLINE ListIterator< Val >&
402 GUM_OP_CPY(ListIterator);
404 return *this;
405 }
406
407 // move operator
408 template < typename Val >
410 GUM_OP_MOV(ListIterator);
412 return *this;
413 }
414
415 // Destructor
416 template < typename Val >
418 GUM_DESTRUCTOR(ListIterator);
419 }
420
421 // test equality
422 template < typename Val >
423 INLINE bool ListIterator< Val >::operator==(const ListIterator< Val >& src) const noexcept {
425 }
426
427 // test inequality
428 template < typename Val >
429 INLINE bool ListIterator< Val >::operator!=(const ListIterator< Val >& src) const noexcept {
430 return !operator==(src);
431 }
432
433 // makes the iterator point to the next element in the List
434 template < typename Val >
437 return *this;
438 }
439
440 // makes the iterator point to i elements further in the List
441 template < typename Val >
442 INLINE ListIterator< Val >&
447
448 // makes the iterator point to the preceding element in the List
449 template < typename Val >
454
455 // makes the iterator point to i elements before in the List
456 template < typename Val >
457 INLINE ListIterator< Val >&
462
463 // returns a new iterator
464 template < typename Val >
467 return ListIterator< Val >(*this) += i;
468 }
469
470 // returns a new iterator
471 template < typename Val >
476
477 // dereferences the value pointed to by the iterator
478 template < typename Val >
480 return const_cast< Val* >(ListConstIterator< Val >::operator->());
482
483 // dereferences the value pointed to by the iterator
484 template < typename Val >
485 INLINE const Val* ListIterator< Val >::operator->() const {
487 }
488
489 // gives access to the content of the iterator
490 template < typename Val >
492 return const_cast< Val& >(ListConstIterator< Val >::operator*());
493 }
494
495 // gives access to the content of the iterator
496 template < typename Val >
497 INLINE const Val& ListIterator< Val >::operator*() const {
499 }
500
501 // ===========================================================================
502 // ===========================================================================
503 // === SAFE LIST CONST ITERATOR IMPLEMENTATION ===
504 // ===========================================================================
505 // ===========================================================================
506
507 // basic constructor
508 template < typename Val >
510 // for debugging purposes
511 GUM_CONSTRUCTOR(ListConstIteratorSafe);
512 }
513
514 // Constructor for a begin
515 template < typename Val >
517 _list_{&theList}, _bucket_{theList._deb_list_} {
518 // for debugging purposes
519 GUM_CONSTRUCTOR(ListConstIteratorSafe);
520
521 // add the iterator to the list of safe iterators
522 theList._safe_iterators_.push_back(this);
523 }
524
525 // copy constructor
526 template < typename Val >
527 INLINE
531 // for debugging purposes
532 GUM_CONS_CPY(ListConstIteratorSafe);
533
534 // add the iterator to the list of safe iterators
535 if (_list_ != nullptr) _list_->_safe_iterators_.push_back(this);
536 }
537
538 // Constructor for an iterator pointing to the \e ind_eltth element of a
539 // List.
540 template < typename Val >
541
543 _list_{&theList} {
544 // for debugging purposes
545 GUM_CONSTRUCTOR(ListConstIteratorSafe);
546
547 // check if the index ind_elt passed as parameter is valid
548 if (ind_elt >= _list_->_nb_elements_) {
549 GUM_ERROR(UndefinedIteratorValue, "Not enough elements in the list")
550 }
551
552 // check if it is faster to find the indexth element src the start or
553 // src the end of the list
554 if (ind_elt < (_list_->_nb_elements_ >> 1)) {
555 // find the element we shall point to src the start of the list
556 for (_bucket_ = _list_->_deb_list_; ind_elt; --ind_elt, _bucket_ = _bucket_->_next_) {}
557 } else {
558 // find the element we shall point to src the end of the list
559 for (_bucket_ = _list_->_end_list_, ind_elt = _list_->_nb_elements_ - ind_elt - 1; ind_elt;
560 --ind_elt, _bucket_ = _bucket_->_prev_) {}
561 }
563 // add the iterator to the list of safe iterators
564 theList._safe_iterators_.push_back(this);
565 }
566
567 // move constructor
568 template < typename Val >
572 // for debugging purposes
573 GUM_CONS_MOV(ListConstIteratorSafe);
574
575 if (_list_ != nullptr) {
576 // substitute src by this in the list of safe iterators
577 std::vector< ListConstIteratorSafe< Val >* >& vect = _list_->_safe_iterators_;
578
579 for (auto ptr = vect.rbegin(); ptr != vect.rend(); --ptr) {
580 if (*ptr == &src) {
581 *ptr = this;
582 break;
583 }
584 }
585
586 src._list_ = nullptr;
587 src._bucket_ = nullptr;
588 src._null_pointing_ = false;
589 }
590 }
591
592 // remove the iterator for its list' safe iterators list
593 template < typename Val >
595 // find where the iterator is
596 std::vector< ListConstIteratorSafe< Val >* >& vect = _list_->_safe_iterators_;
597
598 for (auto i = vect.size() - 1; i >= 0; --i) {
599 if (vect[i] == this) {
600 vect.erase(vect.begin() + i);
601 break;
602 }
603 }
604 }
605
606 // Copy operator
607 template < typename Val >
610 // avoid self assignment
611 if (this != &src) {
612 // for debugging purposes
613 GUM_OP_CPY(ListConstIteratorSafe);
614
615 // check if src and this belong to the same list. If this is not
616 // the case, we shall remove this from its iterator's list and
617 // put it into src's list one.
618 if (_list_ && (src._list_ != _list_)) {
620 _list_ = nullptr;
621 }
622
623 // if necessary, put this into the same list of safe iterators as src
624 if (src._list_ && (src._list_ != _list_)) {
625 try {
626 src._list_->_safe_iterators_.push_back(this);
627 } catch (...) {
628 _list_ = nullptr;
629 _bucket_ = nullptr;
630 _null_pointing_ = false;
631 throw;
632 }
633 }
634
635 _list_ = src._list_;
636 _bucket_ = src._bucket_;
637 _prev_current_bucket_ = src._prev_current_bucket_;
638 _next_current_bucket_ = src._next_current_bucket_;
639 _null_pointing_ = src._null_pointing_;
640 }
641
642 return *this;
643 }
644
645 // move operator
646 template < typename Val >
649 // avoid self assignment
650 if (this != &src) {
651 // for debugging purposes
652 GUM_OP_MOV(ListConstIteratorSafe);
653
654 // if the two iterators do not point to the same list, remove
655 // the current iterator from its safe iterators list
656 if ((_list_ != nullptr) && (src._list_ != _list_)) {
657 _removeFromSafeList_();
658 _list_ = nullptr;
659 }
660
661 // now if src points to a list, put this at its location
662 if ((src._list_ != nullptr)) {
663 std::vector< ListConstIteratorSafe< Val >* >& vect = src._list_->_safe_iterators_;
664 Idx index_src = Size(vect.size()) - 1;
665
666 for (;; --index_src) {
667 if (vect[index_src] == &src) { break; }
668 }
669
670 if (_list_ == nullptr) {
671 vect[index_src] = this;
672 } else {
673 vect.erase(vect.begin() + index_src);
674 }
675 }
676
677 _list_ = src._list_;
678 _bucket_ = src._bucket_;
679 _prev_current_bucket_ = src._prev_current_bucket_;
680 _next_current_bucket_ = src._next_current_bucket_;
681 _null_pointing_ = src._null_pointing_;
682
683 src._list_ = nullptr;
684 src._bucket_ = nullptr;
685 src._null_pointing_ = false;
686 }
687
688 return *this;
689 }
690
691 // Destructor
692 template < typename Val >
694 // for debugging purposes
695 GUM_DESTRUCTOR(ListConstIteratorSafe);
696
697 // remove the iterator src the table's iterator list
699 }
700
701 // returns the bucket the iterator is pointing to
702 template < typename Val >
704 return _bucket_;
705 }
706
707 // Makes the iterator point toward nothing
708 template < typename Val >
710 // remove the iterator src the list's iterator list
712
713 // set its list as well as the element it points to to nullptr
714 _list_ = nullptr;
715 _bucket_ = nullptr;
716 _null_pointing_ = false;
717 }
719 // positions the iterator to the end of the list
720 template < typename Val >
722 clear();
723 }
724
725 // returns a bool indicating whether the iterator points to the end of the
726 // list
727 template < typename Val >
729 return _null_pointing_
730 ? (_next_current_bucket_ == nullptr) && (_prev_current_bucket_ == nullptr)
731 : (_bucket_ == nullptr);
732 }
733
734 // makes the iterator point to the next element in the List
735 template < typename Val >
737 // check if we are pointing to something that has been deleted
738 if (_null_pointing_) {
739 _null_pointing_ = false;
740
741 // if we are pointing to an element of the chained list that has been
742 // deleted
743 // but that has a next element, just point on the latter
744 if (_next_current_bucket_ != nullptr) {
746 return *this;
747 }
748
749 // here we were pointing on an extremity of the list (either end or rend)
750 // if prev_current_bucket is not null, then we are at rend and doing
751 // a ++ shall now point to the beginning of the list
752 if (_prev_current_bucket_ != nullptr) {
754 return *this;
756
757 // here, we are at the end of the chained list, hence we shall remain at
758 // end
759 _bucket_ = nullptr;
760 return *this;
761 } else {
762 // if we are pointing to an element of the chained list, just
763 // point on the next bucket in this list
764 if (_bucket_ != nullptr) { _bucket_ = _bucket_->_next_; }
765
766 return *this;
767 }
768 }
769
770 // makes the iterator point to i elements before in the List
771 template < typename Val >
773 // check if we are pointing to something that has been deleted
774 if (_null_pointing_) {
775 _null_pointing_ = false;
776
777 // if we are pointing to an element of the chained list that has been
778 // deleted
779 // but that has a preceding element, just point on the latter
780 if (_prev_current_bucket_ != nullptr) {
782 } else {
783 // here we were pointing on an extremity of the list (either end or
784 // rend)
785 // if next_current_bucket is not null, then we are at end and doing
786 // a -- shall now point to the beginning of the list
787 if (_next_current_bucket_ != nullptr) {
789 } else {
790 // here, we are at the rend of the chained list, hence we shall remain
791 // at rend
792 _bucket_ = nullptr;
793 return *this;
794 }
795 }
796 } else {
797 // if we are pointing to an element of the chained list, just
798 // point on the preceding bucket in this list
799 if (_bucket_ != nullptr) { _bucket_ = _bucket_->_prev_; }
800 }
801
802 for (--i; i && (_bucket_ != nullptr); --i, _bucket_ = _bucket_->_prev_) {}
803
804 return *this;
805 }
806
807 // makes the iterator point to the next element in the List
808 template < typename Val >
810 // check if we are pointing to something that has been deleted
811 if (_null_pointing_) {
812 _null_pointing_ = false;
813
814 // if we are pointing to an element of the chained list that has been
815 // deleted
816 // but that has a next element, just point on the latter
817 if (_next_current_bucket_ != nullptr) {
819 } else {
820 // here we were pointing on an extremity of the list (either end or
821 // rend)
822 // if prev_current_bucket is not null, then we are at rend and doing
823 // a ++ shall now point to the beginning of the list
824 if (_prev_current_bucket_ != nullptr) {
826 } else {
827 // here, we are at the end of the chained list, hence we shall
828 // remain at end
829 _bucket_ = nullptr;
830 return *this;
831 }
832 }
833 } else {
834 // if we are pointing to an element of the chained list, just
835 // point on the next bucket in this list
836 if (_bucket_ != nullptr) { _bucket_ = _bucket_->_next_; }
837 }
838
839 for (--i; i && (_bucket_ != nullptr); --i, _bucket_ = _bucket_->_next_) {}
840
841 return *this;
842 }
843
844 // makes the iterator point to the next element in the List
845 template < typename Val >
848 if (!i) return *this;
849
850 if (i < 0) return _opMinus_(-i);
851 else return _opPlus_(i);
852 }
854 // makes the iterator point to the preceding element in the List
855 template < typename Val >
857 // check if we are pointing to something that has been deleted
858 if (_null_pointing_) {
859 _null_pointing_ = false;
860
861 // if we are pointing to an element of the chained list that has been
862 // deleted
863 // but that has a preceding element, just point on the latter
864 if (_prev_current_bucket_ != nullptr) {
866 return *this;
867 }
868
869 // here we were pointing on an extremity of the list (either end or rend)
870 // if next_current_bucket is not null, then we are at end and doing
871 // a -- shall now point to the beginning of the list
872 if (_next_current_bucket_ != nullptr) {
874 return *this;
875 }
876
877 // here, we are at the rend of the chained list, hence we shall remain
878 // at rend
879 _bucket_ = nullptr;
880 return *this;
881 } else {
882 // if we are pointing to an element of the chained list, just
883 // point on the preceding bucket in this list
884 if (_bucket_ != nullptr) { _bucket_ = _bucket_->_prev_; }
885
886 return *this;
887 }
888 }
889
890 // makes the iterator point to i elements before in the List
891 template < typename Val >
894 if (!i) return *this;
895
896 if (i < 0) return _opPlus_(-i);
897 else return _opMinus_(i);
898 }
899
900 // returns a new iterator
901 template < typename Val >
906
907 // returns a new iterator
908 template < typename Val >
913
914 // checks whether two iterators point toward different elements
915 template < typename Val >
916 INLINE bool
922
923 // checks whether two iterators point toward the same elements.
924 template < typename Val >
925 INLINE bool
931
932 // dereferences the value pointed to by the iterator
933 template < typename Val >
935 if (_bucket_ != nullptr) return &(_bucket_->_val_);
936 else { GUM_ERROR(UndefinedIteratorValue, "Accessing a NULL object") }
937 }
938
939 // gives access to the content of the iterator
940 template < typename Val >
941 INLINE const Val& ListConstIteratorSafe< Val >::operator*() const {
942 if (_bucket_ != nullptr) return _bucket_->_val_;
943 else { GUM_ERROR(UndefinedIteratorValue, "Accessing a NULL object") }
944 }
945
946 // for STL compliance, a distance operator
947 template < typename Val >
950 const ListConstIteratorSafe< Val >& iter2) {
952 ListConstIteratorSafe< Val > iter3{iter2};
953
954 for (; iter1 != iter3; ++iter3, ++res) {}
955
956 return res;
957 }
958
959 // ===========================================================================
960 // ===========================================================================
961 // === LIST ITERATOR IMPLEMENTATION ===
962 // ===========================================================================
963 // ===========================================================================
964
965 // basic constructor
966 template < typename Val >
968 GUM_CONSTRUCTOR(ListIteratorSafe);
969 }
970
971 // constructor for a begin
972 template < typename Val >
973
975 ListConstIteratorSafe< Val >(theList) {
976 GUM_CONSTRUCTOR(ListIteratorSafe);
977 }
979 // copy constructor
980 template < typename Val >
985
986 // Constructor for an iterator pointing to the \e ind_eltth element of a
987 // List.
988 template < typename Val >
990 ListConstIteratorSafe< Val >(theList, ind_elt) {
991 GUM_CONSTRUCTOR(ListIteratorSafe);
992 }
993
994 // move constructor
995 template < typename Val >
997 ListConstIteratorSafe< Val >(std::move(src)) {
998 GUM_CONS_MOV(ListIteratorSafe);
999 }
1000
1001 // Copy operator
1002 template < typename Val >
1005 // for debugging purposes
1006 GUM_OP_CPY(ListIteratorSafe);
1008 return *this;
1009 }
1010
1011 // move operator
1012 template < typename Val >
1015 // for debugging purposes
1016 GUM_OP_MOV(ListIteratorSafe);
1018 return *this;
1019 }
1020
1021 // Destructor
1022 template < typename Val >
1024 GUM_DESTRUCTOR(ListIteratorSafe);
1025 }
1026
1027 // test equality
1028 template < typename Val >
1032
1033 // test inequality
1034 template < typename Val >
1036 return !operator==(src);
1037 }
1038
1039 // makes the iterator point to the next element in the List
1040 template < typename Val >
1045
1046 // makes the iterator point to the next element in the List
1047 template < typename Val >
1049 typename ListIteratorSafe< Val >::difference_type i) noexcept {
1051 return *this;
1052 }
1053
1054 // makes the iterator point to the preceding element in the List
1055 template < typename Val >
1061 // makes the iterator point to the preceding element in the List
1062 template < typename Val >
1068
1069 // returns a new iterator
1070 template < typename Val >
1075
1076 // returns a new iterator
1077 template < typename Val >
1082
1083 // dereferences the value pointed to by the iterator
1084 template < typename Val >
1086 return const_cast< Val* >(ListConstIteratorSafe< Val >::operator->());
1087 }
1088
1089 // dereferences the value pointed to by the iterator
1090 template < typename Val >
1094
1095 // gives access to the content of the iterator
1096 template < typename Val >
1098 return const_cast< Val& >(ListConstIteratorSafe< Val >::operator*());
1099 }
1100
1101 // gives access to the content of the iterator
1102 template < typename Val >
1103 INLINE const Val& ListIteratorSafe< Val >::operator*() const {
1105 }
1106
1107 // ===========================================================================
1108 // ===========================================================================
1109 // === LIST IMPLEMENTATION ===
1110 // ===========================================================================
1111 // ===========================================================================
1112
1113 // a function used to perform copies of elements of Lists
1114 template < typename Val >
1116 ListBucket< Val >* ptr;
1117 ListBucket< Val >* old_ptr = nullptr;
1118 ListBucket< Val >* new_elt = nullptr;
1119
1120 // copy src's list
1121 try {
1122 for (ptr = src._deb_list_; ptr != nullptr; ptr = ptr->_next_) {
1123 // create a copy bucket
1124 new_elt = new ListBucket< Val >(*ptr);
1125
1126 // rechain properly the new list (the next field is already initialized
1127 // with nullptr)
1128 new_elt->_prev_ = old_ptr;
1129
1130 if (old_ptr) old_ptr->_next_ = new_elt;
1131 else _deb_list_ = new_elt;
1132
1133 old_ptr = new_elt;
1134 }
1135 } catch (...) {
1136 // problem: we could not allocate an element in the list => we delete
1137 // the elements created so far and we throw an exception
1138 for (; _deb_list_ != nullptr; _deb_list_ = const_cast< ListBucket< Val >* >(ptr)) {
1139 ptr = _deb_list_->_next_;
1140 delete _deb_list_;
1141 }
1142
1143 _deb_list_ = nullptr;
1144 throw;
1145 }
1146
1147 // update properly the end of the chained list and the number of elements
1148 _end_list_ = old_ptr;
1150 }
1151
1152 // deletes all the elements of a chained list.
1153 template < typename Val >
1155 // first we update all the safe iterators of the list : they should now
1156 // point to end/rend
1157 for (const auto ptr_iter: _safe_iterators_) {
1158 ptr_iter->clear();
1159 }
1160
1161 // clear all the values
1162 for (ListBucket< Val >*ptr = _deb_list_, *next_ptr = nullptr; ptr != nullptr; ptr = next_ptr) {
1163 next_ptr = ptr->_next_;
1164 delete ptr;
1165 }
1166
1167 _nb_elements_ = 0;
1168 _deb_list_ = nullptr;
1169 _end_list_ = nullptr;
1170 }
1171
1172 // A basic constructor that creates an empty list
1173 template < typename Val >
1175 // for debugging purposes
1176 GUM_CONSTRUCTOR(List);
1177
1178 // reserve space for only the default number of iterators
1180 }
1181
1182 // Copy constructor
1183 template < typename Val >
1184 INLINE List< Val >::List(const List< Val >& src) {
1185 // for debugging purposes
1186 GUM_CONS_CPY(List);
1187
1188 // copy the elements
1189 _copy_elements_(src);
1190
1191 // reserve space for only the default number of iterators
1193 }
1194
1195 // move constructor
1196 template < typename Val >
1197 INLINE List< Val >::List(List< Val >&& src) noexcept :
1198 _deb_list_{std::move(src._deb_list_)}, _end_list_{std::move(src._end_list_)},
1199 _nb_elements_{std::move(src._nb_elements_)},
1200 _safe_iterators_{std::move(src._safe_iterators_)} {
1201 // for debugging purposes
1202 GUM_CONS_MOV(List);
1203
1204 src._deb_list_ = nullptr;
1205 src._end_list_ = nullptr;
1206 src._nb_elements_ = 0;
1207 src._safe_iterators_.clear();
1208 }
1209
1210 // initializer_list constructor
1211 template < typename Val >
1212 INLINE List< Val >::List(std::initializer_list< Val > list) {
1213 // for debugging purposes
1214 GUM_CONSTRUCTOR(List);
1215
1216 // adding all the elements
1217 for (const auto& val: list) {
1218 pushBack(val);
1219 }
1221 // reserve space for only the default number of iterators
1223 }
1224
1225 // Destructor
1226 template < typename Val >
1228 // for debugging (although this program is bug-free)
1229 GUM_DESTRUCTOR(List);
1230
1231 // we detach all the safe iterators attached to the current List and we
1232 // remove all the elements from the list
1233 clear();
1235
1236 // Copy operator. The List iterator's list is not shared with that of \e src.
1237 template < typename Val >
1239 // avoid self assignment
1240 if (this != &src) {
1241 // for debugging purposes
1242 GUM_OP_CPY(List);
1243
1244 // remove the old content of 'this' and update accordingly the iterators
1245 clear();
1246
1247 // perform the copy
1248 _copy_elements_(src);
1249 }
1250
1251 return *this;
1252 }
1253
1254 // move operator
1255 template < typename Val >
1257 // avoid self assignment
1258 if (this != &src) {
1259 // for debugging purposes
1260 GUM_OP_MOV(List);
1261
1262 // remove the old content of 'this' and update accordingly the iterators
1263 clear();
1264
1265 // perform the move
1266 _deb_list_ = std::move(src._deb_list_);
1267 _end_list_ = std::move(src._end_list_);
1268 _nb_elements_ = std::move(src._nb_elements_);
1269 _safe_iterators_ = std::move(src._safe_iterators_);
1270
1271 src._deb_list_ = nullptr;
1272 src._end_list_ = nullptr;
1274 src._safe_iterators_.clear();
1275 }
1276
1277 return *this;
1278 }
1279
1280 // the iterator pointing to the end of the List
1281 template < typename Val >
1283 return *(reinterpret_cast< const ListConstIteratorSafe< Val >* >(_list_end_safe_));
1285
1286 // the iterator pointing to the end of the List
1287 template < typename Val >
1289 return *(reinterpret_cast< const ListIteratorSafe< Val >* >(_list_end_safe_));
1290 }
1291
1292 // the iterator pointing to the end of the List
1293 template < typename Val >
1294 INLINE const ListConstIterator< Val >& List< Val >::cend() const noexcept {
1295 return *(reinterpret_cast< const ListConstIterator< Val >* >(_list_end_));
1296 }
1297
1298 // the iterator pointing to the end of the List
1299 template < typename Val >
1300 INLINE const ListIterator< Val >& List< Val >::end() noexcept {
1301 return *(reinterpret_cast< const ListIterator< Val >* >(_list_end_));
1302 }
1303
1304 // the iterator pointing to the end of the List
1305 template < typename Val >
1306 INLINE const ListConstIterator< Val >& List< Val >::end() const noexcept {
1307 return *(reinterpret_cast< const ListConstIterator< Val >* >(_list_end_));
1308 }
1309
1310 // the iterator pointing to the rend (just before the beginning) of the List
1311 template < typename Val >
1313 return *(reinterpret_cast< const ListConstIteratorSafe< Val >* >(_list_end_safe_));
1314 }
1315
1316 // the iterator pointing to the rend (just before the beginning) of the List
1317 template < typename Val >
1319 return *(reinterpret_cast< const ListIteratorSafe< Val >* >(_list_end_safe_));
1320 }
1321
1322 // the iterator pointing to the rend (just before the beginning) of the List
1323 template < typename Val >
1324 INLINE const ListConstIterator< Val >& List< Val >::crend() const noexcept {
1325 return *(reinterpret_cast< const ListConstIterator< Val >* >(_list_end_));
1326 }
1327
1328 // the iterator pointing to the rend (just before the beginning) of the List
1329 template < typename Val >
1330 INLINE const ListIterator< Val >& List< Val >::rend() noexcept {
1331 return *(reinterpret_cast< const ListIterator< Val >* >(_list_end_));
1332 }
1333
1334 // the iterator pointing to the rend (just before the beginning) of the List
1335 template < typename Val >
1336 INLINE const ListConstIterator< Val >& List< Val >::rend() const noexcept {
1337 return *(reinterpret_cast< const ListConstIterator< Val >* >(_list_end_));
1338 }
1339
1340 // the iterator pointing to the beginning of the List
1341 template < typename Val >
1343 return ListConstIteratorSafe< Val >{*this};
1344 }
1345
1346 // the iterator pointing to the beginning of the List
1347 template < typename Val >
1350 }
1351
1352 // the iterator pointing to the beginning of the List
1353 template < typename Val >
1355 return ListConstIterator< Val >{*this};
1356 }
1358 // the iterator pointing to the beginning of the List
1359 template < typename Val >
1361 return ListIterator< Val >{*this};
1362 }
1363
1364 // the iterator pointing to the beginning of the List
1365 template < typename Val >
1367 return ListConstIterator< Val >{*this};
1368 }
1369
1370 // the iterator pointing to the rbegin (the last element) of the List
1371 template < typename Val >
1376
1377 // the iterator pointing to the rbegin (the last element) of the List
1378 template < typename Val >
1383
1384 // the iterator pointing to the rbegin (the last element) of the List
1385 template < typename Val >
1390
1391 // the iterator pointing to the rbegin (the last element) of the List
1392 template < typename Val >
1394 if (_nb_elements_) return ListIterator< Val >{*this, _nb_elements_ - 1};
1395 else return ListIterator< Val >{};
1396 }
1397
1398 // the iterator pointing to the rbegin (the last element) of the List
1399 template < typename Val >
1404
1405 // create a new bucket with a given value
1406 template < typename Val >
1407 INLINE ListBucket< Val >* List< Val >::_createBucket_(const Val& val) const {
1408 return new ListBucket< Val >(val);
1409 }
1410
1411 // create a new bucket with a given value
1412 template < typename Val >
1414 return new ListBucket< Val >(std::move(val));
1415 }
1416
1417 // create an emplace bucket
1418 template < typename Val >
1419 template < typename... Args >
1422 std::forward< Args >(args)...);
1423 }
1424
1425 // insert a bucket at the front of the list
1426 template < typename Val >
1428 new_elt->_next_ = _deb_list_;
1429
1430 if (_deb_list_ != nullptr) _deb_list_->_prev_ = new_elt;
1431 else _end_list_ = new_elt;
1432
1433 _deb_list_ = new_elt;
1434
1435 // update the number of elements
1436 ++_nb_elements_;
1437
1438 // return the inserted element
1439 return new_elt->_val_;
1440 }
1441
1442 // insert a bucket at the end of the list
1443 template < typename Val >
1445 // place the bucket at the end of the list
1446 new_elt->_prev_ = _end_list_;
1447
1448 if (_end_list_ != nullptr) _end_list_->_next_ = new_elt;
1449 else _deb_list_ = new_elt;
1450
1451 _end_list_ = new_elt;
1452
1453 // update the number of elements
1454 ++_nb_elements_;
1455
1456 // returns the current value
1457 return new_elt->_val_;
1458 }
1459
1460 // Insertion of a new element (a copy) at the beginning of the chained list.
1461 template < typename Val >
1462 INLINE Val& List< Val >::pushFront(const Val& val) {
1463 return _pushFront_(_createBucket_(val));
1464 }
1465
1466 // Insertion of a new element (a copy) at the beginning of the chained list.
1467 template < typename Val >
1468 INLINE Val& List< Val >::pushFront(Val&& val) {
1469 return _pushFront_(_createBucket_(std::move(val)));
1470 }
1471
1472 // an alias for pushFront used for STL compliance
1473 template < typename Val >
1474 template < typename... Args >
1475 INLINE Val& List< Val >::push_front(Args&&... args) {
1476 return pushFront(std::forward< Args >(args)...);
1477 }
1478
1479 // emplace elements at the beginning of the chained list
1480 template < typename Val >
1481 template < typename... Args >
1482 INLINE Val& List< Val >::emplaceFront(Args&&... args) {
1483 return _pushFront_(_createEmplaceBucket_(std::forward< Args >(args)...));
1484 }
1485
1486 // Insertion of a new element (a copy) at the end of the chained list.
1487 template < typename Val >
1488 INLINE Val& List< Val >::pushBack(const Val& val) {
1489 return _pushBack_(_createBucket_(val));
1490 }
1491
1492 // pushBack for rvalues
1493 template < typename Val >
1494 INLINE Val& List< Val >::pushBack(Val&& val) {
1495 return _pushBack_(_createBucket_(std::move(val)));
1496 }
1497
1498 // an alias for pushBack used for STL compliance
1499 template < typename Val >
1500 template < typename... Args >
1501 INLINE Val& List< Val >::push_back(Args&&... args) {
1502 return pushBack(std::forward< Args >(args)...);
1503 }
1504
1505 // emplace elements at the end of the chained list
1506 template < typename Val >
1507 template < typename... Args >
1508 INLINE Val& List< Val >::emplaceBack(Args&&... args) {
1509 return _pushBack_(_createEmplaceBucket_(std::forward< Args >(args)...));
1510 }
1511
1512 // Insertion of a new element at the end of the chained list (alias of
1513 // pushBack)
1514 template < typename Val >
1515 INLINE Val& List< Val >::insert(const Val& val) {
1516 return pushBack(val);
1517 }
1518
1519 // insert for rvalues
1520 template < typename Val >
1521 INLINE Val& List< Val >::insert(Val&& val) {
1522 return pushBack(std::move(val));
1523 }
1524
1525 // returns the bucket corresponding to the ith position
1526 template < typename Val >
1528 ListBucket< Val >* ptr;
1529
1530 if (i < _nb_elements_ / 2) {
1531 for (ptr = _deb_list_; i; --i, ptr = ptr->_next_) {}
1532 } else {
1533 for (ptr = _end_list_, i = _nb_elements_ - i - 1; i; --i, ptr = ptr->_prev_) {}
1534 }
1535
1536 return ptr;
1537 }
1538
1539 // insert a new bucket before another one
1540 template < typename Val >
1542 ListBucket< Val >* current_elt) {
1543 new_elt->_next_ = current_elt;
1544 new_elt->_prev_ = current_elt->_prev_;
1545 current_elt->_prev_ = new_elt;
1546
1547 if (new_elt->_prev_ == nullptr) _deb_list_ = new_elt;
1548 else new_elt->_prev_->_next_ = new_elt;
1549
1550 // update the number of elements
1551 ++_nb_elements_;
1552
1553 // returns the current value
1554 return new_elt->_val_;
1555 }
1556
1557 // insert a new bucket after another one
1558 template < typename Val >
1560 ListBucket< Val >* current_elt) {
1561 new_elt->_prev_ = current_elt;
1562 new_elt->_next_ = current_elt->_next_;
1563 current_elt->_next_ = new_elt;
1564
1565 if (new_elt->_next_ == nullptr) _end_list_ = new_elt;
1566 else new_elt->_next_->_prev_ = new_elt;
1567
1568 // update the number of elements
1569 ++_nb_elements_;
1570
1571 // returns the current value
1572 return new_elt->_val_;
1573 }
1574
1575 // inserts a new element at the ith pos of the chained list
1576 template < typename Val >
1577 INLINE Val& List< Val >::insert(Size pos, const Val& val) {
1578 // if ther are fewer elements than pos, put the value at the end of the list
1579 if (_nb_elements_ <= pos) { return pushBack(val); }
1580
1581 return _insertBefore_(_createBucket_(val), _getIthBucket_(pos));
1582 }
1583
1584 // insert an rvalue at the ith pos of the chained list
1585 template < typename Val >
1586 INLINE Val& List< Val >::insert(Size pos, Val&& val) {
1587 // if ther are fewer elements than pos, put the value at the end of the list
1588 if (_nb_elements_ <= pos) { return pushBack(std::move(val)); }
1589
1590 return _insertBefore_(_createBucket_(std::move(val)), _getIthBucket_(pos));
1591 }
1592
1593 // inserts a new bucket before or after the location pointed to by an
1594 // iterator
1595 template < typename Val >
1597 ListBucket< Val >* new_elt,
1598 location place) {
1599 // find the location around which the new element should be inserted
1600 ListBucket< Val >* ptr;
1601
1602 if (iter._null_pointing_) {
1603 if (place == location::BEFORE) {
1604 ptr = iter._next_current_bucket_;
1605 } else {
1606 ptr = iter._prev_current_bucket_;
1607 }
1608 } else {
1609 ptr = iter._getBucket_();
1610 }
1611
1612 if (ptr == nullptr) {
1613 // here, we are at the end of the list
1614 return _pushBack_(new_elt);
1615 } else {
1616 switch (place) {
1617 case location::BEFORE : return _insertBefore_(new_elt, ptr);
1618
1619 case location::AFTER : return _insertAfter_(new_elt, ptr);
1620
1621 default : GUM_ERROR(FatalError, "List insertion for this location unimplemented")
1622 }
1623 }
1624 }
1625
1626 // inserts a new bucket before or after the location pointed to by an
1627 // iterator
1628 template < typename Val >
1629 INLINE Val& List< Val >::_insert_(const const_iterator& iter,
1630 ListBucket< Val >* new_elt,
1631 location place) {
1632 // find the location around which the new element should be inserted
1633 ListBucket< Val >* ptr = iter._getBucket_();
1634
1635 if (ptr == nullptr) {
1636 // here, we are at the end of the list
1637 return _pushBack_(new_elt);
1638 } else {
1639 switch (place) {
1640 case location::BEFORE : return _insertBefore_(new_elt, ptr);
1641
1642 case location::AFTER : return _insertAfter_(new_elt, ptr);
1643
1644 default : GUM_ERROR(FatalError, "List insertion for this location unimplemented")
1645 }
1646 }
1647 }
1648
1649 // inserts a new element before or after the location pointed to by an
1650 // iterator
1651 template < typename Val >
1652 INLINE Val& List< Val >::insert(const const_iterator_safe& iter, const Val& val, location place) {
1653 // if the iterator does not point to the list, raise an exception
1654 if (iter._list_ != this) {
1655 GUM_ERROR(InvalidArgument, "the iterator does not point to the correct list")
1656 }
1657
1658 return _insert_(iter, _createBucket_(val), place);
1659 }
1660
1661 // inserts a new element before or after the location pointed to by an
1662 // iterator
1663 template < typename Val >
1664 INLINE Val& List< Val >::insert(const const_iterator_safe& iter, Val&& val, location place) {
1665 // if the iterator does not point to the list, raise an exception
1666 if (iter._list_ != this) {
1667 GUM_ERROR(InvalidArgument, "the iterator does not point to the correct list")
1668 }
1669
1670 return _insert_(iter, _createBucket_(std::move(val)), place);
1671 }
1672
1673 // inserts a new element before or after the location pointed to by an
1674 // iterator
1675 template < typename Val >
1676 INLINE Val& List< Val >::insert(const const_iterator& iter, const Val& val, location place) {
1677 return _insert_(iter, _createBucket_(val), place);
1678 }
1679
1680 // inserts a new element before or after the location pointed to by an
1681 // iterator
1682 template < typename Val >
1683 INLINE Val& List< Val >::insert(const const_iterator& iter, Val&& val, location place) {
1684 return _insert_(iter, _createBucket_(std::move(val)), place);
1685 }
1686
1687 // emplace a new element before a given iterator
1688 template < typename Val >
1689 template < typename... Args >
1690 INLINE Val& List< Val >::emplace(const const_iterator& iter, Args&&... args) {
1691 return _insert_(iter, _createEmplaceBucket_(std::forward< Args >(args)...), location::BEFORE);
1692 }
1693
1694 // emplace a new element before a given iterator
1695 template < typename Val >
1696 template < typename... Args >
1697 INLINE Val& List< Val >::emplace(const const_iterator_safe& iter, Args&&... args) {
1698 return _insert_(iter, _createEmplaceBucket_(std::forward< Args >(args)...), location::BEFORE);
1699 }
1700
1701 // returns a reference to first element of a list
1702 template < typename Val >
1703 INLINE Val& List< Val >::front() const {
1704 if (_nb_elements_ == Size(0)) { GUM_ERROR(NotFound, "not enough elements in the chained list") }
1705
1706 return _deb_list_->_val_;
1707 }
1708
1709 // returns a reference to last element of a list
1710 template < typename Val >
1711 INLINE Val& List< Val >::back() const {
1712 if (_nb_elements_ == Size(0)) { GUM_ERROR(NotFound, "not enough elements in the chained list") }
1713
1714 return _end_list_->_val_;
1715 }
1716
1717 // returns the number of elements in the list.
1718 template < typename Val >
1719 INLINE Size List< Val >::size() const noexcept {
1720 return _nb_elements_;
1721 }
1722
1723 // checks whether there exists a given element in the list.
1724 template < typename Val >
1725 INLINE bool List< Val >::exists(const Val& val) const {
1726 for (ListBucket< Val >* ptr = _deb_list_; ptr != nullptr; ptr = ptr->_next_)
1727 if (ptr->_val_ == val) return true;
1728
1729 return false;
1730 }
1731
1732 // suppresses a given bucket from a chained list.
1733 template < typename Val >
1735 // perform deletion only if there is a bucket to remove
1736 if (bucket != nullptr) {
1737 // update the iterators pointing on this element
1738 for (const auto ptr_iter: _safe_iterators_) {
1739 if (ptr_iter->_bucket_ == bucket) {
1740 ptr_iter->_next_current_bucket_ = bucket->_prev_;
1741 ptr_iter->_prev_current_bucket_ = bucket->_next_;
1742 ptr_iter->_bucket_ = nullptr;
1743 ptr_iter->_null_pointing_ = true;
1744 } else {
1745 if (ptr_iter->_null_pointing_) {
1746 if (ptr_iter->_next_current_bucket_ == bucket)
1747 ptr_iter->_next_current_bucket_ = bucket->_prev_;
1748
1749 if (ptr_iter->_prev_current_bucket_ == bucket)
1750 ptr_iter->_prev_current_bucket_ = bucket->_next_;
1751 }
1752 }
1753 }
1754
1755 // set properly the begin and end of the chained list (the other chainings
1756 // will be performed by operator delete)
1757 if (bucket->_prev_ == nullptr) _deb_list_ = bucket->_next_;
1758 else bucket->_prev_->_next_ = bucket->_next_;
1759
1760 if (bucket->_next_ == nullptr) _end_list_ = bucket->_prev_;
1761 else bucket->_next_->_prev_ = bucket->_prev_;
1762
1763 // remove the current element src the list
1764 delete bucket;
1765
1766 --_nb_elements_;
1767 }
1768 }
1769
1770 // erases the ith element of the List (the first one is in position 0)
1771 template < typename Val >
1772 INLINE void List< Val >::erase(Size i) {
1773 if (i >= _nb_elements_) return;
1774
1775 // erase the ith bucket
1777 }
1778
1779 // erases the element of the List pointed to by the iterator
1780 template < typename Val >
1781 INLINE void List< Val >::erase(const iterator_safe& iter) {
1782 _erase_(iter._getBucket_());
1783 }
1784
1785 // erases the element of the List pointed to by the iterator
1786 template < typename Val >
1787 INLINE void List< Val >::erase(const const_iterator_safe& iter) {
1788 _erase_(iter._getBucket_());
1789 }
1790
1791 // returns the bucket corresponding to a given value.
1792 template < typename Val >
1793 INLINE ListBucket< Val >* List< Val >::_getBucket_(const Val& val) const noexcept {
1794 for (ListBucket< Val >* ptr = _deb_list_; ptr != nullptr; ptr = ptr->_next_)
1795 if (ptr->_val_ == val) return ptr;
1796
1797 return nullptr;
1798 }
1799
1800 // erases the first element encountered with a given value
1801 template < typename Val >
1802 INLINE void List< Val >::eraseByVal(const Val& val) {
1803 _erase_(_getBucket_(val));
1804 }
1805
1806 // erases all the elements encountered with a given value
1807 template < typename Val >
1808 INLINE void List< Val >::eraseAllVal(const Val& val) {
1809 for (ListBucket< Val >*iter = _deb_list_, *next_bucket = nullptr; iter != nullptr;
1810 iter = next_bucket) {
1811 next_bucket = iter->_next_;
1812
1813 if (val == iter->_val_) _erase_(iter);
1814 }
1815 }
1816
1817 // removes the last element of a List
1818 template < typename Val >
1819 INLINE void List< Val >::popBack() {
1821 }
1822
1823 // removes the first element of a List
1824 template < typename Val >
1827 }
1828
1829 // returns a boolean indicating whether the chained list is empty
1830 template < typename Val >
1831 INLINE bool List< Val >::empty() const noexcept {
1832 return (_nb_elements_ == Size(0));
1833 }
1834
1835 // displays the content of a chained list
1836 template < typename Val >
1837 std::string List< Val >::toString() const {
1838 bool deja = false;
1839 std::stringstream stream;
1840 stream << "[";
1841
1842 for (ListBucket< Val >* ptr = _deb_list_; ptr != nullptr; ptr = ptr->_next_, deja = true) {
1843 if (deja) stream << " --> ";
1844
1845 stream << ptr->_val_;
1846 }
1847
1848 stream << "]";
1849
1850 return stream.str();
1851 }
1852
1853 // creates a list of mountains src a list of val
1854 template < typename Val >
1855 template < typename Mount >
1856 List< Mount > List< Val >::map(Mount (*f)(Val)) const {
1857 // create a new empty list
1858 List< Mount > list;
1859
1860 // fill the new list
1861 for (const_iterator iter = begin(); iter != end(); ++iter) {
1862 list.pushBack(f(*iter));
1863 }
1864
1865 return list;
1866 }
1867
1868 // creates a list of mountains src a list of val
1869 template < typename Val >
1870 template < typename Mount >
1871 List< Mount > List< Val >::map(Mount (*f)(Val&)) const {
1872 // create a new empty list
1873 List< Mount > list;
1874
1875 // fill the new list
1876 for (const_iterator iter = begin(); iter != end(); ++iter) {
1877 list.pushBack(f(*iter));
1878 }
1879
1880 return list;
1881 }
1882
1883 // creates a list of mountains src a list of val
1884 template < typename Val >
1885 template < typename Mount >
1886 List< Mount > List< Val >::map(Mount (*f)(const Val&)) const {
1887 // create a new empty list
1888 List< Mount > list;
1889
1890 // fill the new list
1891 for (const_iterator iter = begin(); iter != end(); ++iter) {
1892 list.pushBack(f(*iter));
1893 }
1894
1895 return list;
1896 }
1897
1898 // creates a list of mountains with a given value src a list of val
1899 template < typename Val >
1900 template < typename Mount >
1901 List< Mount > List< Val >::map(const Mount& mount) const {
1902 // create a new empty list
1903 List< Mount > list;
1904
1905 // fill the new list
1906 for (Size i = Size(0); i < _nb_elements_; ++i)
1907 list.pushBack(mount);
1908
1909 return list;
1910 }
1911
1912 // creates and insert a new element at the end of the list (alias of
1913 // pushBack).
1914 template < typename Val >
1915 INLINE Val& List< Val >::operator+=(const Val& val) {
1916 return pushBack(val);
1917 }
1918
1919 // creates and insert a new element at the end of the list (alias of
1920 // pushBack).
1921 template < typename Val >
1922 INLINE Val& List< Val >::operator+=(Val&& val) {
1923 return pushBack(std::move(val));
1924 }
1925
1926 // checks whether two lists are identical (same elements in the same order)
1927 template < typename Val >
1928 INLINE bool List< Val >::operator==(const List< Val >& src) const {
1929 // check if the two lists have at least the same number of elements
1930 if (_nb_elements_ != src._nb_elements_) return false;
1931
1932 // parse the two lists
1933 for (ListBucket< Val >*iter1 = _deb_list_, *iter2 = src._deb_list_; iter1 != nullptr;
1934 iter1 = iter1->_next_, iter2 = iter2->_next_)
1935 if (*iter1 != *iter2) return false;
1936
1937 return true;
1938 }
1939
1940 // checks whether two lists are different (different elements or orders)
1941 template < typename Val >
1942 INLINE bool List< Val >::operator!=(const List< Val >& src) const {
1943 return !operator==(src);
1944 }
1945
1946 // returns the ith element in the current chained list.
1947 template < typename Val >
1948 INLINE Val& List< Val >::operator[](const Size i) {
1949 // check if we can return the element we ask for
1950 if (i >= _nb_elements_) { GUM_ERROR(NotFound, "not enough elements in the chained list") }
1951
1952 return **_getIthBucket_(i);
1953 }
1954
1955 // returns the ith element in the current chained list.
1956 template < typename Val >
1957 INLINE const Val& List< Val >::operator[](const Size i) const {
1958 // check if we can return the element we ask for
1959 if (i >= _nb_elements_) { GUM_ERROR(NotFound, "not enough elements in the chained list") }
1960
1961 return **_getIthBucket_(i);
1962 }
1963
1964 // replace the current list with another one
1965 template < typename Val >
1966 INLINE void List< Val >::swap(List& other_list) {
1967 std::swap(_deb_list_, other_list._deb_list_);
1968 std::swap(_end_list_, other_list._end_list_);
1969 std::swap(_nb_elements_, other_list._nb_elements_);
1970 std::swap(_safe_iterators_, other_list._safe_iterators_);
1971 }
1972
1973 // A \c << operator for List
1974 template < typename Val >
1975 std::ostream& operator<<(std::ostream& stream, const List< Val >& list) {
1976 stream << list.toString();
1977 return stream;
1978 }
1979
1980} /* namespace gum */
Exception : fatal (unknown ?) error.
Exception: at least one argument passed to a function is not what was expected.
Bucket for a chained list.
Definition list.h:114
Val _val_
Val is the value contained in the box.
Definition list.h:257
INLINE ListBucket(typename ListBucket< gum::Instantiation * >::Emplace, Args &&... args)
Definition list_tpl.h:78
const ListBucket< Val > * next() const noexcept
Returns the bucket toward the next element.
Definition list_tpl.h:136
ListBucket< Val > * _next_
Chaining toward the adjacent elements.
Definition list.h:253
const ListBucket< Val > * previous() const noexcept
Returns the bucket toward the preceding element.
Definition list_tpl.h:142
bool operator==(const ListBucket< Val > &src) const
Equality check.
Definition list_tpl.h:112
ListBucket< Val > & operator=(const ListBucket< Val > &src)
Copy operator.
Definition list_tpl.h:93
ListBucket()=delete
Removes empty constructor.
~ListBucket()
Class destructor.
Definition list_tpl.h:105
Val & operator*() noexcept
Dereferencing operator.
Definition list_tpl.h:130
Emplace
C dummy type for the emplace constructor.
Definition list.h:121
ListBucket< Val > * _prev_
Chaining toward the adjacent elements.
Definition list.h:252
bool operator!=(const ListBucket< Val > &src) const
Inequality check.
Definition list_tpl.h:118
Safe const iterators for Lists.
Definition list.h:2006
bool operator==(const ListConstIteratorSafe< Val > &src) const
Checks whether two iterators point toward the same elements.
Definition list_tpl.h:926
ListConstIteratorSafe< Val > operator+(difference_type i) noexcept
Returns a new iterator pointing to i further elements in the gum::List.
Definition list_tpl.h:902
void _removeFromSafeList_() const
Remove the iterator for its list' safe iterators list.
Definition list_tpl.h:594
ListBucket< Val > * _bucket_
The bucket in the chained list pointed to by the iterator.
Definition list.h:2233
bool isEnd() const
Returns a bool indicating whether the iterator points to the end of the list.
Definition list_tpl.h:728
std::ptrdiff_t difference_type
Types for STL compliance.
Definition list.h:2016
const Val * operator->() const
Dereferences the value pointed to by the iterator.
Definition list_tpl.h:934
ListConstIteratorSafe< Val > & _opPlus_(Size i) noexcept
Makes the iterator point to the next element in the List.
Definition list_tpl.h:809
ListConstIteratorSafe< Val > & operator-=(difference_type i) noexcept
Makes the iterator point to i elements befor in the List.
Definition list_tpl.h:892
ListConstIteratorSafe< Val > & operator--() noexcept
Makes the iterator point to the preceding element in the List.
Definition list_tpl.h:856
ListConstIteratorSafe< Val > operator-(difference_type i) noexcept
Returns a new iterator pointing to i preceding elements in the gum::List.
Definition list_tpl.h:909
ListConstIteratorSafe< Val > & operator++() noexcept
Makes the iterator point to the next element in the List.
Definition list_tpl.h:736
~ListConstIteratorSafe()
Class Desctructor.
Definition list_tpl.h:693
ListBucket< Val > * _getBucket_() const noexcept
Returns the bucket the iterator is pointing to.
Definition list_tpl.h:703
friend class List< Val >
class List must be a friend because it uses the getBucket method to speed up some processes.
Definition list.h:2225
ListConstIteratorSafe< Val > & operator=(const ListConstIteratorSafe< Val > &src)
Copy operator.
Definition list_tpl.h:609
ListBucket< Val > * _next_current_bucket_
The bucket we should start from when we are pointing on a deleted bucket and we decide to do a ++.
Definition list.h:2237
ListBucket< Val > * _prev_current_bucket_
The bucket we should start from when we are pointing on a deleted bucket and we decide to do a –.
Definition list.h:2241
bool operator!=(const ListConstIteratorSafe< Val > &src) const
Checks whether two iterators point toward different elements.
Definition list_tpl.h:917
ListConstIteratorSafe() noexcept
Default constructor.
Definition list_tpl.h:509
const Val & operator*() const
Gives access to the content of the iterator.
Definition list_tpl.h:941
void setToEnd()
Positions the iterator to the end of the list.
Definition list_tpl.h:721
const List< Val > * _list_
The list the iterator is pointing to.
Definition list.h:2230
ListConstIteratorSafe< Val > & _opMinus_(Size i) noexcept
Makes the iterator point to i elements before in the List.
Definition list_tpl.h:772
void clear()
Makes the iterator point toward nothing.
Definition list_tpl.h:709
bool _null_pointing_
Indicates whether the bucket the iterator points to has been deleted.
Definition list.h:2244
ListConstIteratorSafe< Val > & operator+=(difference_type i) noexcept
Makes the iterator point to i elements further in the List.
Definition list_tpl.h:846
Unsafe but fast const iterators for Lists.
Definition list.h:1450
ListBucket< Val > * _bucket_
The bucket in the chained list pointed to by the iterator.
Definition list.h:1672
std::ptrdiff_t difference_type
Types for STL compliance.
Definition list.h:1460
ListConstIterator< Val > & operator+=(difference_type i) noexcept
Makes the iterator point to i elements further in the List.
Definition list_tpl.h:272
bool isEnd() const noexcept
Returns a bool indicating whether the iterator points to the end of the list.
Definition list_tpl.h:256
ListConstIterator< Val > & operator=(const ListConstIterator< Val > &src) noexcept
Copy operator.
Definition list_tpl.h:217
ListBucket< Val > * _getBucket_() const noexcept
Returns the bucket the iterator is pointing to.
Definition list_tpl.h:237
ListConstIterator< Val > & operator--() noexcept
Makes the iterator point to the preceding element in the List.
Definition list_tpl.h:284
ListConstIterator< Val > & operator-=(difference_type i) noexcept
Makes the iterator point to i elements befor in the List.
Definition list_tpl.h:294
bool operator==(const ListConstIterator< Val > &src) const noexcept
Checks whether two iterators point toward the same elements.
Definition list_tpl.h:328
const Val * operator->() const
Dereferences the value pointed to by the iterator.
Definition list_tpl.h:334
void clear() noexcept
Makes the iterator point toward nothing.
Definition list_tpl.h:243
ListConstIterator< Val > operator-(difference_type i) noexcept
Returns a new iterator pointing to i preceding elements in the gum::List.
Definition list_tpl.h:313
friend class List< Val >
Class List must be a friend because it uses the getBucket method to speed up some processes.
Definition list.h:1669
~ListConstIterator() noexcept
Class Desctructor.
Definition list_tpl.h:209
ListConstIterator() noexcept
Default constructor.
Definition list_tpl.h:154
ListConstIterator< Val > operator+(difference_type i) noexcept
Returns a new iterator pointing to i further elements in the gum::List.
Definition list_tpl.h:306
bool operator!=(const ListConstIterator< Val > &src) const noexcept
Checks whether two iterators point toward different elements.
Definition list_tpl.h:321
void setToEnd() noexcept
Positions the iterator to the end of the list.
Definition list_tpl.h:249
const Val & operator*() const
Gives access to the content of the iterator.
Definition list_tpl.h:341
ListConstIterator< Val > & operator++() noexcept
Makes the iterator point to the next element in the List.
Definition list_tpl.h:262
Safe iterators for Lists.
Definition list.h:2319
std::ptrdiff_t difference_type
Types for STL compliance.
Definition list.h:2329
ListIteratorSafe< Val > & operator--() noexcept
Makes the iterator point to the preceding element in the List.
Definition list_tpl.h:1056
ListIteratorSafe() noexcept
Default constructor.
Definition list_tpl.h:967
ListIteratorSafe< Val > operator+(difference_type i) noexcept
Returns a new iterator pointing to i further elements in the gum::List.
Definition list_tpl.h:1071
~ListIteratorSafe()
Class Desctructor.
Definition list_tpl.h:1023
ListIteratorSafe< Val > & operator=(const ListIteratorSafe< Val > &src)
Copy operator.
Definition list_tpl.h:1004
Val * operator->()
Dereferences the value pointed to by the iterator.
Definition list_tpl.h:1085
bool operator!=(const ListIteratorSafe< Val > &src) const
Checks whether two iterators point toward different elements.
Definition list_tpl.h:1035
bool operator==(const ListIteratorSafe< Val > &src) const
Checks whether two iterators point toward the same elements.
Definition list_tpl.h:1029
ListIteratorSafe< Val > & operator-=(difference_type i) noexcept
Makes the iterator point to i elements befor in the List.
Definition list_tpl.h:1063
Val & operator*()
Gives access to the content of the iterator.
Definition list_tpl.h:1097
ListIteratorSafe< Val > & operator++() noexcept
Makes the iterator point to the next element in the List.
Definition list_tpl.h:1041
ListIteratorSafe< Val > operator-(difference_type i) noexcept
Returns a new iterator pointing to i preceding elements in the gum::List.
Definition list_tpl.h:1078
ListIteratorSafe< Val > & operator+=(difference_type i) noexcept
Makes the iterator point to i elements further in the List.
Definition list_tpl.h:1048
Unsafe but fast iterators for Lists.
Definition list.h:1737
ListIterator< Val > & operator-=(difference_type i) noexcept
Makes the iterator point to i elements befor in the List.
Definition list_tpl.h:458
ListIterator< Val > & operator--() noexcept
Makes the iterator point to the preceding element in the List.
Definition list_tpl.h:450
bool operator!=(const ListIterator< Val > &src) const noexcept
Checks whether two iterators point toward different elements.
Definition list_tpl.h:429
std::ptrdiff_t difference_type
Types for STL compliance.
Definition list.h:1747
ListIterator< Val > & operator=(const ListIterator< Val > &src) noexcept
Copy operator.
Definition list_tpl.h:401
ListIterator< Val > operator-(difference_type i) noexcept
Returns a new iterator pointing to i preceding elements in the gum::List.
Definition list_tpl.h:473
const Val * operator->() const
Dereferences the value pointed to by the iterator.
Definition list_tpl.h:485
ListIterator< Val > operator+(difference_type i) noexcept
Returns a new iterator pointing to i further elements in the gum::List.
Definition list_tpl.h:466
~ListIterator() noexcept
Class destructor.
Definition list_tpl.h:417
ListIterator() noexcept
Default constructor.
Definition list_tpl.h:365
ListIterator< Val > & operator+=(difference_type i) noexcept
Makes the iterator point to i elements further in the List.
Definition list_tpl.h:443
ListIterator< Val > & operator++() noexcept
Makes the iterator point to the next element in the List.
Definition list_tpl.h:435
bool operator==(const ListIterator< Val > &src) const noexcept
Checks whether two iterators point toward the same elements.
Definition list_tpl.h:423
const Val & operator*() const
Gives access to the content of the iterator.
Definition list_tpl.h:497
Generic doubly linked lists.
Definition list.h:379
Val & emplaceFront(Args &&... args)
Emplace elements at the beginning of the chained list.
std::vector< const_iterator_safe * > _safe_iterators_
The list of "safe" iterators attached to the list.
Definition list.h:1263
void eraseByVal(const Val &val)
erases the first element encountered with a given value.
Definition list_tpl.h:1802
ListBucket< Val > * _getBucket_(const Val &val) const noexcept
Returns the bucket corresponding to a given value.
Definition list_tpl.h:1793
const_iterator cbegin() const
Returns an unsafe const iterator pointing to the beginning of the List.
Definition list_tpl.h:1354
const_iterator crbegin() const
Returns an unsafe const iterator pointing to the last element of the List.
Definition list_tpl.h:1386
bool exists(const Val &val) const
Checks whether there exists a given element in the list.
Definition list_tpl.h:1725
const iterator_safe & endSafe() noexcept
Returns a safe iterator pointing to the end of the List.
Definition list_tpl.h:1288
Val & front() const
Returns a reference to first element of a list, if any.
Definition list_tpl.h:1703
ListBucket< Val > * _getIthBucket_(Size i) const noexcept
Returns the bucket corresponding to the ith position in the list.
Definition list_tpl.h:1527
Val & operator+=(const Val &val)
Inserts a new element at the end of the list (alias of pushBack).
Definition list_tpl.h:1915
ListConstIteratorSafe< Val > const_iterator_safe
Types for STL compliance.
Definition list.h:393
bool operator!=(const List< Val > &src) const
Checks whether two lists are different (different elements or orders).
Definition list_tpl.h:1942
INLINE ListBucket< gum::Instantiation * > * _createEmplaceBucket_(Args &&... args) const
Definition list_tpl.h:1420
friend class ListConstIterator< Val >
ListIterator should be a friend to optimize access to elements.
Definition list.h:1390
const const_iterator_safe & crendSafe() const noexcept
Return a safe const iterator pointing just before the beginning of the List.
Definition list_tpl.h:1312
location
Locations around iterators where insertions of new elements can take / place.
Definition list.h:398
Val & push_front(Args &&... args)
An alias for pushFront used for STL compliance.
Val & pushFront(const Val &val)
Inserts a new element (a copy) at the beginning of the chained list.
Definition list_tpl.h:1462
List()
A basic constructor that creates an empty list.
Definition list_tpl.h:1174
void popBack()
Removes the last element of a List, if any.
Definition list_tpl.h:1819
Size size() const noexcept
Returns the number of elements in the list.
Definition list_tpl.h:1719
void clear()
Deletes all the elements of a chained list.
Definition list_tpl.h:1154
friend class ListIteratorSafe< Val >
Definition list.h:1391
friend class ListConstIteratorSafe< Val >
Definition list.h:1392
std::string toString() const
Converts a list into a string.
Definition list_tpl.h:1837
List< Val > & operator=(const List< Val > &src)
Copy operator.
Definition list_tpl.h:1238
ListBucket< Val > * _createEmplaceBucket_(Args &&... args) const
Create an emplace bucket.
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
Definition list_tpl.h:1831
void eraseAllVal(const Val &val)
erases all the elements encountered with a given value
Definition list_tpl.h:1808
iterator_safe rbeginSafe()
Returns a safe iterator pointing to the last element of the List.
Definition list_tpl.h:1379
List< Mount > map(Mount(*f)(Val)) const
Creates a list of mountains from a list of val.
Definition list_tpl.h:1856
void _erase_(ListBucket< Val > *bucket)
Removes an element from a chained list.
Definition list_tpl.h:1734
iterator rbegin()
Returns an unsafe iterator pointing to the last element of the List.
Definition list_tpl.h:1393
const iterator & rend() noexcept
Returns an unsafe iterator pointing just before the beginning of the List.
Definition list_tpl.h:1330
Val & push_back(Args &&... args)
An alias for pushBack used for STL compliance.
const const_iterator & cend() const noexcept
Returns an unsafe const iterator pointing to the end of the List.
Definition list_tpl.h:1294
const iterator_safe & rendSafe() noexcept
Returns a safe iterator pointing just before the beginning of the List.
Definition list_tpl.h:1318
void popFront()
Removes the first element of a List, if any.
Definition list_tpl.h:1825
Val & emplaceBack(Args &&... args)
Emplace elements at the end of the chained list.
const const_iterator & crend() const noexcept
Returns an unsafe const iterator pointing just before the beginning of the List.
Definition list_tpl.h:1324
Val & _insertBefore_(ListBucket< Val > *new_elt, ListBucket< Val > *current_elt)
Insert a new bucket before another one.
Definition list_tpl.h:1541
const_iterator_safe crbeginSafe() const
Returns a safe const iterator pointing to the last element of the List.
Definition list_tpl.h:1372
ListBucket< Val > * _deb_list_
A pointer on the first element of the chained list.
Definition list.h:1254
Val & operator[](const Size i)
Returns the ith element in the current chained list.
Definition list_tpl.h:1948
~List()
Class destructor.
Definition list_tpl.h:1227
const const_iterator_safe & cendSafe() const noexcept
Returns a safe const iterator pointing to the end of the List.
Definition list_tpl.h:1282
Val & _insertAfter_(ListBucket< Val > *new_elt, ListBucket< Val > *current_elt)
Insert a new bucket after another one.
Definition list_tpl.h:1559
ListIteratorSafe< Val > iterator_safe
Types for STL compliance.
Definition list.h:392
const iterator & end() noexcept
Returns an unsafe iterator pointing to the end of the List.
Definition list_tpl.h:1300
iterator_safe beginSafe()
Returns a safe iterator pointing to the beginning of the List.
Definition list_tpl.h:1348
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
Definition list_tpl.h:1515
iterator begin()
Returns an unsafe iterator pointing to the beginning of the List.
Definition list_tpl.h:1360
Size _nb_elements_
The number of elements in the list.
Definition list.h:1260
const_iterator_safe cbeginSafe() const
Returns a safe const iterator pointing to the beginning of the List.
Definition list_tpl.h:1342
void _copy_elements_(const List< Val > &src)
A function used to perform copies of elements of Lists.
Definition list_tpl.h:1115
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
Definition list_tpl.h:1488
Val & _pushFront_(ListBucket< Val > *new_elt)
Insert a bucket at the front of the list.
Definition list_tpl.h:1427
Val & emplace(const const_iterator &iter, Args &&... args)
Emplace a new element before a given iterator.
Val & back() const
Returns a reference to last element of a list, if any.
Definition list_tpl.h:1711
void erase(Size i)
Erases the ith element of the List (the first one is in position 0).
Definition list_tpl.h:1772
Val & _pushBack_(ListBucket< Val > *new_elt)
Insert a bucket at the end of the list.
Definition list_tpl.h:1444
Val & _insert_(const const_iterator_safe &iter, ListBucket< Val > *new_elt, location place)
Inserts a new bucket before or after the location pointed to by an iterator.
Definition list_tpl.h:1596
void swap(List &other_list)
Swap the current list with another one.
Definition list_tpl.h:1966
ListConstIterator< Val > const_iterator
Types for STL compliance.
Definition list.h:391
ListBucket< Val > * _createBucket_(const Val &val) const
Create a new bucket with a given value.
Definition list_tpl.h:1407
ListBucket< Val > * _end_list_
A pointer on the last element of the chained list.
Definition list.h:1257
bool operator==(const List< Val > &src) const
Checks whether two lists are identical (same elements in the same order).
Definition list_tpl.h:1928
Exception : the element we looked for cannot be found.
Exception : generic error on iterator.
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
Generic class for manipulating lists.
#define GUM_DEFAULT_ITERATOR_NUMBER
Definition list.h:64
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree
Definition AVLTree.h:913
ListConstIterator< Val >::difference_type operator-(const ListConstIterator< Val > &iter1, const ListConstIterator< Val > &iter2)
For STL compliance, a distance operator.
Definition list_tpl.h:349
bool operator==(const HashTableIteratorSafe< Key, Val > &from) const noexcept
Checks whether two iterators are pointing toward equal elements.
STL namespace.