aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
list.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Generic class for manipulating lists.
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  *
28  */
29 #ifndef GUM_LIST_H
30 #define GUM_LIST_H
31 
32 #include <cstddef>
33 #include <initializer_list>
34 #include <iostream>
35 #include <sstream>
36 #include <vector>
37 
38 #include <agrum/agrum.h>
39 #include <agrum/tools/core/refPtr.h>
40 
41 #define GUM_DEFAULT_ITERATOR_NUMBER 4
42 
43 namespace gum {
44 
45  // ==============================================================================
46  // templates provided by this header
47  // ==============================================================================
48 
49 #ifndef DOXYGEN_SHOULD_SKIP_THIS
50 
51  template < typename Val >
52  class ListBucket;
53  template < typename Val >
54  class ListIterator;
55  template < typename Val >
56  class ListConstIterator;
57  template < typename Val >
58  class ListIteratorSafe;
59  template < typename Val >
60  class ListConstIteratorSafe;
61  template < typename Val, typename Alloc >
62  class List;
63 
64 #endif // DOXYGEN_SHOULD_SKIP_THIS
65 
66 #ifndef SWIG // SWIG cannot read these lines
67  /// an << operator for List
68  template < typename Val, typename Alloc >
69  std::ostream& operator<<(std::ostream& stream, const List< Val, Alloc >& list);
70 #endif // SWIG
71 
72 #ifndef DOXYGEN_SHOULD_SKIP_THIS
73  // list_end__ is a 'pseudo static' iterator that represents both end and rend
74  // iterators for all Lists (whatever their type). This global variable
75  // avoids creating the same iterators within every List instance (this would
76  // be quite inefficient as end and rend are precisely identical for all
77  // lists).
78  // The type of list_end__ is a pointer to void because C++ allows pointers to
79  // void to be cast into pointers to other types (and conversely). This avoids
80  // the weird strict-aliasing rule warning
81  extern const void* const list_end_safe__;
82  extern const void* const list_end__;
83 #endif // DOXYGEN_SHOULD_SKIP_THIS
84 
85 
86  // ===========================================================================
87  // === BUCKETS: SINGLE ELEMENTS OF A CHAINED LIST ===
88  // ===========================================================================
89 
90  /**
91  * @class ListBucket
92  * @headerfile list.h <agrum/tools/core/list.h>
93  * @brief Bucket for a chained list.
94  * @ingroup list_group
95  *
96  * In aGrUM, each box of a chained list is called a bucket. Lists are doubly
97  * linked bucket lists so as to enable efficient rbegin/rend iterators.
98  *
99  * @warning Values stored in buckets are ALWAYS COPIES.
100  *
101  * @tparam Val The values type stored in the gum::ListBucket.
102  */
103  template < typename Val >
104  class ListBucket {
105  private:
106  /**
107  * @brief C dummy type for the emplace constructor.
108  *
109  * This type is used to prevent the list emplace (int) to compile.
110  */
111  enum class Emplace
112  { EMPLACE };
113 
114  public:
115  // ============================================================================
116  /// @name Constructors / Destructors
117  // ============================================================================
118  ///@{
119 
120  /// Removes empty constructor.
121  ListBucket() = delete;
122 
123  /**
124  * @brief Default constructor.
125  * @param v The value stored in the gum::ListBucket.
126  */
127  explicit ListBucket(const Val& v);
128 
129  /**
130  * @brief Constructor for Val rvalues.
131  * @param v The value stored in the gum::ListBucket.
132  */
133  explicit ListBucket(Val&& v) noexcept;
134 
135  /**
136  * @brief Emplace (universal) constructor.
137  * @tparam Args The emplace values type.
138  * @param args The emplace values.
139  */
140  template < typename... Args >
141  explicit ListBucket(Emplace, Args&&... args);
142 
143  /**
144  * @brief Copy constructor.
145  * @param src The gum::ListBucket to copy.
146  */
147  ListBucket(const ListBucket< Val >& src);
148 
149  /**
150  * @brief Move constructor should be useless.
151  * @param src The gum::ListBucket to move.
152  */
153  ListBucket(ListBucket< Val >&& src) = delete;
154 
155  /**
156  * @brief Class destructor.
157  *
158  * @warning during its deletion, the bucket takes care of properly
159  * rechaining the chained list. However, it has no knowledge about the
160  * variables that keep track of the beginning/end of the chained list,
161  * hence it cannot update them properly. This should be done by the List
162  * itself.
163  */
164  ~ListBucket();
165 
166  /// @}
167  // ============================================================================
168  /// @name Operators
169  // ============================================================================
170  /// @{
171 
172  /**
173  * @brief Copy operator.
174  * @param src The gum::ListBucket to copy.
175  * @return This gum::ListBucket.
176  */
177  ListBucket< Val >& operator=(const ListBucket< Val >& src);
178 
179  /**
180  * @brief Move operator.
181  * @param src The gum::ListBucket to move.
182  * @return This gum::ListBucket.
183  */
184  ListBucket< Val >& operator=(ListBucket< Val >&& src) = delete;
185 
186  /**
187  * @brief Equality check.
188  * @param src The gum::ListBucket to test for equality.
189  * @return Returns true if src and this gum::ListBucket are equal.
190  */
191  bool operator==(const ListBucket< Val >& src) const;
192 
193  /**
194  * @brief Inequality check.
195  * @param src The gum::ListBucket to test for inequality.
196  * @return Returns true if src and this gum::ListBucket are not equal.
197  */
198  bool operator!=(const ListBucket< Val >& src) const;
199 
200  /// @}
201  // ============================================================================
202  /// @name Accessors / Modifiers
203  // ============================================================================
204  /// @{
205 
206  /**
207  * @brief Dereferencing operator.
208  * @return The value stored in this gum::ListBucket.
209  */
210  Val& operator*() noexcept;
211 
212  /**
213  * @brief Dereferencing operator.
214  * @return The value stored in this gum::ListBucket.
215  */
216  const Val& operator*() const noexcept;
217 
218  /**
219  * @brief Returns the bucket toward the next element.
220  * @return Returns the bucket toward the next element.
221  */
222  const ListBucket< Val >* next() const noexcept;
223 
224  /**
225  * @brief Returns the bucket toward the preceding element.
226  * @return Returns the bucket toward the preceding element.
227  */
228  const ListBucket< Val >* previous() const noexcept;
229 
230  /// @}
231 
232  private:
233  /// All the list containers and iterators should be able to access the
234  /// buckets.
235  template < typename T, typename A >
236  friend class List;
237  friend class ListIterator< Val >;
238  friend class ListConstIterator< Val >;
239  friend class ListIteratorSafe< Val >;
240  friend class ListConstIteratorSafe< Val >;
241 
242  /// @{
243  /// Chaining toward the adjacent elements.
244  ListBucket< Val >* prev__{nullptr};
245  ListBucket< Val >* next__{nullptr};
246  /// @}
247 
248  /// Val is the value contained in the box.
249  Val val__;
250  };
251 
252  // ===========================================================================
253  // === GENERIC DOUBLY CHAINED LISTS ===
254  // ===========================================================================
255 
256  /**
257  * @class List
258  * @headerfile list.h <agrum/tools/core/list.h>
259  * @ingroup basicstruct_group
260  * @ingroup list_group
261  *
262  * @brief Generic doubly linked lists.
263  *
264  * List enables fast and safe manipulation of chained lists. Unless the
265  * elements are rvalues, the insertions of new elements into the lists are @b
266  * ALWAYS performed by copy, i.e., each time we add a new element X to the
267  * List, a copy of X is actually created and this very copy is stored into
268  * the list. For rvalues, move operations are performed.
269  *
270  * The List iterators are implemented so as to avoid segmentation faults when
271  * elements of the list are deleted while some safe iterators are pointing on
272  * them. Moreover they ensure that, when elements are removed from a List,
273  * iterators on that list will never access these elements (which is not the
274  * case for the iterators in the C++ standard library). Note that this
275  * guarantee is ensured at low cost as experimental results show that List
276  * and ListIterator are as efficient as their STL counterparts. However, this
277  * guarantee can hold only if List is aware of all of the iterators pointing
278  * to it: thus, when List erases one element, it can parse the list of its
279  * iterators and update those that point toward the now deleted element. When
280  * parsing elements without removing any element, you can use unsafe
281  * iterators instead of safe ones because they are slightly faster. But those
282  * will most certainly segfault if they perform some operations on deleted
283  * elements.
284  *
285  * @par Usage example:
286  * @code
287  * // creation of an empty list
288  * List<int> list1;
289  * List<int> list2 { 3, 4, 5 }; // initializer list
290  *
291  * // adding elements to the list
292  * list1.pushFront (23);
293  * list1.pushBack (10);
294  * list1 += 25;
295  * list1.insert (12);
296  *
297  * // getting the second element of the list
298  * cerr << "10 = " << list1[1] << endl;
299  *
300  * // getting the first and last elements
301  * cerr << "first = " << list1.front() << " last = " << list1.back() << endl;
302  *
303  * // get the number of elements in the list
304  * cerr << "number of elements = " << list1.size () << endl;
305  *
306  * // display the content of the list
307  * cerr << list1 << endl;
308  *
309  * // copy the list
310  * List<int> list2 = list1, list3;
311  * list3 = list1;
312  *
313  * // delete the second element from the list
314  * list1.erase (1);
315  *
316  * // delete the first and last elements
317  * list1.popFront ();
318  * list1.popBack ();
319  *
320  * // delete element whose value is 25
321  * list1.eraseByVal (25);
322  *
323  * // check whether the list is empty
324  * if (list1.empty()) cerr << "empty list" << endl;
325  *
326  * // remove all elements from the list
327  * list1.clear ();
328  *
329  * // parse all the elements of a list using unsafe iterators
330  * for (List<int>::iterator iter = list2.begin();
331  * iter != list2.end(); ++iter)
332  * cerr << *iter << endl;
333  * for (List<int>::iterator iter = list2.rbegin();
334  * iter != list2.rend(); --iter)
335  * cerr << *iter << endl;
336  * for (List<int>::const_iterator iter = list2.cbegin();
337  * iter != list2.cend(); ++iter)
338  * cerr << *iter << endl;
339  * for (List<int>::const_iterator iter = list2.crbegin();
340  * iter != list2.crend(); --iter)
341  * cerr << *iter << endl;
342  *
343  * // parse all the elements of a list using safe iterators
344  * for (List<int>::iterator_safe iter = list2.beginSafe();
345  * iter != list2.endSafe(); ++iter)
346  * cerr << *iter << endl;
347  * for (List<int>::iterator_safe iter = list2.rbeginSafe();
348  * iter != list2.rendSafe(); --iter)
349  * cerr << *iter << endl;
350  * for (List<int>::const_iterator_safe iter = list2.cbeginSafe();
351  * iter != list2.cendSafe(); ++iter)
352  * cerr << *iter << endl;
353  * for (List<int>::const_iterator_safe iter = list2.crbeginSafe();
354  * iter != list2.crendSafe(); --iter)
355  * cerr << *iter << endl;
356  *
357  * // use an iterator to point the element we wish to erase
358  * List<int>::iterator_safe iter = list2.beginSafe();
359  * List2.erase ( iter );
360  * List<int>::iterator iter2 = list2.begin() + 4; // 5th element of the list
361  * iter2 = iter + 4;
362  *
363  * // map a list into another list (assuming function f is defined as
364  * // float f (int x) { return (2.5 * x); } )
365  * List<float> flist = list2.map (f);
366  * @endcode
367  *
368  * @tparam Val The values type stored in the gum::List.
369  * @tparam Alloc The allocator for the values stored in the gum::List.
370  */
371  template < typename Val, typename Alloc = std::allocator< Val > >
372  class List {
373  public:
374  /// Types for STL compliance.
375  /// @{
376  using value_type = Val;
377  using reference = Val&;
378  using const_reference = const Val&;
379  using pointer = Val*;
380  using const_pointer = const Val*;
381  using size_type = Size;
382  using difference_type = std::ptrdiff_t;
383  using allocator_type = Alloc;
384  using iterator = ListIterator< Val >;
385  using const_iterator = ListConstIterator< Val >;
386  using iterator_safe = ListIteratorSafe< Val >;
387  using const_iterator_safe = ListConstIteratorSafe< Val >;
388  /// @}
389 
390  /// Type of the allocator for ListBuckets.
391  using BucketAllocator =
392  typename Alloc::template rebind< ListBucket< Val > >::other;
393 
394  /// Locations around iterators where insertions of new elements can take /
395  /// place.
396  enum class location
397  {
398  BEFORE,
399  AFTER
400  };
401 
402  // ============================================================================
403  /// @name Constructors / Destructors
404  // ============================================================================
405  /// @{
406 
407  /**
408  * @brief A basic constructor that creates an empty list.
409  */
410  List();
411 
412  /**
413  * @brief Copy constructor.
414  *
415  * The new list and that which is copied do not share their elements: the
416  * new list contains new instances of the values stored in the list to be
417  * copied. Of course if these values are pointers, the new values point
418  * toward the same elements. This constructor runs in linear time.
419  *
420  * @param src the list the contents of which is copied into the current one.
421  */
422  List(const List< Val, Alloc >& src);
423 
424  /**
425  * @brief Ceneralized copy constructor.
426  *
427  * The new list and that which is copied do not share their elements: the
428  * new list contains new instances of the values stored in the list to be
429  * copied. Of course if these values are pointers, the new values point
430  * toward the same elements. This constructor runs in linear time.
431  *
432  * @param src the list the contents of which is copied into the current one.
433  * @tparam OtherAlloc The other allocator.
434  */
435  template < typename OtherAlloc >
436  List(const List< Val, OtherAlloc >& src);
437 
438  /**
439  * @brief Move constructor.
440  * @param src The gum::List to move.
441  */
442  List(List< Val, Alloc >&& src);
443 
444  /**
445  * @brief Initializer_list constructor.
446  * @param list The initializer list.
447  */
448  List(std::initializer_list< Val > list);
449 
450  /**
451  * @brief Class destructor.
452  */
453  ~List();
454 
455  /// @}
456  // ============================================================================
457  /// @name Iterators
458  // ============================================================================
459  /// @{
460 
461  /**
462  * @brief Returns a safe const iterator pointing to the end of the List.
463  *
464  * Safe const iterators are const iterators whose state is updated by the
465  * list when the element they point to is erased. As such, in this case,
466  * they can throw an exception when we try to derefence them and they are
467  * able to perform a valid ++ or -- step
468  *
469  * @brief Returns a safe const iterator pointing to the end of the List.
470  */
471  const const_iterator_safe& cendSafe() const noexcept;
472 
473  /**
474  * @brief Returns a safe iterator pointing to the end of the List.
475  *
476  * Safe iterators are iterators whose state is updated by the list when the
477  * element they point to is erased. As such, in this case, they can throw
478  * an exception when we try to derefence them and they are able to perform
479  * a valid ++ or -- step.
480  *
481  * @brief Ceturns a safe iterator pointing to the end of the List.
482  */
483  const iterator_safe& endSafe() noexcept;
484 
485  /**
486  * @brief Return a safe const iterator pointing just before the beginning
487  * of the List.
488  *
489  * Safe const iterators are const iterators whose state is updated by the
490  * list when the element they point to is erased. As such, in this case,
491  * they can throw an exception when we try to derefence them and they are
492  * able to perform a valid ++ or -- step.
493  *
494  * @brief Return a safe const iterator pointing just before the beginning
495  * of the List.
496  */
497  const const_iterator_safe& crendSafe() const noexcept;
498 
499  /**
500  * @brief Returns a safe iterator pointing just before the beginning of the
501  * List.
502  *
503  * Safe iterators are iterators whose state is updated by the list when the
504  * element they point to is erased. As such, in this case, they can throw
505  * an exception when we try to derefence them and they are able to perform
506  * a valid ++ or -- step.
507  *
508  * @return Returns a safe iterator pointing just before the beginning of
509  * the List.
510  */
511  const iterator_safe& rendSafe() noexcept;
512 
513  /**
514  * @brief Returns a safe const iterator pointing to the beginning of the
515  * List.
516  *
517  * Safe const iterators are const iterators whose state is updated by the
518  * list when the element they point to is erased. As such, in this case,
519  * they can throw an exception when we try to derefence them and they are
520  * able to perform a valid ++ or -- step.
521  *
522  * @return Returns a safe const iterator pointing to the beginning of the
523  * List.
524  */
525  const_iterator_safe cbeginSafe() const;
526 
527  /**
528  * @brief Returns a safe iterator pointing to the beginning of the List.
529  *
530  * Safe iterators are iterators whose state is updated by the list when the
531  * element they point to is erased. As such, in this case, they can throw
532  * an exception when we try to derefence them and they are able to perform
533  * a valid ++ or -- step.
534  *
535  * @return Returns a safe iterator pointing to the beginning of the List.
536  */
537  iterator_safe beginSafe();
538 
539  /**
540  * @brief Returns a safe const iterator pointing to the last element of the
541  * List.
542  *
543  * Safe const iterators are const iterators whose state is updated by the
544  * list when the element they point to is erased. As such, in this case,
545  * they can throw an exception when we try to derefence them and they are
546  * able to perform a valid ++ or -- step.
547  *
548  * @return Returns a safe const iterator pointing to the last element of
549  * the List.
550  */
551  const_iterator_safe crbeginSafe() const;
552 
553  /**
554  * @brief Returns a safe iterator pointing to the last element of the List.
555  *
556  * Safe iterators are iterators whose state is updated by the list when the
557  * element they point to is erased. As such, in this case, they can throw
558  * an exception when we try to derefence them and they are able to perform
559  * a valid ++ or -- step.
560  *
561  * @return Returns a safe iterator pointing to the last element of the
562  * List.
563  */
564  iterator_safe rbeginSafe();
565 
566  /**
567  * @brief Returns an unsafe const iterator pointing to the end of the List.
568  *
569  * Unsafe const iterators are a little bit faster than safe const iterators
570  * and they consume less memory. However, if the element they point to is
571  * erased, their dereference or their increment/decrement will produce a
572  * mess, probably a segfault. You should use them only when performance is
573  * an issue and if you are sure that they will never point to an element
574  * erased.
575  *
576  * @brief Returns an unsafe const iterator pointing to the end of the List.
577  */
578  const const_iterator& cend() const noexcept;
579 
580  /**
581  * @brief Returns an unsafe iterator pointing to the end of the List.
582  *
583  * Unsafe iterators are a little bit faster than safe iterators and they
584  * consume less memory. However, if the element they point to is erased,
585  * their dereference or their increment/decrement will produce a mess,
586  * probably a segfault. You should use them only when performance is an
587  * issue and if you are sure that they will never point to an element
588  * erased.
589  *
590  * @return Returns an unsafe iterator pointing to the end of the List.
591  */
592  const iterator& end() noexcept;
593 
594  /**
595  * @brief Returns an unsafe const iterator pointing to the end of the List.
596  *
597  * Unsafe const iterators are a little bit faster than safe const iterators
598  * and they consume less memory. However, if the element they point to is
599  * erased, their dereference or their increment/decrement will produce a
600  * mess, probably a segfault. You should use them only when performance is
601  * an issue and if you are sure that they will never point to an element
602  * erased.
603  *
604  * @return Returns an unsafe const iterator pointing to the end of the
605  * List.
606  */
607  const const_iterator& end() const noexcept;
608 
609  /**
610  * @brief Returns an unsafe const iterator pointing just before the
611  * beginning of the List
612  *
613  * Unsafe const iterators are a little bit faster than safe const iterators
614  * and they consume less memory. However, if the element they point to is
615  * erased, their dereference or their increment/decrement will produce a
616  * mess, probably a segfault. You should use them only when performance is
617  * an issue and if you are sure that they will never point to an element
618  * erased.
619  *
620  * @return Returns an unsafe const iterator pointing just before the
621  * beginning of the List
622  */
623  const const_iterator& crend() const noexcept;
624 
625  /**
626  * @brief Returns an unsafe iterator pointing just before the beginning of
627  * the List.
628  *
629  * Unsafe iterators are a little bit faster than safe iterators and they
630  * consume less memory. However, if the element they point to is erased,
631  * their dereference or their increment/decrement will produce a mess,
632  * probably a segfault. You should use them only when performance is an
633  * issue and if you are sure that they will never point to an element
634  * erased.
635  *
636  * @brief Returns an unsafe iterator pointing just before the beginning of
637  * the List.
638  */
639  const iterator& rend() noexcept;
640 
641  /**
642  * @brief Returns an unsafe const iterator pointing just before the
643  * beginning of the List.
644  *
645  * Unsafe const iterators are a little bit faster than safe const iterators
646  * and they consume less memory. However, if the element they point to is
647  * erased, their dereference or their increment/decrement will produce a
648  * mess, probably a segfault. You should use them only when performance is
649  * an issue and if you are sure that they will never point to an element
650  * erased.
651  *
652  * @return Returns an unsafe const iterator pointing just before the
653  * beginning of the List.
654  */
655  const const_iterator& rend() const noexcept;
656 
657  /**
658  * @brief Returns an unsafe const iterator pointing to the beginning of the
659  * List.
660  *
661  * Unsafe const iterators are a little bit faster than safe const iterators
662  * and they consume less memory. However, if the element they point to is
663  * erased, their dereference or their increment/decrement will produce a
664  * mess, probably a segfault. You should use them only when performance is
665  * an issue and if you are sure that they will never point to an element
666  * erased.
667  *
668  * @return Returns an unsafe const iterator pointing to the beginning of
669  * the List.
670  */
671  const_iterator cbegin() const;
672 
673  /**
674  * @brief Returns an unsafe iterator pointing to the beginning of the List.
675  *
676  * Unsafe iterators are a little bit faster than safe iterators and they
677  * consume less memory. However, if the element they point to is erased,
678  * their dereference or their increment/decrement will produce a mess,
679  * probably a segfault. You should use them only when performance is an
680  * issue and if you are sure that they will never point to an element
681  * erased.
682  *
683  * @return Returns an unsafe iterator pointing to the beginning of the
684  * List.
685  */
686  iterator begin();
687 
688  /**
689  * @brief Returns an unsafe const iterator pointing to the beginning of the
690  * List.
691  *
692  * Unsafe const iterators are a little bit faster than safe const iterators
693  * and they consume less memory. However, if the element they point to is
694  * erased, their dereference or their increment/decrement will produce a
695  * mess, probably a segfault. You should use them only when performance is
696  * an issue and if you are sure that they will never point to an element
697  * erased.
698  *
699  * @brief Returns an unsafe const iterator pointing to the beginning of the
700  * List.
701  */
702  const_iterator begin() const;
703 
704  /**
705  * @brief Returns an unsafe const iterator pointing to the last element of
706  * the List.
707  *
708  * Unsafe iterators are a little bit faster than safe iterators and they
709  * consume less memory. However, if the element they point to is erased,
710  * their dereference or their increment/decrement will produce a mess,
711  * probably a segfault. You should use them only when performance is an
712  * issue and if you are sure that they will never point to an element
713  * erased.
714  *
715  * @return Returns an unsafe const iterator pointing to the last element of
716  * the List.
717  */
718  const_iterator crbegin() const;
719 
720  /**
721  * @brief Returns an unsafe iterator pointing to the last element of the
722  * List.
723  *
724  * Unsafe iterators are a little bit faster than safe iterators and they
725  * consume less memory. However, if the element they point to is erased,
726  * their dereference or their increment/decrement will produce a mess,
727  * probably a segfault. You should use them only when performance is an
728  * issue and if you are sure that they will never point to an element
729  * erased.
730  *
731  * @return Returns an unsafe iterator pointing to the last element of the
732  * List.
733  */
734  iterator rbegin();
735 
736  /**
737  * @brief Returns an unsafe const iterator pointing to the last element of
738  * the List.
739  *
740  * Unsafe iterators are a little bit faster than safe iterators and they
741  * consume less memory. However, if the element they point to is erased,
742  * their dereference or their increment/decrement will produce a mess,
743  * probably a segfault. You should use them only when performance is an
744  * issue and if you are sure that they will never point to an element
745  * erased.
746  *
747  * @return Returns an unsafe const iterator pointing to the last element of
748  * the List.
749  */
750  const_iterator rbegin() const;
751 
752  /// @}
753  // ============================================================================
754  /// @name Accessors / Modifiers
755  // ============================================================================
756  /// @{
757 
758  /**
759  * @brief Inserts a new element (a copy) at the beginning of the chained
760  * list.
761  *
762  * The value passed in argument is not actually inserted into the list:
763  * this is a copy of this value that is inserted. The method runs in
764  * constant time.
765  *
766  * @param val The valus pushed at the front.
767  * @return Returns a reference on the copy inserted into the list.
768  * @warning Note that \e val is not actually inserted into the list.
769  * Rather, it is a copy of val that is inserted.
770  */
771  Val& pushFront(const Val& val);
772 
773  /**
774  * @brief Inserts a new element (a move) at the beginning of the chained
775  * list.
776  *
777  * @param val The valus pushed at the front.
778  * @return Returns a reference on the copy inserted into the list.
779  * @warning Note that \e val is not actually inserted into the list.
780  * Rather, it is a copy of val that is inserted.
781  */
782  Val& pushFront(Val&& val);
783 
784  /**
785  * @brief An alias for pushFront used for STL compliance.
786  *
787  * Defining push_front allows using, for instance, FrontInserters.
788  *
789  * @tparam Args The emplace values type.
790  * @param args The emplace values.
791  * @return Returns a reference on the copy inserted into the list.
792  */
793  template < typename... Args >
794  Val& push_front(Args&&... args);
795 
796  /**
797  * @brief Emplace elements at the beginning of the chained list.
798  *
799  * Emplace is a method that allows to construct directly an element of type
800  * Val by passing to its constructor all the arguments it needs
801  *
802  * @param args The arguments passed to the constructor.
803  * @return Returns a reference on the copy inserted into the list.
804  */
805  template < typename... Args >
806  Val& emplaceFront(Args&&... args);
807 
808  /**
809  * @brief Inserts a new element (a copy) at the end of the chained list.
810  *
811  * The value passed in argument is not actually inserted into the list:
812  * this is a copy of this value that is inserted. The method runs in
813  * constant time.
814  *
815  * @param val The value pushed back.
816  * @return Returns a reference on the copy inserted into the list.
817  * @warning Note that \e val is not actually inserted into the list.
818  * Rather, it is a copy of val that is inserted.
819  */
820  Val& pushBack(const Val& val);
821 
822  /**
823  * @brief Inserts a new element (a move) at the end of the chained list.
824  *
825  * The value passed in argument is not actually inserted into the list:
826  * this is a copy of this value that is inserted. The method runs in
827  * constant time.
828  *
829  * @param val The value pushed back.
830  * @return Returns a reference on the copy inserted into the list.
831  * @warning Note that \e val is not actually inserted into the list.
832  * Rather, it is a copy of val that is inserted.
833  */
834  Val& pushBack(Val&& val);
835 
836  /**
837  * @brief An alias for pushBack used for STL compliance.
838  *
839  * Defining push_back allows using, for instance, BackInserters.
840  * @tparam Args The emplace arguments type.
841  * @param args The emplace arguments values.
842  * @return Returns a reference on the copy inserted into the list.
843  */
844  template < typename... Args >
845  Val& push_back(Args&&... args);
846 
847  /**
848  * @brief Emplace elements at the end of the chained list.
849  *
850  * Emplace is a method that allows to construct directly an element of type
851  * Val by passing to its constructor all the arguments it needs
852  *
853  * @tparam Args The emplaced arguments types.
854  * @param args The arguments passed to the constructor
855  * @return A reference on the copy inserted into the list.
856  */
857  template < typename... Args >
858  Val& emplaceBack(Args&&... args);
859 
860  /**
861  * @brief Inserts a new element at the end of the chained list (alias of
862  * pushBack).
863  *
864  * @param val The value inserted.
865  * @return a reference on the copy inserted into the list.
866  * @warning Note that \e val is not actually inserted into the list.
867  * Rather, it is a copy of val that is inserted.
868  */
869  Val& insert(const Val& val);
870 
871  /**
872  * @brief Inserts a new element at the end of the chained list (alias of
873  * pushBack).
874  *
875  * @param val The value inserted.
876  * @return a reference on the copy inserted into the list.
877  * @warning Note that \e val is not actually inserted into the list.
878  * Rather, it is a copy of val that is inserted.
879  */
880  Val& insert(Val&& val);
881 
882  /**
883  * @brief Inserts a new element at the ith pos of the chained list.
884  *
885  * The first element of the list is at pos 0. After the insert, the element
886  * is placed precisely at pos if pos is less than the size of the list
887  * before insertion, else it is inserted at the end of the list.
888  *
889  * @param pos The position where to inser the new element.
890  * @param val The value to insert.
891  * @return a reference on the copy inserted into the list.
892  * @warning Note that \e val is not actually inserted into the list.
893  * Rather, it is a copy of val that is inserted.
894  */
895  Val& insert(Size pos, const Val& val);
896 
897  /**
898  * @brief Insert an rvalue at the ith pos of the chained list.
899  *
900  * The first element of the list is at pos 0. After the insert, the element
901  * is placed precisely at pos if pos is less than the size of the list
902  * before insertion, else it is inserted at the end of the list.
903  *
904  * @param pos The position where to inser the new element.
905  * @param val The value to insert.
906  * @return Returns a reference on the copy inserted into the list.
907  */
908  Val& insert(Size pos, Val&& val);
909 
910  /**
911  * @brief Inserts a new element before or after a given iterator.
912  *
913  * @param iter The iterator pointing where to inser the new element.
914  * @param val The value to insert.
915  * @param place Defines where to insert the new element relatively to iter.
916  * @return Returns a reference on the copy inserted into the list.
917  * @warning Note that \e val is not actually inserted into the list.
918  * Rather, it is a copy of val that is inserted.
919  */
920  Val& insert(const const_iterator_safe& iter,
921  const Val& val,
922  location place = location::BEFORE);
923 
924  /**
925  * @brief Inserts an rvalue before or after a given iterator.
926  *
927  * @param iter The iterator pointing where to inser the new element.
928  * @param val The value to insert.
929  * @param place Defines where to insert the new element relatively to iter.
930  * @return Returns a reference on the copy inserted into the list.
931  * @warning Note that \e val is not actually inserted into the list. Rather,
932  * it is a copy of val that is inserted.
933  */
934  Val& insert(const const_iterator_safe& iter,
935  Val&& val,
936  location place = location::BEFORE);
937 
938  /**
939  * @brief Inserts a new element before or after a given iterator.
940  *
941  * @param iter The iterator pointing where to inser the new element.
942  * @param val The value to insert.
943  * @param place Defines where to insert the new element relatively to iter.
944  * @return Returns a reference on the copy inserted into the list.
945  * @warning Note that \e val is not actually inserted into the list.
946  * Rather, it is a copy of val that is inserted.
947  */
948  Val& insert(const const_iterator& iter,
949  const Val& val,
950  location place = location::BEFORE);
951 
952  /**
953  * @brief Inserts an rvalue before or after a given iterator.
954  *
955  * @param iter The iterator pointing where to inser the new element.
956  * @param val The value to insert.
957  * @param place Defines where to insert the new element relatively to iter.
958  * @return Returns a reference on the copy inserted into the list.
959  * @warning Note that \e val is not actually inserted into the list. Rather,
960  * it is a copy of val that is inserted.
961  */
962  Val& insert(const const_iterator& iter,
963  Val&& val,
964  location place = location::BEFORE);
965 
966  /**
967  * @brief Emplace a new element before a given iterator.
968  *
969  * Emplace is a method that allows to construct directly an element of type
970  * Val by passing to its constructor all the arguments it needs. The first
971  * element of the list is at pos 0. After the insert, the element is placed
972  * precisely at pos if pos is less than the size of the list before
973  * insertion, else it is inserted at the end of the list.
974  *
975  * @param iter The position in the list
976  * @param args The arguments passed to the constructor
977  * @return Returns a reference on the copy inserted into the list.
978  */
979  template < typename... Args >
980  Val& emplace(const const_iterator& iter, Args&&... args);
981 
982  /**
983  * @brief Emplace a new element before a given safe iterator.
984  *
985  * Emplace is a method that allows to construct directly an element of type
986  * Val by passing to its constructor all the arguments it needs. The first
987  * element of the list is at pos 0. After the insert, the element is placed
988  * precisely at pos if pos is less than the size of the list before
989  * insertion, else it is inserted at the end of the list.
990  *
991  * @param iter The position in the list.
992  * @param args the arguments passed to the constructor.
993  * @return Returns a reference on the copy inserted into the list.
994  */
995  template < typename... Args >
996  Val& emplace(const const_iterator_safe& iter, Args&&... args);
997 
998  /**
999  * @brief Returns a reference to first element of a list, if any.
1000  * @throw NotFound exception is thrown if the list is empty.
1001  */
1002  Val& front() const;
1003 
1004  /**
1005  * @brief Returns a reference to last element of a list, if any.
1006  * @throw NotFound exception is thrown if the list is empty.
1007  */
1008  Val& back() const;
1009 
1010  /**
1011  * @brief Returns the number of elements in the list.
1012  * This method runs in constant time.
1013  */
1014  Size size() const noexcept;
1015 
1016  /**
1017  * @brief Checks whether there exists a given element in the list.
1018  *
1019  * This method runs in linear time.
1020  *
1021  * Comparisons between Val instances are performed through == operators.
1022  *
1023  * @param val the value of the element we wish to check the existence of.
1024  * @return Returns true if val is in the gum::List.
1025  */
1026  bool exists(const Val& val) const;
1027 
1028  /**
1029  * @brief Erases the ith element of the List (the first one is in position
1030  * 0).
1031  *
1032  * If the element cannot be found, the function returns without throwing
1033  * any exception. It runs in linear time in the size of the list.
1034  *
1035  * @param i The position in the list of the element we wish to remove.
1036  */
1037  void erase(Size i);
1038 
1039  /**
1040  * @brief Erases the element of the List pointed to by the safe iterator.
1041  *
1042  * If the element cannot be found, i.e., it has already been erased or the
1043  * iterator points to end/rend, the function returns without throwing any
1044  * exception. It runs in linear time in the size of the list.
1045  *
1046  * @param iter An iterator pointing to the element to remove.
1047  */
1048  void erase(const iterator_safe& iter);
1049 
1050  /**
1051  * @brief Erases the element of the List pointed to by the safe const
1052  * iterator.
1053  *
1054  * If the element cannot be found, i.e., it has already been erased or the
1055  * iterator points to end/rend, the function returns without throwing any
1056  * exception. It runs in linear time in the size of the list.
1057  *
1058  * @param iter An iterator pointing to the element to remove.
1059  */
1060  void erase(const const_iterator_safe& iter);
1061 
1062  /**
1063  * @brief erases the first element encountered with a given value.
1064  *
1065  * If no element equal to \e val can be found, the function returns without
1066  * throwing any exception. It runs in linear time both in the size of the
1067  * list and in the number of iterators referenced in the list. Comparisons
1068  * between Val instances are performed through == operators.
1069  *
1070  * @param val The value of the element we wish to remove.
1071  */
1072  void eraseByVal(const Val& val);
1073 
1074  /**
1075  * @brief erases all the elements encountered with a given value
1076  *
1077  * If no element equal to \e val can be found, the function returns without
1078  * throwing any exception.
1079  *
1080  * Comparisons between Val instances are performed through == operators.
1081  *
1082  * @param val the value of the element we wish to remove.
1083  */
1084  void eraseAllVal(const Val& val);
1085 
1086  /**
1087  * @brief Removes the last element of a List, if any.
1088  *
1089  * When the list is empty, it does not do anything.
1090  */
1091  void popBack();
1092 
1093  /**
1094  * @brief Removes the first element of a List, if any.
1095  *
1096  * When the list is empty, it does not do anything.
1097  */
1098  void popFront();
1099 
1100  /**
1101  * @brief Deletes all the elements of a chained list.
1102  *
1103  * All the iterators of the list will be resetted to rend. The method runs
1104  * in linear time of both the size of the list and the number of iterators
1105  * attached to the List.
1106  */
1107  void clear();
1108 
1109  /**
1110  * @brief Returns a boolean indicating whether the chained list is empty.
1111  * @return Returns a boolean indicating whether the chained list is empty.
1112  */
1113  bool empty() const noexcept;
1114 
1115  /**
1116  * @brief Swap the current list with another one.
1117  * @param other_list The list to swap elements with.
1118  */
1119  void swap(List& other_list);
1120 
1121  /**
1122  * @brief Converts a list into a string.
1123  * @return Returns a std::string representation of the gum::List.
1124  */
1125  std::string toString() const;
1126 
1127  /**
1128  * @brief Creates a list of mountains from a list of val.
1129  * @param f A function that maps any Val element into a Mount
1130  * @return Returns a lsit of mountains.
1131  * @tparam Mount The type of mountains.
1132  * @tparam OtherAlloc The mountains type allocator.
1133  */
1134  template < typename Mount, typename OtherAlloc = std::allocator< Mount > >
1135  List< Mount, OtherAlloc > map(Mount (*f)(Val)) const;
1136 
1137  /**
1138  * @brief Creates a list of mountains from a list of val.
1139  * @param f A function that maps any Val element into a Mount
1140  * @return Returns a lsit of mountains.
1141  * @tparam Mount The type of mountains.
1142  * @tparam OtherAlloc The mountains type allocator.
1143  */
1144  template < typename Mount, typename OtherAlloc = std::allocator< Mount > >
1145  List< Mount, OtherAlloc > map(Mount (*f)(Val&)) const;
1146 
1147  /**
1148  * @brief Creates a list of mountains from a list of val.
1149  * @param f A function that maps any Val element into a Mount
1150  * @return Returns a lsit of mountains.
1151  * @tparam Mount The type of mountains.
1152  * @tparam OtherAlloc The mountains type allocator.
1153  */
1154  template < typename Mount, typename OtherAlloc = std::allocator< Mount > >
1155  List< Mount, OtherAlloc > map(Mount (*f)(const Val&)) const;
1156 
1157  /**
1158  * @brief Creates a list of mountains with a given value from a list of
1159  * val.
1160  * @param mount the value taken by all the elements of the resulting list
1161  * @return Returns a lsit of mountains.
1162  * @tparam Mount The type of mountains.
1163  * @tparam OtherAlloc The mountains type allocator.
1164  */
1165  template < typename Mount, typename OtherAlloc = std::allocator< Mount > >
1166  List< Mount, OtherAlloc > map(const Mount& mount) const;
1167 
1168  /// @}
1169  // ============================================================================
1170  /// @name Operators
1171  // ============================================================================
1172  /// @{
1173 
1174  /**
1175  * @brief Copy operator.
1176  *
1177  * The new list and that which is copied do not share the elements: the new
1178  * list contains new instances of the values stored in the list to be
1179  * copied. Of course if these values are pointers, the new values point
1180  * toward the same elements. The List on which the operator is applied
1181  * keeps its iterator's list. Of course, if it previously contained some
1182  * elements, those are removed prior to the copy. This operator runs in
1183  * linear time.
1184  *
1185  * @warning If the current List previously contained iterators, those will
1186  * be resetted to end()/rend().
1187  *
1188  * @param src the list the content of which will be copied into the current
1189  * List.
1190  * @return Returns this gum::List.
1191  */
1192  List< Val, Alloc >& operator=(const List< Val, Alloc >& src);
1193 
1194  /**
1195  * @brief Generalized copy operator.
1196  *
1197  * The new list and that which is copied do not share the elements: the new
1198  * list contains new instances of the values stored in the list to be
1199  * copied. Of course if these values are pointers, the new values point
1200  * toward the same elements. The List on which the operator is applied
1201  * keeps its iterator's list. Of course, if it previously contained some
1202  * elements, those are removed prior to the copy. This operator runs in
1203  * linear time.
1204  *
1205  * @warning If the current List previously contained iterators, those will
1206  * be resetted to end()/rend().
1207  * @param src the list the content of which will be copied into the current
1208  * List.
1209  * @return Returns this gum::List.
1210  */
1211  template < typename OtherAlloc >
1212  List< Val, Alloc >& operator=(const List< Val, OtherAlloc >& src);
1213 
1214  /**
1215  * @brief Move operator.
1216  *
1217  * @param src The gum::List to move.
1218  * @return Returns this gum::List.
1219  */
1220  List< Val, Alloc >& operator=(List< Val, Alloc >&& src);
1221 
1222  /**
1223  * @brief Inserts a new element at the end of the list (alias of pushBack).
1224  *
1225  * This enables writing code like \c list \c += \c xxx; to add element \c
1226  * xxx to the list.
1227  *
1228  * @warning Note that \e val is not actually inserted into the list.
1229  * Rather, it is a copy of val that is inserted.
1230  *
1231  * @param val Tha value inserted int the list.
1232  * @return Returns a reference on the copy inserted into the list.
1233  */
1234  Val& operator+=(const Val& val);
1235 
1236  /**
1237  * @brief Inserts a new element at the end of the list (alias of pushBack).
1238  *
1239  * This enables writing code like \c list \c += \c xxx; to add element \c
1240  * xxx to the list.
1241  *
1242  * @warning Note that \e val is not actually inserted into the list.
1243  * Rather, it is a copy of val that is inserted.
1244  *
1245  * @param val Tha value inserted int the list.
1246  * @return Returns a reference on the copy inserted into the list.
1247  */
1248  Val& operator+=(Val&& val);
1249 
1250  /**
1251  * @brief Checks whether two lists are identical (same elements in the same
1252  * order).
1253  *
1254  * This method runs in time linear in the number of elements of the list.
1255  *
1256  * @return Returns true if src and this gum::List are identical.
1257  * @tparam OtherAlloc The other allocator.
1258  */
1259  template < typename OtherAlloc >
1260  bool operator==(const List< Val, OtherAlloc >& src) const;
1261 
1262  /**
1263  * @brief Checks whether two lists are different (different elements or
1264  * orders).
1265  *
1266  * This method runs in time linear in the number of elements of the list.
1267  *
1268  * @return Returns true if src and this gum::List are identical.
1269  * @tparam OtherAlloc The other allocator.
1270  */
1271  template < typename OtherAlloc >
1272  bool operator!=(const List< Val, OtherAlloc >& src) const;
1273 
1274  /**
1275  * @brief Returns the ith element in the current chained list.
1276  *
1277  * The first of the list element has index 0.
1278  *
1279  * This method runs in linear time.
1280  *
1281  * @param i The position of the element in the list (0 = first element).
1282  * @throw NotFound Raised if the element to be retrieved does not exist.
1283  * @return Returns a reference on the element stored at the ith position in
1284  * the list.
1285  */
1286  Val& operator[](const Size i);
1287 
1288  /**
1289  * @brief Returns the const ith element in the current chained list.
1290  *
1291  * The first of the list element has index 0.
1292  *
1293  * This method runs in linear time.
1294  *
1295  * @param i the position of the element in the list (0 = first element).
1296  * @throw NotFound Raised if the element to be retrieved does not exist.
1297  * @return Returns a reference on the element stored at the ith position in
1298  * the list.
1299  */
1300  const Val& operator[](const Size i) const;
1301 
1302  /// @}
1303 
1304  private:
1305  /// A pointer on the first element of the chained list.
1306  ListBucket< Val >* deb_list__{nullptr};
1307 
1308  /// A pointer on the last element of the chained list.
1309  ListBucket< Val >* end_list__{nullptr};
1310 
1311  /// The number of elements in the list.
1312  Size nb_elements__{Size(0)};
1313 
1314  /// The list of "safe" iterators attached to the list.
1315  mutable std::vector< const_iterator_safe* > safe_iterators__;
1316 
1317  /// The allocator for the buckets.
1318  mutable BucketAllocator alloc_bucket__;
1319 
1320  /**
1321  * @brief A function used to perform copies of elements of Lists.
1322  *
1323  * Before performing the copy, we assume in this function that the current
1324  * list (this) is empty (else there would be memory leak).
1325  *
1326  * @tparam OtherAlloc The other allocator.
1327  * @param src The gum::List to copy.
1328  */
1329  template < typename OtherAlloc >
1330  void copy_elements__(const List< Val, OtherAlloc >& src);
1331 
1332  /**
1333  * @brief Returns the bucket corresponding to the ith position in the list.
1334  *
1335  * This method assumes that the list contains at least i+1 elements. The
1336  * index of the first element of the list is 0.
1337  *
1338  * @param i The position of the returned element.
1339  * @return Returns the gum::ListBucket of the ith element.
1340  */
1341  ListBucket< Val >* getIthBucket__(Size i) const noexcept;
1342 
1343  /**
1344  * @brief Returns the bucket corresponding to a given value.
1345  *
1346  * Actually, this is the first bucket of value val encountered in the list,
1347  * if any, that is returned. If the element cannot be found, 0 is returned.
1348  * This method enables fast removals of buckets. It runs in linear time.
1349  *
1350  * Comparisons between Val instances are performed through == operators.
1351  *
1352  * @param val The value of the element the bucket of which we wish to
1353  * return.
1354  * @return Returns the bucket corresponding to a given value.
1355  */
1356  ListBucket< Val >* getBucket__(const Val& val) const noexcept;
1357 
1358  /**
1359  * @brief Removes an element from a chained list.
1360  *
1361  * If parameter \e bucket is equal to 0, then the method does not perform
1362  * anything, else the bucket is deleted. In the latter case, no test is
1363  * ever performed to check that the bucket does actually belong to the
1364  * List. The method runs in constant time.
1365  *
1366  * @param bucket A pointer on the bucket in the chained list
1367  * we wish to remove.
1368  */
1369  void erase__(ListBucket< Val >* bucket);
1370 
1371  /**
1372  * @brief Create a new bucket with a given value.
1373  * @param val The value of the new bucket.
1374  * @return Returns the bucket holding val.
1375  */
1376  ListBucket< Val >* createBucket__(const Val& val) const;
1377 
1378  /**
1379  * @brief Create a new bucket with a given value.
1380  * @param val The value of the new bucket.
1381  * @return Returns the bucket holding val.
1382  */
1383  ListBucket< Val >* createBucket__(Val&& val) const;
1384 
1385  /**
1386  * Create an emplace bucket.
1387  * @tparam Args The emplace arguments types.
1388  * @param args The emplace arguments.
1389  * @return Returns the bucket holding the new value.
1390  */
1391  template < typename... Args >
1392  ListBucket< Val >* createEmplaceBucket__(Args&&... args) const;
1393 
1394  /**
1395  * @brief Insert a bucket at the front of the list.
1396  * @param new_elt The new element pushed at the front of the gum::List.
1397  * @return Returns a refefence over the value stored in the gum::List.
1398  */
1399  Val& pushFront__(ListBucket< Val >* new_elt);
1400 
1401  /**
1402  * @brief Insert a bucket at the end of the list.
1403  * @param new_elt The new element pushed at the end of the gum::List.
1404  * @return Returns a refefence over the value stored in the gum::List.
1405  */
1406  Val& pushBack__(ListBucket< Val >* new_elt);
1407 
1408  /**
1409  * @brief Insert a new bucket before another one.
1410  * @param new_elt The new element to insert in the gum::List.
1411  * @param current_elt The element before which new_elt will be inserted.
1412  * @return Returns a reference over the value stored in the gum::List.
1413  */
1414  Val& insertBefore__(ListBucket< Val >* new_elt,
1415  ListBucket< Val >* current_elt);
1416 
1417  /**
1418  * @brief Insert a new bucket after another one.
1419  * @param new_elt The new element to insert in the gum::List.
1420  * @param current_elt The element before which new_elt will be inserted.
1421  * @return Returns a reference over the value stored in the gum::List.
1422  */
1423  Val& insertAfter__(ListBucket< Val >* new_elt, ListBucket< Val >* current_elt);
1424 
1425  /**
1426  * @brief Inserts a new bucket before or after the location pointed to by
1427  * an iterator.
1428  * @param iter An iterator pointing where to insert a new element.
1429  * @param new_elt The new element ot insert in the gum::List.
1430  * @param place Where to insert the new element relatively to the iterator.
1431  * @return Returns a reference over the value stored in the gum::List.
1432  */
1433  Val& insert__(const const_iterator_safe& iter,
1434  ListBucket< Val >* new_elt,
1435  location place);
1436 
1437  /**
1438  * @brief Inserts a new bucket before or after the location pointed to by
1439  * an iterator.
1440  * @param iter An iterator pointing where to insert a new element.
1441  * @param new_elt The new element ot insert in the gum::List.
1442  * @param place Where to insert the new element relatively to the iterator.
1443  * @return Returns a reference over the value stored in the gum::List.
1444  */
1445  Val& insert__(const const_iterator& iter,
1446  ListBucket< Val >* new_elt,
1447  location place);
1448 
1449  /// ListIterator should be a friend to optimize access to elements
1450  /// @{
1451  friend class ListIterator< Val >;
1452  friend class ListConstIterator< Val >;
1453  friend class ListIteratorSafe< Val >;
1454  friend class ListConstIteratorSafe< Val >;
1455  /// @}
1456  };
1457 
1458  // ===========================================================================
1459  // === UNSAFE LIST CONST ITERATORS ===
1460  // ===========================================================================
1461  /**
1462  * @class ListConstIterator
1463  * @headerfile list.h <agrum/tools/core/list.h>
1464  * @ingroup list_group
1465  * @brief Unsafe but fast const iterators for Lists.
1466  *
1467  * Class ListConstIterator implements unsafe iterators for List. However,
1468  * developers may consider using List<x>::const_iterator instead of
1469  * ListConstIterator<x>.
1470  *
1471  * These iterators are fast but they are unaware of changes within the List.
1472  * Therefore, if they point to an element that is being deleted from memory
1473  * by the list, their accessing this element will most probably produce a
1474  * segmentation fault. Similarly, incrementing or decrementing such an
1475  * iterator pointing to a deleted element will most certainly produce a mess.
1476  * So, ListConstIterator should be used only if you are sure that they will
1477  * never point to an element that has been removed from the list (a typical
1478  * use is to iterate over a const List). Whenever you are not sure that this
1479  * property holds, use ListConstIteratorSafe<x> or
1480  * List<x>::const_iterator_safe. Those iterators are a little bit slower but
1481  * guarantee that no segmentation fault will ever occur.
1482  *
1483  * @par Usage example:
1484  * @code
1485  * // create a list of strings
1486  * List<string> list;
1487  * list.pushBack ("toto"); list.pushBack ("titi");
1488  *
1489  * // parse all the elements of a list
1490  * for ( List<string>::const_iterator iter = list.cbegin ();
1491  * iter != list.cend (); ++iter )
1492  * cerr << *iter << endl;
1493  * for ( List<string>::const_iterator iter = list.cbegin ();
1494  * iter != list.cend (); iter += 2 ) // step = 2
1495  * cerr << *iter << endl;
1496  * for ( List<string>::const_iterator iter = list.cbegin ();
1497  * iter != list.cend (); iter = iter + 2 ) // step = 2
1498  * cerr << *iter << endl;
1499  * for ( List<string>::const_iterator iter = list.crbegin ();
1500  * iter != list.crend (); --iter )
1501  * cerr << *iter << endl;
1502  *
1503  * // use member size() of the strings
1504  * for ( List<string>::const_iterator iter = list.cbegin ();
1505  * iter != list.cend (); ++iter)
1506  * cerr << iter->size() << endl;
1507  * @endcode
1508  *
1509  * @tparam Val The gum::List values type.
1510  */
1511  template < typename Val >
1512  class ListConstIterator {
1513  public:
1514  /// Types for STL compliance.
1515  /// @{
1516  using iterator_category = std::bidirectional_iterator_tag;
1517  using value_type = Val;
1518  using reference = Val&;
1519  using const_reference = const Val&;
1520  using pointer = Val*;
1521  using const_pointer = const Val*;
1522  using difference_type = std::ptrdiff_t;
1523  /// @}
1524 
1525  // ============================================================================
1526  /// @name Constructors / Destructors
1527  // ============================================================================
1528  /// @{
1529 
1530  /**
1531  * @brief Default constructor.
1532  *
1533  * Returns an iterator pointing toward nothing.
1534  */
1535  ListConstIterator() noexcept;
1536 
1537  /**
1538  * @brief Constructor for a begin.
1539  * @tparam Alloc The gum::List allocator.
1540  */
1541  template < typename Alloc >
1542  ListConstIterator(const List< Val, Alloc >& theList) noexcept;
1543 
1544  /**
1545  * @brief Copy constructor.
1546  * @param src The gum::ListConstIterator to copy.
1547  */
1548  ListConstIterator(const ListConstIterator< Val >& src) noexcept;
1549 
1550  /**
1551  * @brief Move constructor.
1552  * @param src The gum::ListConstIterator to move.
1553  */
1554  ListConstIterator(ListConstIterator< Val >&& src) noexcept;
1555 
1556  /**
1557  * @brief Constructor for an iterator pointing to the \e ind_eltth element
1558  * of a List.
1559  * @param theList The list to iterate over.
1560  * @param ind_elt The iterator starting position.
1561  * @throw UndefinedIteratorValue Raised if the element does not exist in
1562  * the list.
1563  */
1564  ListConstIterator(const List< Val >& theList, Size ind_elt);
1565 
1566  /**
1567  * @brief Class Desctructor.
1568  */
1569  ~ListConstIterator() noexcept;
1570 
1571  /// @}
1572  // ============================================================================
1573  /// @name Accessors / Modifiers
1574  // ============================================================================
1575  /// @{
1576 
1577  /**
1578  * @brief Makes the iterator point toward nothing.
1579  *
1580  * A method for detaching the iterator from the List it is attached to.
1581  * After being detached, the iterator does not point to any element, i.e.,
1582  * trying to access its content will raise an exception.
1583  */
1584  void clear() noexcept;
1585 
1586  /**
1587  * @brief Positions the iterator to the end of the list.
1588  */
1589  void setToEnd() noexcept;
1590 
1591  /**
1592  * @brief Returns a bool indicating whether the iterator points to the end
1593  * of the list.
1594  * @return Returns a bool indicating whether the iterator points to the end
1595  * of the list.
1596  */
1597  bool isEnd() const noexcept;
1598 
1599  /// @}
1600  // ============================================================================
1601  /// @name Operators
1602  // ============================================================================
1603  /// @{
1604 
1605  /**
1606  * @brief Copy operator.
1607  *
1608  * The current iterator now points to the same element as iterator \e from.
1609  *
1610  * @param src The gum::ListConstIterator to copy.
1611  * @return Returns this gum::ListConstIterator.
1612  */
1613  ListConstIterator< Val >&
1614  operator=(const ListConstIterator< Val >& src) noexcept;
1615 
1616  /**
1617  * @brief Move operator.
1618  *
1619  * @param src The gum::ListConstIterator to move.
1620  * @return Returns this gum::ListConstIterator.
1621  */
1622  ListConstIterator< Val >& operator=(ListConstIterator< Val >&& src) noexcept;
1623 
1624  /**
1625  * @brief Makes the iterator point to the next element in the List.
1626  *
1627  * @code
1628  * for (iter = list.begin(); iter != list.end(); ++iter) { }
1629  * @endcode
1630  *
1631  * The above loop is guaranteed to parse the whole List as long as no
1632  * element is added to or deleted from the List while being in the loop.
1633  * Runs in constant time.
1634  *
1635  * @return Returns this gum::ListConstIterator.
1636  */
1637  ListConstIterator< Val >& operator++() noexcept;
1638 
1639  /**
1640  * @brief Makes the iterator point to i elements further in the List.
1641  * @param i The number of steps to move the iterator.
1642  * @return Returns this gum::ListConstIterator.
1643  */
1644  ListConstIterator< Val >& operator+=(difference_type i) noexcept;
1645 
1646  /**
1647  * @brief Makes the iterator point to the preceding element in the List.
1648  *
1649  * @code
1650  * for (iter = list.rbegin(); iter != list.rend(); --iter) { }
1651  * @endcode
1652  *
1653  * The above loop is guaranteed to parse the whole List as long as no
1654  * element is added to or deleted from the List while being in the loop.
1655  * Runs in constant time.
1656  *
1657  * @return Returns this gum::ListConstIterator.
1658  */
1659  ListConstIterator< Val >& operator--() noexcept;
1660 
1661  /**
1662  * @brief Makes the iterator point to i elements befor in the List.
1663  *
1664  * @param i The number of steps to move the iterator.
1665  * @return Returns this gum::ListConstIterator.
1666  */
1667  ListConstIterator< Val >& operator-=(difference_type i) noexcept;
1668 
1669  /**
1670  * @brief Returns a new iterator pointing to i further elements in the
1671  * gum::List.
1672  * @param i The number of steps to move the iterator.
1673  * @return Returns a new gum::ListConstIterator.
1674  */
1675  ListConstIterator< Val > operator+(difference_type i) noexcept;
1676 
1677  /**
1678  * @brief Returns a new iterator pointing to i preceding elements in the
1679  * gum::List.
1680  * @param i The number of steps to move the iterator.
1681  * @return Returns a new gum::ListConstIterator.
1682  */
1683  ListConstIterator< Val > operator-(difference_type i) noexcept;
1684 
1685  /**
1686  * @brief Checks whether two iterators point toward different elements.
1687  *
1688  * @warning the end and rend iterators are always equal, whatever the list
1689  * they belong to, i.e., \c list1.end() == \c list2.rend().
1690  *
1691  * @param src The gum::ListConstIterator to test for inequality.
1692  * @return Returns true if src and this are equal.
1693  */
1694  bool operator!=(const ListConstIterator< Val >& src) const noexcept;
1695 
1696  /**
1697  * @brief Checks whether two iterators point toward the same elements.
1698  *
1699  * @warning the end and rend iterators are always equal, whatever the list
1700  * they belong to, i.e., \c list1.end() == \c list2.rend().
1701  *
1702  * @param src The gum::ListConstIterator to test for equality.
1703  * @return Returns true if src and this are equal.
1704  */
1705  bool operator==(const ListConstIterator< Val >& src) const noexcept;
1706 
1707  /**
1708  * @brief Gives access to the content of the iterator.
1709  * @throw UndefinedIteratorValue Raised if the iterator points to nothing.
1710  * @return Returns the content of the iterator.
1711  */
1712  const Val& operator*() const;
1713 
1714  /**
1715  * @brief Dereferences the value pointed to by the iterator.
1716  * @throw UndefinedIteratorValue Raised if the iterator points to nothing.
1717  * @return Returns the value pointed to by the iterator.
1718  */
1719  const Val* operator->() const;
1720 
1721  /// @}
1722 
1723  private:
1724  /**
1725  * @brief Class List must be a friend because it uses the getBucket method
1726  * to speed up some processes.
1727  */
1728  template < typename T, typename A >
1729  friend class List;
1730 
1731  /// The bucket in the chained list pointed to by the iterator.
1732  ListBucket< Val >* bucket__{nullptr};
1733 
1734  /// Returns the bucket the iterator is pointing to.
1735  ListBucket< Val >* getBucket__() const noexcept;
1736  };
1737 
1738  /// For STL compliance, a distance operator.
1739  template < typename Val >
1740  typename ListConstIterator< Val >::difference_type
1741  operator-(const ListConstIterator< Val >& iter1,
1742  const ListConstIterator< Val >& iter2);
1743 
1744  // ===========================================================================
1745  // === UNSAFE LIST ITERATORS ===
1746  // ===========================================================================
1747 
1748  /**
1749  * @class ListIterator
1750  * @headerfile list.h <agrum/tools/core/list.h>
1751  * @ingroup list_group
1752  * @brief Unsafe but fast iterators for Lists.
1753  *
1754  * Class ListIterator implements iterators for List. However, developers may
1755  * consider using List<x>::iterator instead of ListIterator<x>.
1756  *
1757  * These iterators are fast but they are unaware of changes within the List.
1758  * Therefore, if they point to an element that is being deleted from memory
1759  * by the list, their accessing this element will most probably produce a
1760  * segmentation fault. Similarly, incrementing or decrementing such an
1761  * iterator pointing to a deleted element will most certainly produce a mess.
1762  * So, ListIterator should be used only if you are sure that they will never
1763  * point to an element that has been removed from the list (a typical use is
1764  * to iterate over a const List). Whenever you are not sure that this
1765  * property holds, use ListIteratorSafe<x> or List<x>::iterator_safe. Those
1766  * iterators are a little bit slower but guarantee that no segmentation fault
1767  * will ever occur.
1768  *
1769  * @par Usage example:
1770  * @code
1771  * // create a list of strings
1772  * List<string> list;
1773  * list.pushBack ("toto"); list.pushBack ("titi");
1774  *
1775  * // parse all the elements of a list
1776  * for ( List<string>::iterator iter = list.begin ();
1777  * iter != list.end (); ++iter )
1778  * cerr << *iter << endl;
1779  * for ( List<string>::iterator iter = list.begin ();
1780  * iter != list.end (); iter += 2 ) // step = 2
1781  * cerr << *iter << endl;
1782  * for ( List<string>::iterator iter = list.begin ();
1783  * iter != list.end (); iter = iter + 2 ) // step = 2
1784  * cerr << *iter << endl;
1785  * for ( List<string>::iterator iter = list.rbegin ();
1786  * iter != list.rend (); --iter )
1787  * cerr << *iter << endl;
1788  *
1789  * // use member size() of the strings
1790  * for ( List<string>::iterator iter = list.begin ();
1791  * iter != list.end (); ++iter)
1792  * cerr << iter->size() << endl;
1793  * @endcode
1794  *
1795  * @tparam Val The gum::List values type.
1796  */
1797  template < typename Val >
1798  class ListIterator: public ListConstIterator< Val > {
1799  public:
1800  /// Types for STL compliance.
1801  /// @{
1802  using iterator_category = std::bidirectional_iterator_tag;
1803  using value_type = Val;
1804  using reference = Val&;
1805  using const_reference = const Val&;
1806  using pointer = Val*;
1807  using const_pointer = const Val*;
1808  using difference_type = std::ptrdiff_t;
1809  /// @}
1810 
1811  // ============================================================================
1812  /// @name Constructors / Destructors
1813  // ============================================================================
1814  /// @{
1815 
1816  /**
1817  * @brief Default constructor.
1818  *
1819  * Returns an iterator pointing toward nothing.
1820  */
1821  ListIterator() noexcept;
1822 
1823  /**
1824  * @brief Constructor for a begin.
1825  * @tparam Alloc The gum::List allocator.
1826  * @param theList The list to iterate over.
1827  */
1828  template < typename Alloc >
1829  ListIterator(const List< Val, Alloc >& theList) noexcept;
1830 
1831  /**
1832  * @brief Copy constructor.
1833  * @param src The gum::ListIterator to copy.
1834  */
1835  ListIterator(const ListIterator< Val >& src) noexcept;
1836 
1837  /**
1838  * @brief Move constructor.
1839  * @param src The gum::ListIterator to move.
1840  */
1841  ListIterator(ListIterator< Val >&& src) noexcept;
1842 
1843  /**
1844  * @brief Constructor for an iterator pointing to the \e ind_eltth element
1845  * of a List.
1846  * @param theList The gum::List to iterate over.
1847  * @param ind_elt The position to point to.
1848  * @throw UndefinedIteratorValue Raised if the element does not exist in
1849  * the list.
1850  */
1851  ListIterator(const List< Val >& theList, Size ind_elt);
1852 
1853  /**
1854  * @brief Class destructor.
1855  */
1856  ~ListIterator() noexcept;
1857 
1858  /// @}
1859  // ============================================================================
1860  /// @name Accessors / Modifiers
1861  // ============================================================================
1862  /// @{
1863 
1864  using ListConstIterator< Val >::clear;
1865  using ListConstIterator< Val >::setToEnd;
1866  using ListConstIterator< Val >::isEnd;
1867 
1868  /// @}
1869 
1870  // ============================================================================
1871  /// @name Operators
1872  // ============================================================================
1873  /// @{
1874 
1875  /**
1876  * @brief Copy operator.
1877  *
1878  * The current iterator now points to the same element as iterator \e src.
1879  *
1880  * @param src The gum::ListIterator to copy.
1881  * @return Returns this gum::ListIterator.
1882  */
1883  ListIterator< Val >& operator=(const ListIterator< Val >& src) noexcept;
1884 
1885  /// move operator
1886  /**
1887  * @brief Move operator.
1888  *
1889  * The current iterator now points to the same element as iterator \e src.
1890  *
1891  * @param src The gum::ListIterator to move.
1892  * @return Returns this gum::ListIterator.
1893  */
1894  ListIterator< Val >& operator=(ListIterator< Val >&& src) noexcept;
1895 
1896  /**
1897  * @brief Makes the iterator point to the next element in the List.
1898  *
1899  * @code
1900  * for (iter = list.begin(); iter != list.end(); ++iter) { }
1901  * @endcode
1902  *
1903  * The above loop is guaranteed to parse the whole List as long as no
1904  * element is added to or deleted from the List while being in the loop.
1905  * Deleting elements during the loop is guaranteed to never produce a
1906  * segmentation fault. Runs in constant time.
1907  *
1908  * @return Returns this gum::ListIterator.
1909  */
1910  ListIterator< Val >& operator++() noexcept;
1911 
1912  /**
1913  * @brief Makes the iterator point to i elements further in the List.
1914  * @param i The number of steps to move the iterator.
1915  * @return Returns this gum::ListIterator.
1916  */
1917  ListIterator< Val >& operator+=(difference_type i) noexcept;
1918 
1919  /**
1920  * @brief Makes the iterator point to the preceding element in the List.
1921  *
1922  * @code
1923  * for (iter = list.rbegin(); iter != list.rend(); --iter) { }
1924  * @endcode
1925  *
1926  * The above loop is guaranteed to parse the whole List as long as no
1927  * element is added to or deleted from the List while being in the loop.
1928  * Runs in constant time.
1929  *
1930  * @return Returns this gum::ListIterator.
1931  */
1932  ListIterator< Val >& operator--() noexcept;
1933 
1934  /**
1935  * @brief Makes the iterator point to i elements befor in the List.
1936  *
1937  * @param i The number of steps to move the iterator.
1938  * @return Returns this gum::ListIterator.
1939  */
1940  ListIterator< Val >& operator-=(difference_type i) noexcept;
1941 
1942  /**
1943  * @brief Returns a new iterator pointing to i further elements in the
1944  * gum::List.
1945  * @param i The number of steps to move the iterator.
1946  * @return Returns a new gum::ListIterator.
1947  */
1948  ListIterator< Val > operator+(difference_type i) noexcept;
1949 
1950  /**
1951  * @brief Returns a new iterator pointing to i preceding elements in the
1952  * gum::List.
1953  * @param i The number of steps to move the iterator.
1954  * @return Returns a new gum::ListIterator.
1955  */
1956  ListIterator< Val > operator-(difference_type i) noexcept;
1957 
1958  /// Adding gum::ListConstIterator operator support.
1959  /// @{
1960  using ListConstIterator< Val >::operator==;
1961  using ListConstIterator< Val >::operator!=;
1962  using ListConstIterator< Val >::operator*;
1963  using ListConstIterator< Val >::operator->;
1964  /// @}
1965 
1966  /**
1967  * @brief Gives access to the iterator's content.
1968  * @return Returns the iterator content.
1969  * @throw UndefinedIteratorValue Raised if the iterator is pointing toward
1970  * nothing.
1971  */
1972  Val& operator*();
1973 
1974  /**
1975  * @brief Dereferences the value pointed to by the iterator.
1976  * @return Returns the iterator content.
1977  * @throw UndefinedIteratorValue Raised if the iterator is pointing toward
1978  * nothing.
1979  */
1980  Val* operator->();
1981 
1982  /// @}
1983  };
1984 
1985  // ===========================================================================
1986  // === LIST CONST ITERATORS ===
1987  // ===========================================================================
1988  /**
1989  * @class ListConstIteratorSafe
1990  * @headerfile list.h <agrum/tools/core/list.h>
1991  * @ingroup list_group
1992  * @brief Safe const iterators for Lists.
1993  *
1994  * Class ListConstIteratorSafe implements safe const iterators for List.
1995  * However, developers may consider using List<x>::const_iterator_safe
1996  * instead of ListConstIteratorSafe<x>.
1997  *
1998  * These const iterators ensure that whenever they point to an element that
1999  * is being deleted from memory, their accessing this element will never
2000  * produce a segmentation fault but rather throw an exception. Similarly,
2001  * incrementing or decrementing an iterator pointing to a deleted element is
2002  * guaranteed to make the iterator point on the next (or preceding) element
2003  * that has not been deleted.
2004  *
2005  * @par Usage example:
2006  * @code
2007  * // create a list of strings
2008  * List<string> list;
2009  * list.pushBack ("toto"); list.pushBack ("titi");
2010  *
2011  * // parse all the elements of a list
2012  * for ( List<string>::const_iterator_safe iter = list.cbeginSafe ();
2013  * iter != list.cendSafe (); ++iter )
2014  * cerr << *iter << endl;
2015  * for ( List<string>::const_iterator_safe iter = list.cbeginSafe ();
2016  * iter != list.cendSafe (); iter += 2 ) // step = 2
2017  * cerr << *iter << endl;
2018  * for ( List<string>::const_iterator_safe iter = list.cbeginSafe ();
2019  * iter != list.cendSafe (); iter = iter + 2 ) // step = 2
2020  * cerr << *iter << endl;
2021  * for ( List<string>::const_iterator_safe iter = list.crbeginSafe ();
2022  * iter != list.crendSafe (); --iter )
2023  * cerr << *iter << endl;
2024  *
2025  * // use member size() of the strings
2026  * for ( List<string>::const_iterator_safe iter = list.cbeginSafe ();
2027  * iter != list.cendSafe (); ++iter )
2028  * cerr << iter->size() << endl;
2029  * @endcode
2030  *
2031  * @tparam Val The gum::List values type.
2032  */
2033  template < typename Val >
2034  class ListConstIteratorSafe {
2035  public:
2036  /// Types for STL compliance.
2037  /// @{
2038  using iterator_category = std::bidirectional_iterator_tag;
2039  using value_type = Val;
2040  using reference = Val&;
2041  using const_reference = const Val&;
2042  using pointer = Val*;
2043  using const_pointer = const Val*;
2044  using difference_type = std::ptrdiff_t;
2045  /// @}
2046 
2047  // ============================================================================
2048  /// @name Constructors / Destructors
2049  // ============================================================================
2050  /// @{
2051 
2052  /**
2053  * @brief Default constructor.
2054  *
2055  * Returns an iterator pointing toward nothing.
2056  */
2057  ListConstIteratorSafe() noexcept;
2058 
2059  /**
2060  * @brief Constructor for a begin.
2061  * @tparam Alloc The gum::List allocator.
2062  */
2063  template < typename Alloc >
2064  ListConstIteratorSafe(const List< Val, Alloc >& theList);
2065 
2066  /**
2067  * @brief Copy constructor.
2068  * @param src The gum::ListConstIteratorSafe to copy.
2069  */
2070  ListConstIteratorSafe(const ListConstIteratorSafe< Val >& src);
2071 
2072  /**
2073  * @brief Constructor for an iterator pointing to the \e ind_eltth element
2074  * of a List.
2075  * @param theList The list to iterate over.
2076  * @param ind_elt The iterator starting position.
2077  * @throw UndefinedIteratorValue Raised if the element does not exist in
2078  * the list.
2079  */
2080  template < typename Alloc >
2081  ListConstIteratorSafe(const List< Val, Alloc >& theList, Size ind_elt);
2082 
2083  /**
2084  * @brief Move constructor.
2085  * @param src The gum::ListConstIterator to move.
2086  */
2087  ListConstIteratorSafe(ListConstIteratorSafe< Val >&& src);
2088 
2089  /**
2090  * @brief Class Desctructor.
2091  */
2092  ~ListConstIteratorSafe();
2093 
2094  /// @}
2095  // ============================================================================
2096  /// @name Accessors / Modifiers
2097  // ============================================================================
2098  /// @{
2099 
2100  /**
2101  * @brief Makes the iterator point toward nothing.
2102  *
2103  * A method for detaching the iterator from the List it is attached to. It
2104  * is mainly used by the List when the latter is deleted while the iterator
2105  * is still alive. After being detached, the iterator does not point to any
2106  * element, i.e., trying to access its content will raise an exception.
2107  */
2108  void clear();
2109 
2110  /**
2111  * @brief Positions the iterator to the end of the list.
2112  */
2113  void setToEnd();
2114 
2115  /**
2116  * @brief Returns a bool indicating whether the iterator points to the end
2117  * of the list.
2118  * @return Returns a bool indicating whether the iterator points to the end
2119  * of the list.
2120  */
2121  bool isEnd() const;
2122 
2123  /// @}
2124  // ============================================================================
2125  /// @name Operators
2126  // ============================================================================
2127  /// @{
2128 
2129  /**
2130  * @brief Copy operator.
2131  *
2132  * The current iterator now points to the same element as iterator \e from.
2133  *
2134  * @param src The gum::ListConstIteratorSafe to copy.
2135  * @return Returns this gum::ListConstIteratorSafe.
2136  */
2137  ListConstIteratorSafe< Val >&
2138  operator=(const ListConstIteratorSafe< Val >& src);
2139 
2140  /**
2141  * @brief Move operator.
2142  *
2143  * @param src The gum::ListConstIteratorSafe to move.
2144  * @return Returns this gum::ListConstIteratorSafe.
2145  */
2146  ListConstIteratorSafe< Val >& operator=(ListConstIteratorSafe< Val >&& src);
2147 
2148  /**
2149  * @brief Makes the iterator point to the next element in the List.
2150  *
2151  * @code
2152  * for (iter = list.begin(); iter != list.end(); ++iter) { }
2153  * @endcode
2154  *
2155  * The above loop is guaranteed to parse the whole List as long as no
2156  * element is added to or deleted from the List while being in the loop.
2157  * Runs in constant time.
2158  *
2159  * @return Returns this gum::ListConstIteratorSafe.
2160  */
2161  ListConstIteratorSafe< Val >& operator++() noexcept;
2162 
2163  /**
2164  * @brief Makes the iterator point to i elements further in the List.
2165  * @param i The number of steps to move the iterator.
2166  * @return Returns this gum::ListConstIterator.
2167  */
2168  ListConstIteratorSafe< Val >& operator+=(difference_type i) noexcept;
2169 
2170  /**
2171  * @brief Makes the iterator point to the preceding element in the List.
2172  *
2173  * @code
2174  * for (iter = list.rbegin(); iter != list.rend(); --iter) { }
2175  * @endcode
2176  *
2177  * The above loop is guaranteed to parse the whole List as long as no
2178  * element is added to or deleted from the List while being in the loop.
2179  * Runs in constant time.
2180  *
2181  * @return Returns this gum::ListConstIteratorSafe.
2182  */
2183  ListConstIteratorSafe< Val >& operator--() noexcept;
2184 
2185  /**
2186  * @brief Makes the iterator point to i elements befor in the List.
2187  *
2188  * @param i The number of steps to move the iterator.
2189  * @return Returns this gum::ListConstIteratorSafe.
2190  */
2191  ListConstIteratorSafe< Val >& operator-=(difference_type i) noexcept;
2192 
2193  /**
2194  * @brief Returns a new iterator pointing to i further elements in the
2195  * gum::List.
2196  * @param i The number of steps to move the iterator.
2197  * @return Returns a new gum::ListConstIteratoSafe.
2198  */
2199  ListConstIteratorSafe< Val > operator+(difference_type i) noexcept;
2200 
2201  /**
2202  * @brief Returns a new iterator pointing to i preceding elements in the
2203  * gum::List.
2204  * @param i The number of steps to move the iterator.
2205  * @return Returns a new gum::ListConstIteratorSafe.
2206  */
2207  ListConstIteratorSafe< Val > operator-(difference_type i) noexcept;
2208 
2209  /**
2210  * @brief Checks whether two iterators point toward different elements.
2211  *
2212  * @warning the end and rend iterators are always equal, whatever the list
2213  * they belong to, i.e., \c list1.end() == \c list2.rend().
2214  *
2215  * @param src The gum::ListConstIteratorSafe to test for inequality.
2216  * @return Returns true if src and this are equal.
2217  */
2218  bool operator!=(const ListConstIteratorSafe< Val >& src) const;
2219 
2220  /**
2221  * @brief Checks whether two iterators point toward the same elements.
2222  *
2223  * @warning the end and rend iterators are always equal, whatever the list
2224  * they belong to, i.e., \c list1.end() == \c list2.rend().
2225  *
2226  * @param src The gum::ListConstIteratorSafe to test for equality.
2227  * @return Returns true if src and this are equal.
2228  */
2229  bool operator==(const ListConstIteratorSafe< Val >& src) const;
2230 
2231  /**
2232  * @brief Gives access to the content of the iterator.
2233  * @throw UndefinedIteratorValue Raised if the iterator points to nothing.
2234  * @return Returns the content of the iterator.
2235  */
2236  const Val& operator*() const;
2237 
2238  /**
2239  * @brief Dereferences the value pointed to by the iterator.
2240  * @throw UndefinedIteratorValue Raised if the iterator points to nothing.
2241  * @return Returns the value pointed to by the iterator.
2242  */
2243  const Val* operator->() const;
2244 
2245  /// @}
2246 
2247  private:
2248  /// class List must be a friend because it uses the getBucket method to
2249  /// speed up some processes.
2250  /// @{
2251  template < typename T, typename A >
2252  friend class List;
2253  friend class ListConstIterator< Val >;
2254  /// @}
2255 
2256  /// The list the iterator is pointing to.
2257  const List< Val, std::allocator< Val > >* list__{nullptr};
2258 
2259  /// The bucket in the chained list pointed to by the iterator.
2260  ListBucket< Val >* bucket__{nullptr};
2261 
2262  /// The bucket we should start from when we are pointing on a deleted
2263  /// bucket and we decide to do a ++.
2264  ListBucket< Val >* next_current_bucket__{nullptr};
2265 
2266  /// The bucket we should start from when we are pointing on a deleted
2267  /// bucket and we decide to do a --.
2268  ListBucket< Val >* prev_current_bucket__{nullptr};
2269 
2270  /// Indicates whether the bucket the iterator points to has been deleted.
2271  bool null_pointing__{false};
2272 
2273  /// Returns the bucket the iterator is pointing to.
2274  ListBucket< Val >* getBucket__() const noexcept;
2275 
2276  /// Remove the iterator for its list' safe iterators list.
2277  void removeFromSafeList__() const;
2278 
2279  /// Makes the iterator point to the next element in the List.
2280  ListConstIteratorSafe< Val >& opPlus__(Size i) noexcept;
2281 
2282  /// Makes the iterator point to i elements before in the List.
2283  ListConstIteratorSafe< Val >& opMinus__(Size i) noexcept;
2284  };
2285 
2286  /// For STL compliance, a distance operator.
2287  template < typename Val >
2288  typename ListConstIteratorSafe< Val >::difference_type
2289  operator-(const ListConstIteratorSafe< Val >& iter1,
2290  const ListConstIteratorSafe< Val >& iter2);
2291 
2292  // ===========================================================================
2293  // === LIST ITERATORS ===
2294  // ===========================================================================
2295 
2296  /**
2297  * @class ListIteratorSafe
2298  * @headerfile list.h <agrum/tools/core/list.h>
2299  * @ingroup basicstruct_group
2300  * @brief Safe iterators for Lists.
2301  *
2302  * Class ListIteratorSafe implements iterators for List. However, developers
2303  * may consider using List<x>::iterator_safe instead of ListIteratorSafe<x>.
2304  *
2305  * These iterators ensure that whenever they point to an element that is
2306  * being deleted from memory, their accessing this element will never produce
2307  * a segmentation fault but rather throw an exception. Similarly,
2308  * incrementing or decrementing an iterator pointing to a deleted element is
2309  * guaranteed to make the iterator point on the next (or preceding) element
2310  * that has not been deleted. This enables safely writing code like:
2311  *
2312  * @code
2313  * for ( iter = mylist.beginSafe (); iter != mylist.endSafe (); ++iter )
2314  * list.erase ( iter );
2315  * @endcode
2316  *
2317  * @par Usage example:
2318  * @code
2319  * // create a list of strings
2320  * List<string> list;
2321  * list.pushBack ("toto"); list.pushBack ("titi");
2322  *
2323  * // parse all the elements of a list
2324  * for (List<string>::iterator_safe iter = list.beginSafe();
2325  * iter != list.endSafe(); ++iter)
2326  * cerr << *iter << endl;
2327  * for ( List<string>::iterator_safe iter = list.beginSafe ();
2328  * iter != list.endSafe (); iter += 2 ) // step = 2
2329  * cerr << *iter << endl;
2330  * for ( List<string>::iterator_safe iter = list.beginSafe ();
2331  * iter != list.endSafe (); iter = iter + 2 ) // step = 2
2332  * cerr << *iter << endl;
2333  * for (List<string>::iterator_safe iter = list.rbeginSafe();
2334  * iter != list.rendSafe(); --iter)
2335  * cerr << *iter << endl;
2336  *
2337  * // use member size() of the strings
2338  * for (List<string>::iterator_safe iter = list.beginSafe();
2339  * iter != list.endSafe(); ++iter)
2340  * cerr << iter->size() << endl;
2341  * @endcode
2342  *
2343  * @tparam Val The gum::List values type.
2344  */
2345  template < typename Val >
2346  class ListIteratorSafe: public ListConstIteratorSafe< Val > {
2347  public:
2348  /// Types for STL compliance.
2349  /// @{
2350  using iterator_category = std::bidirectional_iterator_tag;
2351  using value_type = Val;
2352  using reference = Val&;
2353  using const_reference = const Val&;
2354  using pointer = Val*;
2355  using const_pointer = const Val*;
2356  using difference_type = std::ptrdiff_t;
2357  /// @}
2358 
2359  // ============================================================================
2360  /// @name Constructors / Destructors
2361  // ============================================================================
2362  /// @{
2363 
2364  /**
2365  * @brief Default constructor.
2366  *
2367  * Returns an iterator pointing toward nothing.
2368  */
2369  ListIteratorSafe() noexcept;
2370 
2371  /**
2372  * @brief Constructor for a begin.
2373  * @tparam Alloc The gum::List allocator.
2374  */
2375  template < typename Alloc >
2376  ListIteratorSafe(const List< Val, Alloc >& theList);
2377 
2378  /**
2379  * @brief Copy constructor.
2380  * @param src The gum::ListConstIteratorSafe to copy.
2381  */
2382  ListIteratorSafe(const ListIteratorSafe< Val >& src);
2383 
2384  /**
2385  * @brief Constructor for an iterator pointing to the \e ind_eltth element
2386  * of a List.
2387  * @param theList The list to iterate over.
2388  * @param ind_elt The iterator starting position.
2389  * @throw UndefinedIteratorValue Raised if the element does not exist in
2390  * the list.
2391  */
2392  template < typename Alloc >
2393  ListIteratorSafe(const List< Val, Alloc >& theList, Size ind_elt);
2394 
2395  /**
2396  * @brief Move constructor.
2397  * @param src The gum::ListConstIterator to move.
2398  */
2399  ListIteratorSafe(ListIteratorSafe< Val >&& src);
2400 
2401  /**
2402  * @brief Class Desctructor.
2403  */
2404  ~ListIteratorSafe();
2405 
2406  /// @}
2407  // ============================================================================
2408  /// @name Accessors / Modifiers
2409  // ============================================================================
2410  /// @{
2411 
2412  using ListConstIteratorSafe< Val >::clear;
2413  using ListConstIteratorSafe< Val >::setToEnd;
2414  using ListConstIteratorSafe< Val >::isEnd;
2415 
2416  /// @}
2417  // ============================================================================
2418  /// @name Operators
2419  // ============================================================================
2420  /// @{
2421 
2422  /**
2423  * @brief Copy operator.
2424  *
2425  * The current iterator now points to the same element as iterator \e from.
2426  *
2427  * @param src The gum::ListIteratorSafe to copy.
2428  * @return Returns this gum::ListIteratorSafe.
2429  */
2430  ListIteratorSafe< Val >& operator=(const ListIteratorSafe< Val >& src);
2431 
2432  /**
2433  * @brief Move operator.
2434  *
2435  * @param src The gum::ListIteratorSafe to move.
2436  * @return Returns this gum::ListIteratorSafe.
2437  */
2438  ListIteratorSafe< Val >& operator=(ListIteratorSafe< Val >&& src);
2439 
2440  /**
2441  * @brief Makes the iterator point to the next element in the List.
2442  *
2443  * @code
2444  * for (iter = list.begin(); iter != list.end(); ++iter) { }
2445  * @endcode
2446  *
2447  * The above loop is guaranteed to parse the whole List as long as no
2448  * element is added to or deleted from the List while being in the loop.
2449  * Runs in constant time.
2450  *
2451  * @return Returns this gum::ListIteratorSafe.
2452  */
2453  ListIteratorSafe< Val >& operator++() noexcept;
2454 
2455  /**
2456  * @brief Makes the iterator point to i elements further in the List.
2457  * @param i The number of steps to move the iterator.
2458  * @return Returns this gum::ListIterator.
2459  */
2460  ListIteratorSafe< Val >& operator+=(difference_type i) noexcept;
2461 
2462  /**
2463  * @brief Makes the iterator point to the preceding element in the List.
2464  *
2465  * @code
2466  * for (iter = list.rbegin(); iter != list.rend(); --iter) { }
2467  * @endcode
2468  *
2469  * The above loop is guaranteed to parse the whole List as long as no
2470  * element is added to or deleted from the List while being in the loop.
2471  * Runs in constant time.
2472  *
2473  * @return Returns this gum::ListIteratorSafe.
2474  */
2475  ListIteratorSafe< Val >& operator--() noexcept;
2476 
2477  /**
2478  * @brief Makes the iterator point to i elements befor in the List.
2479  *
2480  * @param i The number of steps to move the iterator.
2481  * @return Returns this gum::ListIteratorSafe.
2482  */
2483  ListIteratorSafe< Val >& operator-=(difference_type i) noexcept;
2484 
2485  /**
2486  * @brief Returns a new iterator pointing to i further elements in the
2487  * gum::List.
2488  * @param i The number of steps to move the iterator.
2489  * @return Returns a new gum::ListConstIteratoSafe.
2490  */
2491  ListIteratorSafe< Val > operator+(difference_type i) noexcept;
2492 
2493  /**
2494  * @brief Returns a new iterator pointing to i preceding elements in the
2495  * gum::List.
2496  * @param i The number of steps to move the iterator.
2497  * @return Returns a new gum::ListIteratorSafe.
2498  */
2499  ListIteratorSafe< Val > operator-(difference_type i) noexcept;
2500 
2501  /**
2502  * @brief Gives access to the content of the iterator.
2503  * @throw UndefinedIteratorValue Raised if the iterator points to nothing.
2504  * @return Returns the content of the iterator.
2505  */
2506  Val& operator*();
2507 
2508  /**
2509  * @brief Dereferences the value pointed to by the iterator.
2510  * @throw UndefinedIteratorValue Raised if the iterator points to nothing.
2511  * @return Returns the value pointed to by the iterator.
2512  */
2513  Val* operator->();
2514 
2515  /// Adding gum::ListConstIteratorSafe operator support.
2516  /// @{
2517  using ListConstIteratorSafe< Val >::operator!=;
2518  using ListConstIteratorSafe< Val >::operator==;
2519  using ListConstIteratorSafe< Val >::operator*;
2520  using ListConstIteratorSafe< Val >::operator->;
2521  /// @}
2522  };
2523 
2524 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2525  // constructor and destructor for the iterator that represents end and rend
2526  template <>
2527  ListConstIteratorSafe< Debug >::ListConstIteratorSafe() noexcept;
2528  template <>
2529  ListConstIteratorSafe< Debug >::~ListConstIteratorSafe();
2530  template <>
2531  ListConstIterator< Debug >::ListConstIterator() noexcept;
2532  template <>
2533  ListConstIterator< Debug >::~ListConstIterator() noexcept;
2534 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
2535 
2536 } /* namespace gum */
2537 
2538 
2539 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2540 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2541 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2542 extern template class gum::List< bool >;
2543 # endif
2544 # endif
2545 #endif
2546 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2547 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2548 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2549 extern template class gum::List< int >;
2550 # endif
2551 # endif
2552 #endif
2553 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2554 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2555 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2556 extern template class gum::List< unsigned int >;
2557 # endif
2558 # endif
2559 #endif
2560 
2561 
2562 // always include the implementation of the templates
2563 #include <agrum/tools/core/list_tpl.h>
2564 
2565 #endif /* GUM_LIST_H */