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