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