aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
hashTable.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Class hash tables iterators
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef GUM_HASHTABLE_H
30 #define GUM_HASHTABLE_H
31 
32 #include <limits>
33 
34 #include <cstddef>
35 #include <initializer_list>
36 #include <iostream>
37 #include <string>
38 #include <utility>
39 #include <vector>
40 
41 #include <agrum/agrum.h>
42 #include <agrum/tools/core/hashFunc.h>
43 
44 namespace gum {
45 
46 #ifndef DOXYGEN_SHOULD_SKIP_THIS
47 
48  // the templates used by this file
49  template < typename Key, typename Val, typename Alloc >
50  class HashTable;
51  template < typename Key, typename Val, typename Alloc >
52  class HashTableList;
53  template < typename Key, typename Val >
54  class HashTableIterator;
55  template < typename Key, typename Val >
56  class HashTableConstIterator;
57  template < typename Key, typename Val >
58  class HashTableIteratorSafe;
59  template < typename Key, typename Val >
60  class HashTableConstIteratorSafe;
61  template < typename T1, typename T2, typename Alloc >
62  class Bijection;
63 
64 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
65 
66  /**
67  * @class HashTableConst
68  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
69  * @brief Parameters specifying the default behavior of the hashtables.
70  * @ingroup hashtable_group
71  */
72  struct HashTableConst {
73  /**
74  * The default number of slots in hashtables. By default, hashtables can
75  * store up to thrice the number of slots elements before their size is
76  * increased To each slot corresponds a chained list of elements with the
77  * same hashed key.
78  */
79  static constexpr Size default_size{Size(4)};
80 
81  /**
82  * The average number of elements admissible by slots. Once this number is
83  * reached, the size of the hashtable is automatically doubled if we are in
84  * automatic resize mode.
85  */
86  static constexpr Size default_mean_val_by_slot{Size(3)};
87 
88  /**
89  * A Boolean indicating whether inserting too many values into the
90  * hashtable makes it resize itself automatically. true = automatic, false
91  * = manual.
92  */
93  static constexpr bool default_resize_policy{true};
94 
95  /**
96  * A Boolean indicating the default behavior when trying to insert more
97  * than once elements with identical keys. true = do not insert the
98  * elements but the first one and throw an exception after the first
99  * insertion; false = insert the elements without complaining.
100  */
101  static constexpr bool default_uniqueness_policy{true};
102  };
103 
104  // Doxygen raises warning with the following comment bloc
105  // @brief Prints the content of a gum::HashTableList in the stream.
106  // @ingroup hashtable_group
107  // @param s The s used to print the gum::HashTableList.
108  // @param list The gum::HashTableList to print.
109  // @return Returns the std::ostream s.
110  // @tparam Key The type of keys in the gum::HashTableList.
111  // @tparam Val The type of values in the gum::HashTableList.
112  // @tparam Alloc The gum::HashTableList allocator.
113 
114  /**
115  * @brief Prints the content of a gum::HashTableList in the stream.
116  * @ingroup hashtable_group
117  */
118  template < typename Key, typename Val, typename Alloc >
119  std::ostream& operator<<(std::ostream& s,
120  const HashTableList< Key, Val, Alloc >& list);
121 
122  // Doxygen raises warning with the following comment bloc
123  // @brief Prints the content of a gum::HashTableList with pointers key in the
124  // stream.
125  // @ingroup hashtable_group
126  // @param s The s used to print the gum::HashTableList.
127  // @param list The gum::HashTableList to print.
128  // @return Returns the std::ostream s.
129  // @tparam Key The type of keys in the gum::HashTableList.
130  // @tparam Val The type of values in the gum::HashTableList.
131  // @tparam Alloc The gum::HashTableList allocator.
132  //
133 
134  /**
135  * @brief Prints the content of a gum::HashTableList with pointers key in
136  * the stream.
137  * @ingroup hashtable_group
138  */
139  template < typename Key, typename Val, typename Alloc >
140  std::ostream& operator<<(std::ostream& s,
141  const HashTableList< Key*, Val, Alloc >& list);
142 
143  // Doxygen raises warning with the following comment bloc
144  // @brief Prints the content of a gum::HashTable in the stream.
145  // @ingroup hashtable_group
146  // @param s The stream used to print the gum::HashTable.
147  // @param table The gum::HashTable to print.
148  // @return Returns the std::ostream s.
149  // @tparam Key The type of keys in the gum::HashTable.
150  // @tparam Val The type of values in the gum::HashTable.
151  // @tparam Alloc The gum::HashTable allocator.
152 
153  /**
154  * @brief Prints the content of a gum::HashTable in the stream.
155  * @ingroup hashtable_group
156  */
157  template < typename Key, typename Val, typename Alloc >
158  std::ostream& operator<<(std::ostream& s,
159  const HashTable< Key, Val, Alloc >& table);
160 
161  // Doxygen raises warning with the following comment bloc
162  // @brief Prints the content of a gum::HashTable with pointers key in the
163  // stream.
164  // @ingroup hashtable_group
165  // @param s The stream used to print the gum::HashTable.
166  // @param table The gum::HashTable to print.
167  // @return Returns the std::ostream s.
168  // @tparam Key The type of keys in the gum::HashTable.
169  // @tparam Val The type of values in the gum::HashTable.
170  // @tparam Alloc The gum::HashTable allocator.
171 
172  /**
173  * @brief Prints the content of a gum::HashTable with pointers key in the
174  * stream.
175  * @ingroup hashtable_group
176  */
177  template < typename Key, typename Val, typename Alloc >
178  std::ostream& operator<<(std::ostream& s,
179  const HashTable< Key*, Val, Alloc >& table);
180 
181  // ===========================================================================
182  // === LISTS SPECIFIC FOR SAVING ELEMENTS IN HASHTABLES ===
183  // ===========================================================================
184 
185  /**
186  * @class HashTableBucket
187  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
188  * @brief A recipient for a pair of key value in a gum::HashTableList.
189  * @ingroup hashtable_group
190  *
191  * In aGrUM, hashtables are vectors of chained lists. Each list corresponds
192  * to the pairs (key,val) the keys of which have the same hashed value. Each
193  * box of the list is called a bucket. Lists are doubly linked so as to
194  * enable efficient begin/end iterators and efficient insert/erase
195  * operations.
196  *
197  * @tparam Key The type for keys in a gum::HashTable.
198  * @tparam Val The type for values in a gum::HashTable.
199  */
200  template < typename Key, typename Val >
201  struct HashTableBucket {
202  /// The pair stored in this bucket.
203  std::pair< const Key, Val > pair;
204 
205  /// A pointer toward the previous bucket in the gum::HashTableList.
206  HashTableBucket< Key, Val >* prev{nullptr};
207 
208  /// A pointer toward the next bucket in the gum::HashTableList.
209  HashTableBucket< Key, Val >* next{nullptr};
210 
211  /**
212  * @brief A dummy type for the emplace constructor.
213  * This type is used to prevent the Bucket emplace (int,...) to compile.
214  */
215  enum class Emplace
216  { EMPLACE };
217 
218  /**
219  * Class constructor.
220  */
221  HashTableBucket() {}
222 
223  /**
224  * Copy constructor.
225  * @param from The gum::HashTableBucket to copy.
226  */
227  HashTableBucket(const HashTableBucket< Key, Val >& from) : pair{from.pair} {}
228 
229  /**
230  * Constructor.
231  * @param k The key part of the pair.
232  * @param v The value part of the pair.
233  */
234  HashTableBucket(const Key& k, const Val& v) : pair{k, v} {}
235 
236  /**
237  * Constructor.
238  * @param k The key part of the pair.
239  * @param v The value part of the pair.
240  */
241  HashTableBucket(Key&& k, Val&& v) : pair{std::move(k), std::move(v)} {}
242 
243  /**
244  * Constructor.
245  * @param p The pair to store.
246  */
247  HashTableBucket(const std::pair< const Key, Val >& p) : pair(p) {}
248 
249  /**
250  * Constructor.
251  * @param p The pair to store.
252  */
253  HashTableBucket(std::pair< const Key, Val >&& p) : pair(std::move(p)) {}
254 
255  /**
256  * The emplace constructor.
257  * @param e The emplace.
258  * @param args A construction list.
259  * @tparam args The types in the construction list.
260  */
261  template < typename... Args >
262  HashTableBucket(Emplace e, Args&&... args) :
263  // emplace (universal) constructor
264  pair(std::forward< Args >(args)...) {}
265 
266  /**
267  * Class destructor.
268  */
269  ~HashTableBucket() {}
270 
271  /**
272  * @brief Returns the pair stored in this bucket.
273  * @return Returns the pair stored in this bucket.
274  */
275  std::pair< const Key, Val >& elt() { return pair; }
276 
277  /**
278  * @brief Returns the key part of the pair.
279  * @return Returns the key part of the pair.
280  */
281  Key& key() { return const_cast< Key& >(pair.first); }
282 
283  /**
284  * @brief Returns the value part of the pair.
285  * @return Returns value key part of the pair.
286  */
287  Val& val() { return pair.second; }
288  };
289 
290  // ===========================================================================
291  // === DOUBLY CHAINED LISTS FOR STORING ELEMENTS IN HASH TABLES ===
292  // ===========================================================================
293 
294  /**
295  * @class HashTableList
296  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
297  * @brief A chained list used by gum::HashTable.
298  * @ingroup hashtable_group
299  *
300  * @tparam Key The type for keys in a gum::HashTable.
301  * @tparam Val The type for values in a gum::HashTable.
302  * @tparam Alloc The gum::HashTable allocator.
303  */
304  template < typename Key, typename Val, typename Alloc >
305  class HashTableList {
306  public:
307  /// types for STL compliance
308  /// @{
309  using key_type = Key;
310  using mapped_type = Val;
311  using value_type = std::pair< const Key, Val >;
312  using reference = value_type&;
313  using const_reference = const value_type&;
314  using pointer = value_type*;
315  using const_pointer = const value_type*;
316  using size_type = Size;
317  using allocator_type = Alloc;
318  using Bucket = HashTableBucket< Key, Val >;
319  /// @}
320 
321  /// The Bucket allocator.
322  using BucketAllocator = typename Alloc::template rebind< Bucket >::other;
323 
324  // ============================================================================
325  /// @name Constructors / Destructors
326  // ============================================================================
327  /// @{
328 
329  /**
330  * @brief Basic constructor that creates an empty list.
331  *
332  * This is what is used basically by gum::HashTable.
333  *
334  * @warning If the allocator is not passed in argument, do not forget to
335  * use method setAllocator after the creation.
336  * @param allocator The gum::HashTableBucket allocator.
337  */
338  HashTableList(BucketAllocator* allocator = nullptr) noexcept;
339 
340  /**
341  * @brief Copy constructor.
342  *
343  * The new list and that which is copied do not share elements: the new
344  * list contains new instances of the keys and values stored in the copied
345  * list. Of course, if these values are pointers, the new values point
346  * toward the same elements.
347  *
348  * @warning Both from and this will share the same allocator.
349  * @param from The gum::HashTableList to copy.
350  */
351  HashTableList(const HashTableList< Key, Val, Alloc >& from);
352 
353  /**
354  * @brief Move constructor.
355  * @param from The gum::HashTableList to move.
356  */
357  HashTableList(HashTableList< Key, Val, Alloc >&& from) noexcept;
358 
359  /**
360  * @brief Class destructor.
361  */
362  ~HashTableList();
363 
364  /// @}
365  // ============================================================================
366  /// @name Operators
367  // ============================================================================
368  /// @{
369 
370  /**
371  * @brief Assignment operator.
372  *
373  * The new list and that which is copied do not share elements: the new
374  * list contains new instances of the keys and values stored in the copied
375  * list. Of course, if these values are pointers, the new values point
376  * toward the same elements.
377  *
378  * If some allocation problem occurs or if copying the Val elements cannot
379  * be performed properly, exceptions may be raised. In this case, the
380  * function guarantees that no memory leak occurs and that the list is kept
381  * in a coherent state (that of an empty list).
382  *
383  * @warning operator= does not change the current allocator of *this
384  * @param from The gum::HashTableList to copy.
385  * @return Returns this gum::HashTableList.
386  */
387  HashTableList< Key, Val, Alloc >&
388  operator=(const HashTableList< Key, Val, Alloc >& from);
389 
390  /**
391  * @brief Generalized assignment operator.
392  *
393  * The new list and that which is copied do not share elements: the new
394  * list contains new instances of the keys and values stored in the copied
395  * list. Of course, if these values are pointers, the new values point
396  * toward the same elements.
397  *
398  * If some allocation problem occurs or if copying the Val elements cannot
399  * be performed properly, exceptions may be raised. In this case, the
400  * function guarantees that no memory leak occurs and that the list is kept
401  * in a coherent state (that of an empty list).
402  *
403  * @warning operator= does not change the current allocator of *this
404  * @param from The gum::HashTableList to copy.
405  * @return Returns this gum::HashTableList.
406  */
407  template < typename OtherAlloc >
408  HashTableList< Key, Val, Alloc >&
409  operator=(const HashTableList< Key, Val, OtherAlloc >& from);
410 
411  /**
412  * @brief Move operator.
413  * @warning operator= does not change the current allocator of *this
414  * @param from The gum::HashTableList to copy.
415  * @return Returns this gum::HashTableList.
416  */
417  HashTableList< Key, Val, Alloc >&
418  operator=(HashTableList< Key, Val, Alloc >&& from) noexcept;
419 
420  /// @}
421  // ============================================================================
422  /// @name Accessors / Modifiers
423  // ============================================================================
424  /// @{
425 
426  /**
427  * @brief Function at returns the ith element in the current chained list.
428  *
429  * The first element has index 0.
430  * @param i The index to look up.
431  * @return Returns the value at index i.
432  * @throw NotFound Raised if the list has fewer than i elements.
433  */
434  value_type& at(Size i);
435 
436  /**
437  * @brief Function at returns the ith element in the current chained list.
438  *
439  * The first element has index 0.
440  * @param i The index to look up.
441  * @return Returns the value at index i.
442  * @throw NotFound Raised if the list has fewer than i elements.
443  */
444  const value_type& at(Size i) const;
445 
446  /**
447  * @brief Returns the value corresponding to a given key.
448  * @param key The key for which a value is returned.
449  * @return Returns the value corresponding to a given key.
450  * @throw NotFound is raised if the element cannot be found
451  */
452  mapped_type& operator[](const key_type& key);
453 
454  /**
455  * @brief Returns the value corresponding to a given key.
456  * @param key The key for which a value is returned.
457  * @return Returns the value corresponding to a given key.
458  * @throw NotFound is raised if the element cannot be found
459  */
460  const mapped_type& operator[](const key_type& key) const;
461 
462  /**
463  * @brief Returns true if a value with the given key exists.
464  *
465  * Checks whether there exists an element with a given key in the list.
466  * @param key The key to test for existence.
467  * @return Returns true if a value with the given key exists.
468  */
469  bool exists(const key_type& key) const;
470 
471  /**
472  * @brief Inserts a new element in the chained list.
473  *
474  * The element is inserted at the beginning of the list.
475  * @param new_elt The element to add in the gum::HashTableList.
476  */
477  void insert(Bucket* new_elt) noexcept;
478 
479  /**
480  * @brief Removes an element from this chained list.
481  * @param ptr The element to remove.
482  */
483  void erase(Bucket* ptr);
484 
485  /**
486  * @brief Removes all the elements of this chained list.
487  */
488  void clear();
489 
490  /**
491  * @brief Returns true if this chained list is empty.
492  * @return Returns true if this chained list is empty.
493  */
494  bool empty() const noexcept;
495 
496  /**
497  * @brief A method to get the bucket corresponding to a given key.
498  *
499  * This enables efficient removals of buckets.
500  * @param key The key of the bucket to return.
501  * @return Returns the buckket matching key.
502  */
503  Bucket* bucket(const Key& key) const;
504 
505  /**
506  * @brief Sets a new allocator.
507  * @param alloc The new allocator.
508  */
509  void setAllocator(BucketAllocator& alloc);
510 
511  /// @}
512 
513  private:
514  /// Friend for faster access.
515  /// @{
516  template < typename K, typename V, typename A >
517  friend class HashTableList;
518  friend class HashTable< Key, Val, Alloc >;
519  friend class HashTableIterator< Key, Val >;
520  friend class HashTableConstIterator< Key, Val >;
521  friend class HashTableIteratorSafe< Key, Val >;
522  friend class HashTableConstIteratorSafe< Key, Val >;
523  friend std::ostream& operator<<<>(std::ostream&,
524  const HashTableList< Key, Val, Alloc >&);
525  friend std::ostream& operator<<<>(std::ostream&,
526  const HashTableList< Key*, Val, Alloc >&);
527  friend std::ostream& operator<<<>(std::ostream&,
528  const HashTable< Key, Val, Alloc >&);
529  friend std::ostream& operator<<<>(std::ostream&,
530  const HashTable< Key*, Val, Alloc >&);
531  /// @}
532 
533  /// A pointer on the first element of the chained list.
534  HashTableBucket< Key, Val >* deb_list__{nullptr};
535 
536  /// A pointer on the last element of the chained list.
537  HashTableBucket< Key, Val >* end_list__{nullptr};
538 
539  /// The number of elements in the chained list.
540  Size nb_elements__{Size(0)};
541 
542  /// The allocator of the containing hashTable.
543  mutable BucketAllocator* alloc_bucket__;
544 
545  /**
546  * @brief A function used to perform copies of HashTableLists.
547  *
548  * This code is shared by the copy constructor and the copy operator. If it
549  * cannot perform the necessary allocations, no memory leak occurs and the
550  * list is set to the empty list.
551  *
552  * @param from The gum::HashTableList to copy.
553  * @tparam OtherAlloc The other gum::HashTableList allocator.
554  */
555  template < typename OtherAlloc >
556  void copy__(const HashTableList< Key, Val, OtherAlloc >& from);
557  };
558 
559  // ===========================================================================
560  // === GENERIC HASH TABLES ===
561  // ===========================================================================
562  /**
563  * @class HashTable
564  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
565  * @brief The class for generic Hash Tables.
566  * @ingroup basicstruct_group
567  * @ingroup hashtable_group
568  *
569  * In aGrUM, a hashtable is a vector of chained lists (collision problems are
570  * fixed by chaining). Each slot of the vector contains a list of elements
571  * sharing the same hashed value. To be computationally efficient, the hash
572  * table should not contain too many elements as compared to its number of
573  * slots. Therefore, it is sometimes useful to resize the chained lists
574  * vector. aGrUM's hash tables are designed to automatically double their
575  * size when there is in average more than 3 elements per slot. However, when
576  * memory consumption is a concern, this feature can be turned off either by
577  * passing false as an optional resize_pol argument to the constructor of the
578  * hash table or by using method setResizePolicy when the instance of the
579  * class has already been constructed. Similarly, the default number of
580  * slots of the hash table may be parameterized as an optional argument of
581  * the constructor (size_param). Beware: when inserting elements of a given
582  * class into a hash table, unless the element is an r-value, only a copy of
583  * this element is stored into the table (this is compulsory if the hashtable
584  * is to be generic and can be used to store both complex classes and
585  * built-in types like integers). HashTable have different kinds of
586  * iterators: HashTableIteratorSafe and HashTableConstIteratorSafe (a.k.a.
587  * HashTable<>::iterator_safe and HashTable<>::const_iterator_safe) allow
588  * safe parsing of the hash tables. By safe, we mean that whenever the
589  * element pointed to by such an iterator is removed from the hashtable,
590  * accessing it through the iterator (*iter) does not result in a
591  * segmentation fault but rather in an exception being thrown. This safety is
592  * ensured at a very low cost (actually, our experiments show that our
593  * HashTables and HashTable's safe iterators significantly outperform the
594  * standard library unordered_maps). Of course, if there is no possibility
595  * for an iterator to point to a deleted element, the user can use "unsafe"
596  * iterators HashTableIterator and HashTableConstIterator (a.k.a.
597  * HashTable<>::iterator and HashTable<>::const_iterator). These iterators
598  * are slightly faster than their safe counterparts. However, as in the
599  * standard library, accessing through them a deleted element usually results
600  * in a mess (most probably a segfault).
601  *
602  * @warning HashTables @b guarantee that any element stored within them will
603  * have the @b same @b location in memory until it is removed from the
604  * hashtable (and this holds whatever operation is performed on the hashtable
605  * like new insertions, deletions, resizing, etc.).
606  *
607  * @par Usage example:
608  * @code
609  * // creation of an empty hash table
610  * HashTable<int,string> table1;
611  *
612  * // insert two elements into the hash table
613  * table1.insert (10,"xxx");
614  * table1.insert (20,"yyy");
615  * table1.emplace (30,"zzz");
616  *
617  * // creation of a nonempty hashtable using initializer lists
618  * HashTable<int,bool> table { std::make_pair(3,true), std::make_pair(2,false)
619  * };
620  *
621  * // display the content of the hash table
622  * cerr << table1;
623  *
624  * // get the number of elements stored into the hash table
625  * cerr << "number of elements in table1 = " << table1.size () << endl;
626  *
627  * // create two copies of the hash table
628  * HashTable<int,string> table2, table3 = table1;
629  * table2 = table3;
630  *
631  * // get the element whose key is 10
632  * cerr << table1[10] << " = xxx" << endl;
633  *
634  * // check whether there exists an element with key 20
635  * if (table1.exists (20)) cerr << "element found" << endl;
636  *
637  * // transform the hashtable of string into a hashtable of int assuming f is
638  * // defined as: int f (const string& str) { return str.size (); }
639  * HashTable<int,int> table = table1.map (f);
640  *
641  * // remove two elements from table1 and table2
642  * table1.erase (10); // key = 10
643  * table1.eraseByVal ("yyy"); // val = "yyy"
644  * table2.clear ();
645  *
646  * // check whether the hash table is empty
647  * if (!table1.empty ()) cerr << "table not empty" << endl;
648  *
649  * // check whether hashtables contain the same elements
650  * if ((table1 == table2) && (table1 != table3))
651  * cerr << "check for equality/inequality" << endl;
652  *
653  * // parse the content of a hashtable using an unsafe iterator
654  * for (HashTable<int,string>::const_iterator iter = table1.cbegin();
655  * iter != table1.cend(); ++iter)
656  * cerr << *iter;
657  * HashTable<int,string>::iterator iter = table1.begin();
658  * iter += 2;
659  * cerr << iter.key () << " " << iter.val ();
660  *
661  * // use an iterator to point the element we wish to erase
662  * HashTable<int,string>::iterator_safe iterS = table1.beginSafe ();
663  * table1.erase ( table1.beginSafe () + 4 );
664  * table1.erase ( iterS ); // this is safe because the iterator is safe
665  *
666  * // check for iterator's safety
667  * for (HashTable<int,string>::iterator_safe iter = table1.beginSafe ();
668  * iter != table1.endSafe (); ++iter )
669  * table1.eraseByVal ( *iter );
670  * @endcode
671  *
672  * @tparam Key The type for keys in a gum::HashTable.
673  * @tparam Val The type for values in a gum::HashTable.
674  * @tparam Alloc The gum::HashTable allocator.
675  */
676  template < typename Key,
677  typename Val,
678  typename Alloc = std::allocator< std::pair< Key, Val > > >
679  class HashTable {
680  public:
681  /// Types for STL compliance.
682  /// @{
683  using key_type = Key;
684  using mapped_type = Val;
685  using value_type = std::pair< const Key, Val >;
686  using reference = value_type&;
687  using const_reference = const value_type&;
688  using pointer = value_type*;
689  using const_pointer = const value_type*;
690  using size_type = Size;
691  using difference_type = std::ptrdiff_t;
692  using allocator_type = Alloc;
693  using iterator = HashTableIterator< Key, Val >;
694  using const_iterator = HashTableConstIterator< Key, Val >;
695  using iterator_safe = HashTableIteratorSafe< Key, Val >;
696  using const_iterator_safe = HashTableConstIteratorSafe< Key, Val >;
697  /// @}
698 
699  /// The buckets where data are stored.
700  using Bucket = HashTableBucket< Key, Val >;
701 
702  /// The Bucket allocator.
703  using BucketAllocator = typename Alloc::template rebind< Bucket >::other;
704 
705  // ============================================================================
706  /// @name Constructors / Destructors
707  // ============================================================================
708  /// @{
709 
710  /**
711  * @brief Default constructor.
712  *
713  * The true capacity (vector's size) of the hashtable will be the lowest
714  * number greater than or equal to size_param that is also a power of 2.
715  * The second optional argument is the resizing policy. By default, each
716  * time there is an average of 3 elements by node, the size of the
717  * hashtable is automatically multiplied by 2. But the user may pass false
718  * as argument to resize_pol to disable this feature.
719  *
720  * @param size_param The initial size of the gum::HashTable.
721  * @param resize_pol The policy for resizing the hashtable when new
722  * elements are added (possible values: true = automatic resize and false =
723  * manual resize).
724  * @param key_uniqueness_pol Uniqueness policy : should we prevent inserting
725  * the same key more than once in the table?
726  */
727  explicit HashTable(Size size_param = HashTableConst::default_size,
728  bool resize_pol = HashTableConst::default_resize_policy,
729  bool key_uniqueness_pol
730  = HashTableConst::default_uniqueness_policy);
731 
732  /**
733  * @brief Initializer list constructor.
734  * @param list The initialized list.
735  */
736  explicit HashTable(std::initializer_list< std::pair< Key, Val > > list);
737 
738  /**
739  * @brief Copy constructor.
740  *
741  * This creates a new hashtable the content of which is similar to that of
742  * the table passed in argument. Beware: similar does not mean that both
743  * tables share the same objects, but rather that the objects stored in the
744  * newly created table are copies of those of the table passed in argument.
745  * In particular, the new hash table inherits the parameters (resize
746  * policy, uniqueness policy) of table 'from'.
747  *
748  * @param from The gum::HashTable to copy.
749  */
750  HashTable(const HashTable< Key, Val, Alloc >& from);
751 
752  /**
753  * @brief Generalized copy constructor.
754  *
755  * This creates a new hashtable the content of which is similar to that of
756  * the table passed in argument. Beware: similar does not mean that both
757  * tables share the same objects, but rather that the objects stored in the
758  * newly created table are copies of those of the table passed in argument.
759  * In particular, the new hash table inherits the parameters (resize
760  * policy, uniqueness policy) of table 'table'
761  *
762  * @param from The gum::HashTable to copy.
763  */
764  template < typename OtherAlloc >
765  HashTable(const HashTable< Key, Val, OtherAlloc >& from);
766 
767  /**
768  * @brief Move constructor.
769  * @param from The gum::HashTable to move.
770  */
771  HashTable(HashTable< Key, Val, Alloc >&& from);
772 
773  /**
774  * @brief Class destructor.
775  */
776  ~HashTable();
777 
778  /// @}
779  // ============================================================================
780  /// @name Iterators
781  // ============================================================================
782  /// @{
783 
784  /**
785  * @brief Returns the unsafe iterator pointing to the end of the hashtable.
786  *
787  * Unsafe iterators are slightly faster than safe iterators. However, BE
788  * CAREFUL when using them: they should ONLY be used when you have the
789  * guarantee that they will never point to a deleted element. If unsure,
790  * prefer using the safe iterators (those are only slightly slower).
791  *
792  * @return Returns the unsafe iterator pointing to the end of the hashtable.
793  */
794  const iterator& end() noexcept;
795 
796  /**
797  * @brief Returns the unsafe const_iterator pointing to the end of the
798  * hashtable.
799  *
800  * Unsafe iterators are slightly faster than safe iterators. However, BE
801  * CAREFUL when using them: they should ONLY be used when you have the
802  * guarantee that they will never point to a deleted element. If unsure,
803  * prefer using the safe iterators (those are only slightly slower).
804  *
805  * @return Returns the unsafe const_iterator pointing to the end of the
806  * hashtable.
807  */
808  const const_iterator& end() const noexcept;
809 
810  /**
811  * @brief Returns the unsafe const_iterator pointing to the end of the
812  * hashtable.
813  *
814  * Unsafe iterators are slightly faster than safe iterators. However,
815  * BE CAREFUL when using them: they should ONLY be used when you have the
816  * guarantee that they will never point to a deleted element. If unsure,
817  * prefer using the safe iterators (those are only slightly slower).
818  *
819  * @return Returns the unsafe const_iterator pointing to the end of the
820  * hashtable.
821  */
822  const const_iterator& cend() const noexcept;
823 
824  /**
825  * @brief Returns an unsafe iterator pointing to the beginning of the
826  * hashtable.
827  *
828  * Unsafe iterators are slightly faster than safe iterators. However,
829  * BE CAREFUL when using them: they should ONLY be used when you have the
830  * guarantee that they will never point to a deleted element. If unsure,
831  * prefer using the safe iterators (those are only slightly slower).
832  *
833  * @return Returns an unsafe iterator pointing to the beginning of the
834  * hashtable.
835  */
836  iterator begin();
837 
838  /**
839  * @brief Returns an unsafe const_iterator pointing to the beginning of the
840  * hashtable.
841  *
842  * Unsafe iterators are slightly faster than safe iterators. However,
843  * BE CAREFUL when using them: they should ONLY be used when you have the
844  * guarantee that they will never point to a deleted element. If unsure,
845  * prefer using the safe iterators (those are only slightly slower).
846  *
847  * @return Returns an unsafe const_iterator pointing to the beginning of
848  * the hashtable.
849  */
850  const_iterator begin() const;
851 
852  /**
853  * @brief Returns an unsafe const_iterator pointing to the beginning of the
854  * hashtable.
855  *
856  * Unsafe iterators are slightly faster than safe iterators. However,
857  * BE CAREFUL when using them: they should ONLY be used when you have the
858  * guarantee that they will never point to a deleted element. If unsure,
859  * prefer using the safe iterators (those are only slightly slower).
860  *
861  * @return Returns an unsafe const_iterator pointing to the beginning of the
862  * hashtable.
863  */
864  const_iterator cbegin() const;
865 
866  /**
867  * @brief Returns the safe iterator pointing to the end of the hashtable.
868  *
869  * Safe iterators are slightly slower than unsafe ones but they guarantee
870  * that you will never get a segfault if they try to access to a deleted
871  * element or if they try a ++ operation from a deleted element.
872  *
873  * @return Returns the safe iterator pointing to the end of the hashtable.
874  */
875  const iterator_safe& endSafe() noexcept;
876 
877  /**
878  * @brief Returns the safe const_iterator pointing to the end of the
879  * hashtable.
880  *
881  * Safe iterators are slightly slower than unsafe ones but they guarantee
882  * that you will never get a segfault if they try to access to a deleted
883  * element or if they try a ++ operation from a deleted element.
884  *
885  * @return Returns the safe const_iterator pointing to the end of the
886  * hashtable.
887  */
888  const const_iterator_safe& endSafe() const noexcept;
889 
890  /**
891  * @brief Returns the safe const_iterator pointing to the end of the
892  * hashtable.
893  *
894  * Safe iterators are slightly slower than unsafe ones but they guarantee
895  * that you will never get a segfault if they try to access to a deleted
896  * element or if they try a ++ operation from a deleted element.
897  *
898  * @return Returns the safe const_iterator pointing to the end of the
899  * hashtable.
900  */
901  const const_iterator_safe& cendSafe() const noexcept;
902 
903  /**
904  * @brief Returns the safe iterator pointing to the beginning of the
905  * hashtable.
906  *
907  * Safe iterators are slightly slower than unsafe ones but they guarantee
908  * that you will never get a segfault if they try to access to a deleted
909  * element or if they try a ++ operation from a deleted element.
910  *
911  * @return Returns the safe iterator pointing to the beginning of the
912  * hashtable.
913  */
914  iterator_safe beginSafe();
915 
916  /**
917  * @brief Returns the safe const_iterator pointing to the beginning of the
918  * hashtable.
919  *
920  * Safe iterators are slightly slower than unsafe ones but they guarantee
921  * that you will never get a segfault if they try to access to a deleted
922  * element or if they try a ++ operation from a deleted element.
923  *
924  * @return Returns the safe const_iterator pointing to the beginning of the
925  * hashtable.
926  */
927  const_iterator_safe beginSafe() const;
928 
929  /**
930  * @brief Returns the safe const_iterator pointing to the beginning of the
931  * hashtable.
932  *
933  * Safe iterators are slightly slower than unsafe ones but they guarantee
934  * that you will never get a segfault if they try to access to a deleted
935  * element or if they try a ++ operation from a deleted element.
936  *
937  * @return Returns the safe const_iterator pointing to the beginning of the
938  * hashtable.
939  */
940  const_iterator_safe cbeginSafe() const;
941 
942  /**
943  * @brief Returns the end iterator for other classes' statics (read the
944  * detailed description of this method).
945  *
946  * To reduce memory consumption of hash tables (which are heavily used in
947  * aGrUM) while allowing fast for(iter=begin(); iter!=end();++iter) loops,
948  * end iterators are created just once as a static member of a non-template
949  * hashtable. While this scheme is efficient and it works quite effectively
950  * when manipulating hashtables, it has a drawback: other classes with
951  * static members using the HashTable's end() iterator may fail to work due
952  * to the well known "static initialization order fiasco" (see Marshall
953  * Cline's C++ FAQ for more details about this C++ feature). OK, so what is
954  * the problem? Consider for instance class Set. A Set contains a hashtable
955  * that stores all its elements in a convenient way. To reduce memory
956  * consumption, Set::end iterator is a static member that is initialized
957  * with a HashTable's end iterator. If the compiler decides to initialize
958  * Set::end before initializing HashTable::end, then Set::end will be in an
959  * incoherent state. Unfortunately, we cannot know for sure in which order
960  * static members will be initialized (the order is a compiler's decision).
961  * Hence, we shall enforce the fact that HashTable::end is initialized
962  * before Set::end. Using method HashTable::end4Statics will ensure this
963  * fact: it uses the C++ "construct on first use" idiom (see the C++ FAQ)
964  * that ensures that the order fiasco is avoided. More precisely,
965  * end4Statics initializes a global variable that is the very end iterator
966  * used by all hashtables. Now, this induces a small overhead. So, we also
967  * provide a HashTable::end() method that returns the end iterator without
968  * this small overhead, but assuming that function end4Statics has already
969  * been called once (which is always the case) when a hashtable has been
970  * created.
971  *
972  * So, to summarize: when initializing static members, use end4Statics()
973  * rather than end(). In all the other cases, use simply the usual method
974  * end().
975  *
976  * @return Returns the end iterator for other classes' statics (read the
977  * detailed description of this method).
978  */
979  static const iterator& end4Statics();
980 
981  /**
982  * @brief Returns the end iterator for other classes' statics (read the
983  * detailed description of this method).
984  *
985  * To reduce memory consumption of hash tables (which are heavily used in
986  * aGrUM) while allowing fast for(iter=begin(); iter!=end();++iter) loops,
987  * end iterators are created just once as a static member of a non-template
988  * hashtable. While this scheme is efficient and it works quite effectively
989  * when manipulating hashtables, it has a drawback: other classes with
990  * static members using the HashTable's end() iterator may fail to work due
991  * to the well known "static initialization order fiasco" (see Marshall
992  * Cline's C++ FAQ for more details about this C++ feature). OK, so what is
993  * the problem? Consider for instance class Set. A Set contains a hashtable
994  * that stores all its elements in a convenient way. To reduce memory
995  * consumption, Set::end iterator is a static member that is initialized
996  * with a HashTable's end iterator. If the compiler decides to initialize
997  * Set::end before initializing HashTable::end, then Set::end will be in an
998  * incoherent state. Unfortunately, we cannot know for sure in which order
999  * static members will be initialized (the order is a compiler's decision).
1000  * Hence, we shall enforce the fact that HashTable::end is initialized
1001  * before Set::end. Using method HashTable::end4Statics will ensure this
1002  * fact: it uses the C++ "construct on first use" idiom (see the C++ FAQ)
1003  * that ensures that the order fiasco is avoided. More precisely,
1004  * end4Statics initializes a global variable that is the very end iterator
1005  * used by all hashtables. Now, this induces a small overhead. So, we also
1006  * provide a HashTable::end() method that returns the end iterator without
1007  * this small overhead, but assuming that function end4Statics has already
1008  * been called once (which is always the case) when a hashtable has been
1009  * created.
1010  *
1011  * So, to summarize: when initializing static members, use
1012  * constEnd4Statics() rather than cend(). In all the other cases, use
1013  * simply the usual method cend().
1014  *
1015  * @return Returns the end iterator for other classes' statics (read the
1016  * detailed description of this method).
1017  */
1018  static const const_iterator& constEnd4Statics();
1019 
1020  /**
1021  * @brief Returns the end iterator for other classes' statics (read the
1022  * detailed description of this method).
1023  *
1024  * To reduce memory consumption of hash tables (which are heavily used in
1025  * aGrUM) while allowing fast for(iter=begin(); iter!=end();++iter) loops,
1026  * end iterators are created just once as a static member of a non-template
1027  * hashtable. While this scheme is efficient and it works quite effectively
1028  * when manipulating hashtables, it has a drawback: other classes with
1029  * static members using the HashTable's end() iterator may fail to work due
1030  * to the well known "static initialization order fiasco" (see Marshall
1031  * Cline's C++ FAQ for more details about this C++ feature). OK, so what is
1032  * the problem? Consider for instance class Set. A Set contains a hashtable
1033  * that stores all its elements in a convenient way. To reduce memory
1034  * consumption, Set::end iterator is a static member that is initialized
1035  * with a HashTable's end iterator. If the compiler decides to initialize
1036  * Set::end before initializing HashTable::end, then Set::end will be in an
1037  * incoherent state. Unfortunately, we cannot know for sure in which order
1038  * static members will be initialized (the order is a compiler's decision).
1039  * Hence, we shall enforce the fact that HashTable::end is initialized
1040  * before Set::end. Using method HashTable::end4Statics will ensure this
1041  * fact: it uses the C++ "construct on first use" idiom (see the C++ FAQ)
1042  * that ensures that the order fiasco is avoided. More precisely,
1043  * end4Statics initializes a global variable that is the very end iterator
1044  * used by all hashtables. Now, this induces a small overhead. So, we also
1045  * provide a HashTable::end() method that returns the end iterator without
1046  * this small overhead, but assuming that function end4Statics has already
1047  * been called once (which is always the case) when a hashtable has been
1048  * created.
1049  *
1050  * So, to summarize: when initializing static members, use
1051  * endSafe4Statics() rather than endSafe(). In all the other cases, use
1052  * simply the usual method endSafe().
1053  *
1054  * @return Returns the end iterator for other classes' statics (read the
1055  * detailed description of this method).
1056  */
1057  static const iterator_safe& endSafe4Statics();
1058 
1059  /**
1060  * @brief Returns the end iterator for other classes' statics (read the
1061  * detailed description of this method).
1062  *
1063  * To reduce memory consumption of hash tables (which are heavily used in
1064  * aGrUM) while allowing fast for(iter=begin(); iter!=end();++iter) loops,
1065  * end iterators are created just once as a static member of a non-template
1066  * hashtable. While this scheme is efficient and it works quite effectively
1067  * when manipulating hashtables, it has a drawback: other classes with
1068  * static members using the HashTable's end() iterator may fail to work due
1069  * to the well known "static initialization order fiasco" (see Marshall
1070  * Cline's C++ FAQ for more details about this C++ feature). OK, so what is
1071  * the problem? Consider for instance class Set. A Set contains a hashtable
1072  * that stores all its elements in a convenient way. To reduce memory
1073  * consumption, Set::end iterator is a static member that is initialized
1074  * with a HashTable's end iterator. If the compiler decides to initialize
1075  * Set::end before initializing HashTable::end, then Set::end will be in an
1076  * incoherent state. Unfortunately, we cannot know for sure in which order
1077  * static members will be initialized (the order is a compiler's decision).
1078  * Hence, we shall enforce the fact that HashTable::end is initialized
1079  * before Set::end. Using method HashTable::end4Statics will ensure this
1080  * fact: it uses the C++ "construct on first use" idiom (see the C++ FAQ)
1081  * that ensures that the order fiasco is avoided. More precisely,
1082  * end4Statics initializes a global variable that is the very end iterator
1083  * used by all hashtables. Now, this induces a small overhead. So, we also
1084  * provide a HashTable::end() method that returns the end iterator without
1085  * this small overhead, but assuming that function end4Statics has already
1086  * been called once (which is always the case) when a hashtable has been
1087  * created.
1088  *
1089  * So, to summarize: when initializing static members, use
1090  * constEndSafe4Statics() rather than cendSafe(). In all the other cases,
1091  * use simply the usual method cendSafe().
1092  *
1093  * @return Returns the end iterator for other classes' statics (read the
1094  * detailed description of this method).
1095  */
1096  static const const_iterator_safe& constEndSafe4Statics();
1097 
1098  /// @}
1099  // ============================================================================
1100  /// @name Operators
1101  // ============================================================================
1102  /// @{
1103 
1104  /**
1105  * @brief Copy operator.
1106  *
1107  * The copy operators ensures that whenever a memory allocation problem
1108  * occurs, no memory leak occurs as well and it also guarantees that in
1109  * this case the hashtable returned is in a coherent state (it is an empty
1110  * hashtable). Note that the copy not only involves copying pairs
1111  * (key,value) but also the copy of the resize and key uniqueness policies.
1112  *
1113  * @param from The gum::HashTable to copy.
1114  * @return Returns this gum::HashTable.
1115  */
1116  HashTable< Key, Val, Alloc >&
1117  operator=(const HashTable< Key, Val, Alloc >& from);
1118 
1119  /**
1120  * @brief Generalized copy operator.
1121  *
1122  * The copy operators ensures that whenever a memory allocation problem
1123  * occurs, no memory leak occurs as well and it also guarantees that in
1124  * this case the hashtable returned is in a coherent state (it is an empty
1125  * hashtable). Note that the copy not only involves copying pairs
1126  * (key,value) but also the copy of the resize and key uniqueness policies.
1127  *
1128  * @param from The gum::HashTable to copy.
1129  * @return Returns this gum::HashTable.
1130  */
1131  template < typename OtherAlloc >
1132  HashTable< Key, Val, Alloc >&
1133  operator=(const HashTable< Key, Val, OtherAlloc >& from);
1134 
1135  /**
1136  * Move operator.
1137  *
1138  * @param from The gum::HashTable to move.
1139  * @return Returns this gum::HashTable.
1140  */
1141  HashTable< Key, Val, Alloc >& operator=(HashTable< Key, Val, Alloc >&& from);
1142 
1143  /**
1144  * @brief Returns a reference on the value the key of which is passed in
1145  * argument.
1146  *
1147  * In case of multiple identical keys in the hash table, the first value
1148  * encountered is returned. The method runs in constant time.
1149  *
1150  * @param key The key of the value to return.
1151  * @return Returns the value matching the given key.
1152  * @throws NotFound exception is thrown if the element cannot be found.
1153  */
1154  Val& operator[](const Key& key);
1155 
1156  /// returns a reference on the value the key of which is passed in argument
1157  /** In case of multiple identical keys in the hash table, the first value
1158  * encountered is returned. The method runs in constant time.
1159  * @throws NotFound exception is thrown if the element cannot be found. */
1160  const Val& operator[](const Key& key) const;
1161 
1162  /**
1163  * @brief Checks whether two hashtables contain the same elements.
1164  *
1165  * Two hashtables are considered equal if they contain the identical pairs
1166  * (key,val). Two pairs are identical if their keys have the same hashed
1167  * value, these two keys are equal in the sense of ==, and their val's are
1168  * also equal in the sense of ==.
1169  *
1170  * @param from The gum::HashTable to test for equality.
1171  * @return True if this and from are equal.
1172  */
1173  template < typename OtherAlloc >
1174  bool operator==(const HashTable< Key, Val, OtherAlloc >& from) const;
1175 
1176  ///
1177  /**
1178  * @brief Checks whether two hashtables contain different sets of elements.
1179  *
1180  * Two hashtables are considered different if they contain different pairs
1181  * (key,val). Two pairs are different if their keys have different hashed
1182  * values, or if they are different in the sense of !=, or if their val's
1183  * are different in the sense of !=.
1184  *
1185  * @param from The gum::HashTable to test for inequality.
1186  * @return True if this and from are not equal.
1187  */
1188  template < typename OtherAlloc >
1189  bool operator!=(const HashTable< Key, Val, OtherAlloc >& from) const;
1190 
1191  /// @}
1192  // ============================================================================
1193  /// @name Fine tuning
1194  // ============================================================================
1195  /// @{
1196 
1197  /**
1198  * @brief Returns the number of slots in the 'nodes' vector of the
1199  * hashtable.
1200  *
1201  * The method runs in constant time.
1202  *
1203  * @return Returns the number of slots in the 'nodes' vector of the
1204  * hashtable.
1205  */
1206  Size capacity() const noexcept;
1207 
1208  ///
1209  /**
1210  * @brief Changes the number of slots in the 'nodes' vector of the hash
1211  * table.
1212  *
1213  * Usually, method resize enables the user to resize manually the
1214  * hashtable. When in automatic resize mode, the function will actually
1215  * resize the table only if resizing policy is compatible with the new
1216  * size, i.e., the new size is not so small that there would be too many
1217  * elements per slot in the table (this would lead to a significant loss in
1218  * performance). However, the resizing policy may be changed by using
1219  * method setResizePolicy. The method runs in linear time in the size of
1220  * the hashtable. Upon memory allocation problem, the fuction guarantees
1221  * that no data is lost and that the hash table and its iterators are in a
1222  * coherent state. In such a case, a bad_alloc exception is thrown.
1223  *
1224  * @param new_size The new number of slots in the gum::HashTable.
1225  */
1226  void resize(Size new_size);
1227 
1228  /**
1229  * @brief Enables the user to change dynamically the resizing policy.
1230  *
1231  * In most cases, this should be useless. However, when available memory
1232  * becomes rare, avoiding automatic resizing may speed-up new insertions in
1233  * the table.
1234  *
1235  * @warning This function never resizes the hashtable by itself: even if
1236  * you set the new policy to be an automatic resizing and the number of
1237  * elements in the table is sufficiently high that we should resize the
1238  * table, function setResizePolicy won't perform this resizing. The
1239  * resizing will happen only if you insert a new element or if use method
1240  * resize.
1241  *
1242  * @param new_policy The new resizing policy, true implies automatic
1243  * resizing.
1244  */
1245  void setResizePolicy(const bool new_policy) noexcept;
1246 
1247  /**
1248  * @brief Returns the current resizing policy.
1249  * @return Returns the current resizing policy.
1250  */
1251  bool resizePolicy() const noexcept;
1252 
1253  /**
1254  * @brief Enables the user to change dynamically the policy for checking
1255  * whether there can exist several elements in the table with identical
1256  * keys.
1257  *
1258  * By default, we should always check that there does not exist duplicate
1259  * keys. However, this test slows the insertion of elements in the table.
1260  * So, when we know for sure that no duplicate key will be entered into the
1261  * table, we may avoid uniqueness checks.
1262  *
1263  * @warning When setting the key policy to "uniqueness", the function does
1264  * not check whether there are already different elements with identical
1265  * keys in the table. It thus only ensures that elements inserted from now
1266  * on will have unique keys.
1267  */
1268  void setKeyUniquenessPolicy(const bool new_policy) noexcept;
1269 
1270  /**
1271  * @brief Returns the current checking policy.
1272  * @return Returns the current checking policy.
1273  */
1274  bool keyUniquenessPolicy() const noexcept;
1275 
1276  /// @}
1277  // ============================================================================
1278  /// @name Accessors / Modifiers
1279  // ============================================================================
1280  /// @{
1281 
1282  /**
1283  * @brief Returns the number of elements stored into the hashtable.
1284  *
1285  * The method runs in constant time.
1286  *
1287  * @return Returns the number of elements stored into the hashtable.
1288  */
1289  Size size() const noexcept;
1290 
1291  /**
1292  * @brief Checks whether there exists an element with a given key in the
1293  * hashtable.
1294  *
1295  * The method runs in average in constant time if the resizing policy
1296  * is set.
1297  *
1298  * @param key The key to test for existence.
1299  * @return True if key is in this gum::HashTable.
1300  */
1301  bool exists(const Key& key) const;
1302 
1303  /**
1304  * @brief Adds a new element (actually a copy of this element) into the
1305  * hash table.
1306  *
1307  * If there already exists an element with the same key in the table and the
1308  * uniqueness policy prevents multiple identical keys to belong to the same
1309  * hashtable, an exception DuplicateElement is thrown. If the uniqueness
1310  * policy is not set, the method runs in the worst case in constant time,
1311  * else if the automatic resizing policy is set, it runs in constant time in
1312  * average linear in the number of elements by slot. @return As only a copy
1313  * of val is inserted into the hashtable, the method returns a reference on
1314  * a copy of the pair (key,val). @throw DuplicateElement is thrown when
1315  * attempting to insert a pair (key,val) in a hash table containing already
1316  * a pair with the same key and when the hash table's uniqueness policy is
1317  * set.
1318  *
1319  * @param key The key to add.
1320  * @param val The value to add.
1321  * @return The value added by copy to this gum::HashTable.
1322  */
1323  value_type& insert(const Key& key, const Val& val);
1324 
1325  /**
1326  * @brief Moves a new element in the hash table.
1327  *
1328  * If there already exists an element with the same key in the table and
1329  * the uniqueness policy prevents multiple identical keys to belong to the
1330  * same hashtable, an exception DuplicateElement is thrown. If the
1331  * uniqueness policy is not set, the method runs in the worst case in
1332  * constant time, else if the automatic resizing policy is set, it runs in
1333  * constant time in average linear in the number of elements by slot.
1334  * @return a reference to the pair (key,val) in the hashtable. @throw
1335  * DuplicateElement is thrown when attempting to insert a pair (key,val) in
1336  * a hash table containing already a pair with the same key and when the
1337  * hash table's uniqueness policy is set.
1338  *
1339  * @param key The key to move.
1340  * @param val The value to move.
1341  * @return The value moved to this gum::HashTable.
1342  */
1343  value_type& insert(Key&& key, Val&& val);
1344 
1345  /**
1346  * @brief Adds a new element (actually a copy of this element) into the
1347  * hash table.
1348  *
1349  * If there already exists an element with the same key in the table and
1350  * the uniqueness policy prevents multiple identical keys to belong to the
1351  * same hashtable, an exception DuplicateElement is thrown. If the
1352  * uniqueness policy is not set, the method runs in the worst case in
1353  * constant time, else if the automatic resizing policy is set, it runs in
1354  * constant time in average linear in the number of elements by slot.
1355  * @return As only a copy of val is inserted into the hashtable, the method
1356  * returns a reference on a copy of the pair (key,val). @throw
1357  * DuplicateElement is thrown when attempting to insert a pair (key,val) in
1358  * a hash table containing already a pair with the same key and when the
1359  * hash table's uniqueness policy is set.
1360  *
1361  * @param elt The pair of key value to add.
1362  * @return The value added by copy to this gum::HashTable.
1363  */
1364  value_type& insert(const std::pair< Key, Val >& elt);
1365 
1366  /**
1367  * @brief Moves a new element in the hash table.
1368  *
1369  * If there already exists an element with the same key in the table and
1370  * the uniqueness policy prevents multiple identical keys to belong to the
1371  * same hashtable, an exception DuplicateElement is thrown. If the
1372  * uniqueness policy is not set, the method runs in the worst case in
1373  * constant time, else if the automatic resizing policy is set, it runs in
1374  * constant time in average linear in the number of elements by slot.
1375  * @return a reference to the pair (key,val) in the hashtable. @throw
1376  * DuplicateElement is thrown when attempting to insert a pair (key,val) in
1377  * a hash table containing already a pair with the same key and when the
1378  * hash table's uniqueness policy is set.
1379  *
1380  * @param elt The pair of key value to move in this gum::HashTable.
1381  * @return The value moved to this gum::HashTable.
1382  */
1383  value_type& insert(std::pair< Key, Val >&& elt);
1384 
1385  /**
1386  * @brief Emplace a new element into the hashTable.
1387  *
1388  * If there already exists an element with the same key in the list and the
1389  * uniqueness policy prevents multiple identical keys to belong to the same
1390  * hashtable, an exception DuplicateElement is thrown. If the uniqueness
1391  * policy is not set, the method runs in the worst case in constant time,
1392  * else if the automatic resizing policy is set, it runs in constant time
1393  * in average linear in the number of elements by slot. @return a
1394  * reference to the pair (key,val) inserted in the hash table. @throw
1395  * DuplicateElement is thrown when attempting to insert a pair (key,val) in
1396  * a hash table containing already a pair with the same key and when the
1397  * hash table's uniqueness policy is set.
1398  *
1399  * @param args The element to emplace.
1400  */
1401  template < typename... Args >
1402  value_type& emplace(Args&&... args);
1403 
1404  /**
1405  * @brief Returns a reference on the element the key of which is passed in
1406  * argument.
1407  *
1408  * In case of multiple identical keys in the hash table, the first value
1409  * encountered is returned. The method runs in constant time.
1410  * In case of not found key, (key,default_value) is inserted in *this.
1411  *
1412  * @param key The key for wich we want the value.
1413  * @param default_value The default value to return if key does not match
1414  * any value.
1415  * @return Returns a reference on the element the key of which is passed in
1416  * argument.
1417  */
1418  mapped_type& getWithDefault(const Key& key, const Val& default_value);
1419 
1420  /**
1421  * @brief Returns a reference on the element the key of which is passed in
1422  * argument.
1423  *
1424  * In case of multiple identical keys in the hash table, the first value
1425  * encountered is returned. The method runs in constant time. In case of
1426  * not found key, (key,default_value) is inserted in *this.
1427  *
1428  * @param key The key for wich we want the value.
1429  * @param default_value The default value to return if key does not match
1430  * any value.
1431  * @return Returns a reference on the element the key of which is passed in
1432  * argument.
1433  */
1434  mapped_type& getWithDefault(Key&& key, Val&& default_value);
1435 
1436  /**
1437  * @brief Add a new property or modify it if it already existed.
1438  *
1439  * When used as a "dynamic property list", it may be convenient to use this
1440  * function. Function set inserts a new pair (key,val) if the key does not
1441  * already exists, or it changes the value associated with key if a pair
1442  * (key,val) already exists in the hash table.
1443  *
1444  * @param key The key of the value to add or set.
1445  * @param default_value The value to set or add.
1446  */
1447  void set(const Key& key, const Val& default_value);
1448 
1449  /**
1450  * @brief Removes a property (i.e., remove an element).
1451  *
1452  * Reset removes a property (i.e., a pair (key,val)) if it exists. This is
1453  * an alias for erase but it is quite convenient when dealing with "dynamic
1454  * property lists".
1455  *
1456  * @param key The property to remove.
1457  */
1458  void reset(const Key& key);
1459 
1460  /**
1461  * @brief Removes a given element from the hash table.
1462  *
1463  * The element is the first one encountered in the list (from begin() to
1464  * end()) having the specified key. If no such element can be found,
1465  * nothing is done (in particular, it does not throw any exception). The
1466  * function never resizes the nodes vector (even if the resizing policy
1467  * would enable to decrease this size). The method runs in average in time
1468  * linear to the number of iterators pointing to the table if the automatic
1469  * resizing policy is set (else it is in linear time in the number of
1470  * elements of the hash table plus the number of iterators).
1471  *
1472  * @param key The key of the element to remove.
1473  */
1474  void erase(const Key& key);
1475 
1476  /**
1477  * @brief Removes a given element from the hash table.
1478  *
1479  * This method updates all the safe iterators pointing to the deleted
1480  * element, i.e., when trying to dereference those iterators, an exception
1481  * will be raised because they will know that the element they point to no
1482  * longer exists.
1483  *
1484  * @param iter An iterator over the element to remove.
1485  */
1486  void erase(const iterator_safe& iter);
1487 
1488  /**
1489  * @brief Removes a given element from the hash table.
1490  *
1491  * This method updates all the safe iterators pointing to the deleted
1492  * element, i.e., when trying to dereference those iterators, an exception
1493  * will be raised because they will know that the element they point to no
1494  * longer exists.
1495  *
1496  * @param iter An iterator over the element to remove.
1497  */
1498  void erase(const const_iterator_safe& iter);
1499 
1500  /**
1501  * @brief Removes a given element from the hash table.
1502  *
1503  * The element is the first one encountered in the list (from begin() to
1504  * end()) having the specified value. If no such element can be found,
1505  * nothing is done (in particular, it does not throw any exception). The
1506  * function never resizes the nodes vector (even if the resizing policy
1507  * would enable to decrease this size). Comparisons between Val instances
1508  * are performed through == operators. Logically, this method should have
1509  * been named "erase", however, this would have prevented creating hash
1510  * tables where both keys and vals have the same type. Hence we chose to
1511  * add "ByVal" after erase to make a difference between erasing by key and
1512  * erasing by val.
1513  *
1514  * @param val The value to remove.
1515  */
1516  void eraseByVal(const Val& val);
1517 
1518  /**
1519  * @brief Returns a reference on the key given a value.
1520  *
1521  * In case of multiple identical values in the hash table, the first key
1522  * encountered is returned. The method runs in linear time.
1523  *
1524  * @param val The value for which the key is returned.
1525  * @return Returns a reference on the key given a value.
1526  * @throws NotFound Raised if the element cannot be found.
1527  */
1528  const Key& keyByVal(const Val& val) const;
1529 
1530  /**
1531  * @brief Returns a reference on a given key.
1532  *
1533  * Some complex structures use pointers on keys of hashtables. These
1534  * structures thus require that we do not only get a copy of a given key,
1535  * but the key stored in the hashtable itself. This is the very purpose of
1536  * this function.
1537  *
1538  * @param key The key to return.
1539  * @return Returns a reference on a given key.
1540  * @throw NotFound Raised if the element cannot be found.
1541  */
1542  const Key& key(const Key& key) const;
1543 
1544  /**
1545  * @brief Removes all the elements having a certain value from the hash
1546  * table.
1547  *
1548  * If no such element can be found, nothing is done (in particular, it does
1549  * not throw any exception). The function never resizes the nodes vector
1550  * (even if the resizing policy would enable to decrease this size).
1551  * Comparisons between Val instances are performed through == operators.
1552  *
1553  * @param val The value to remove.
1554  *
1555  */
1556  void eraseAllVal(const Val& val);
1557 
1558  /**
1559  * @brief Removes all the elements in the hash table.
1560  *
1561  * The function does not resize the nodes vector (even if the size of this
1562  * one has been increased after the creation of the hash table) and it
1563  * resets the iterators on the hash table to end. The method runs in linear
1564  * time w.r.t. the number of iterators pointing to the hash table.
1565  */
1566  void clear();
1567 
1568  /**
1569  * @brief Indicates whether the hash table is empty.
1570  * @return Returns true if the gum::HashTable is empty.
1571  */
1572  bool empty() const noexcept;
1573 
1574  /**
1575  * @brief Transforms a hashtable of vals into a hashtable of mountains.
1576  *
1577  * @warning Although the resulting hashtable has the same number of
1578  * elements as the original hashtable, by default, the size of the former
1579  * may not be equal to that of the latter. Hence iterators on the original
1580  * hashtable may not parse it in the same order as iterators on the
1581  * resulting hashtable. To guarrantee that both hashtables have the same
1582  * size (and thus have the elements in the same order), set the @e size
1583  * argument to the size of the original hashtable.
1584  *
1585  * @param f A function that maps any Val element into a Mount.
1586  * @param size The size of the resulting hashtable. When equal to 0, a
1587  * default size is computed that is a good trade-off between space
1588  * consumption and efficiency of new elements insertions
1589  * @param resize_pol the resizing policy (automatic or manual resizing)
1590  * @param key_uniqueness_pol uniqueness policy
1591  *
1592  * @return Returns the gum::HashTable of mountains.
1593  */
1594  template < typename Mount,
1595  typename OtherAlloc = typename Alloc::template rebind<
1596  std::pair< Key, Mount > >::other >
1597  HashTable< Key, Mount, OtherAlloc >
1598  map(Mount (*f)(Val),
1599  Size size = Size(0),
1600  bool resize_pol = HashTableConst::default_resize_policy,
1601  bool key_uniqueness_pol
1602  = HashTableConst::default_uniqueness_policy) const;
1603 
1604  /**
1605  * @brief Transforms a hashtable of vals into a hashtable of mountains.
1606  *
1607  * @warning Although the resulting hashtable has the same number of
1608  * elements as the original hashtable, by default, the size of the former
1609  * may not be equal to that of the latter. Hence iterators on the original
1610  * hashtable may not parse it in the same order as iterators on the
1611  * resulting hashtable. To guarrantee that both hashtables have the same
1612  * size (and thus have the elements in the same order), set the @e size
1613  * argument to the size of the original hashtable.
1614  *
1615  * @param f A function that maps any Val element into a Mount.
1616  * @param size The size of the resulting hashtable. When equal to 0, a
1617  * default size is computed that is a good trade-off between space
1618  * consumption and efficiency of new elements insertions
1619  * @param resize_pol the resizing policy (automatic or manual resizing)
1620  * @param key_uniqueness_pol uniqueness policy
1621  *
1622  * @return Returns the gum::HashTable of mountains.
1623  */
1624  template < typename Mount,
1625  typename OtherAlloc = typename Alloc::template rebind<
1626  std::pair< Key, Mount > >::other >
1627  HashTable< Key, Mount, OtherAlloc >
1628  map(Mount (*f)(Val&),
1629  Size size = Size(0),
1630  bool resize_pol = HashTableConst::default_resize_policy,
1631  bool key_uniqueness_pol
1632  = HashTableConst::default_uniqueness_policy) const;
1633 
1634  /**
1635  * @brief Transforms a hashtable of vals into a hashtable of mountains.
1636  *
1637  * @warning Although the resulting hashtable has the same number of
1638  * elements as the original hashtable, by default, the size of the former
1639  * may not be equal to that of the latter. Hence iterators on the original
1640  * hashtable may not parse it in the same order as iterators on the
1641  * resulting hashtable. To guarrantee that both hashtables have the same
1642  * size (and thus have the elements in the same order), set the @e size
1643  * argument to the size of the original hashtable.
1644  *
1645  * @param f A function that maps any Val element into a Mount.
1646  * @param size The size of the resulting hashtable. When equal to 0, a
1647  * default size is computed that is a good trade-off between space
1648  * consumption and efficiency of new elements insertions
1649  * @param resize_pol the resizing policy (automatic or manual resizing)
1650  * @param key_uniqueness_pol uniqueness policy
1651  *
1652  * @return Returns the gum::HashTable of mountains.
1653  */
1654  template < typename Mount,
1655  typename OtherAlloc = typename Alloc::template rebind<
1656  std::pair< Key, Mount > >::other >
1657  HashTable< Key, Mount, OtherAlloc >
1658  map(Mount (*f)(const Val&),
1659  Size size = Size(0),
1660  bool resize_pol = HashTableConst::default_resize_policy,
1661  bool key_uniqueness_pol
1662  = HashTableConst::default_uniqueness_policy) const;
1663 
1664  /**
1665  * @brief Creates a hashtable of mounts with a given value from a hashtable
1666  * of vals.
1667  *
1668  * @warning Although the resulting hashtable has the same number of
1669  * elements as the original hashtable, by default, the size of the former
1670  * may not be equal to that of the latter. Hence iterators on the original
1671  * hashtable may not parse it in the same order as iterators on the
1672  * resulting hashtable. To guarrantee that both hashtables have the same
1673  * size (and thus have the elements in the same order), set the @e size
1674  * argument to the size of the original hashtable.
1675  *
1676  * @param val The value taken by all the elements of the resulting
1677  * hashtable.
1678  * @param size The size of the resulting hashtable. When equal to 0, a
1679  * default size is computed that is a good trade-off between space
1680  * consumption and efficiency of new elements insertions
1681  * @param resize_pol the resizing policy (automatic or manual resizing)
1682  * @param key_uniqueness_pol uniqueness policy
1683  *
1684  * @return Returns the gum::HashTable of mountains.
1685  */
1686  template < typename Mount,
1687  typename OtherAlloc = typename Alloc::template rebind<
1688  std::pair< Key, Mount > >::other >
1689  HashTable< Key, Mount, OtherAlloc >
1690  map(const Mount& val,
1691  Size size = Size(0),
1692  bool resize_pol = HashTableConst::default_resize_policy,
1693  bool key_uniqueness_pol
1694  = HashTableConst::default_uniqueness_policy) const;
1695 
1696  /// @}
1697 
1698  private:
1699  /// Friends to optimize the access to data, iterators must be friends
1700  /// @{
1701  template < typename K, typename V, typename A >
1702  friend class HashTable;
1703  friend class HashTableIterator< Key, Val >;
1704  friend class HashTableConstIterator< Key, Val >;
1705  friend class HashTableIteratorSafe< Key, Val >;
1706  friend class HashTableConstIteratorSafe< Key, Val >;
1707 
1708  friend std::ostream& operator<<<>(std::ostream&,
1709  const HashTable< Key, Val, Alloc >&);
1710  friend std::ostream& operator<<<>(std::ostream& s,
1711  const HashTable< Key*, Val, Alloc >& table);
1712 
1713  /// For bijections to quickly access data.
1714  template < typename T1, typename T2, typename A >
1715  friend class Bijection;
1716  /// @}
1717 
1718  /**
1719  * The hash table is represented as a vector of chained lists. '__nodes'
1720  * is this very vector.
1721  */
1722  std::vector< HashTableList< Key, Val, Alloc > > nodes__;
1723 
1724  /// The number of nodes in vector '__nodes'.
1725  Size size__;
1726 
1727  /// Number of elements of type Val stored in the hash table.
1728  Size nb_elements__{Size(0)};
1729 
1730  /// The function used to hash keys (may change when the table is resized).
1731  HashFunc< Key > hash_func__;
1732 
1733  /// Is resizing performed automatically?
1734  bool resize_policy__{true};
1735 
1736  /// Shall we check for key uniqueness in the table?
1737  bool key_uniqueness_policy__{true};
1738 
1739  /**
1740  * @brief Returns where the begin index should be.
1741  *
1742  * Beware: the beginning of a HashTable is the end of its nodes__ vector,
1743  * i.e., the Bucket at the highest index in nodes__. This enables a
1744  * slightly faster parsing than if it were the lowest index. @warning
1745  * std::numeric_limits<Size>::max() means that we do not know where the
1746  * beginning of the table really is (this can mean either that there is not
1747  * yet any element in the hash table or that an erase operation has been
1748  * performed and that we lost track of the element that should correspond
1749  * to the begin().
1750  *
1751  * @return Returns where the begin index should be.
1752  */
1753  mutable Size begin_index__{std::numeric_limits< Size >::max()};
1754 
1755  /// The list of safe iterators pointing to the hash table.
1756  mutable std::vector< HashTableConstIteratorSafe< Key, Val >* >
1757  safe_iterators__;
1758 
1759  /**
1760  * @brief The allocator for the buckets.
1761  *
1762  * @warning the allocator field should compulsorily be the last of field of
1763  * the class. As such, for K and V fixed, all hashTable<K,V,A> are the same
1764  * (up to the allocator) for all allocators A. This feature proves useful
1765  * to avoid passing the allocator as a template parameter to iterators.
1766  */
1767  BucketAllocator alloc__;
1768 
1769  /// Erases a given bucket.
1770  void erase__(HashTableBucket< Key, Val >* bucket, Size index);
1771 
1772  /**
1773  * @brief A function used to perform copies of HashTables.
1774  *
1775  * This code is shared by the copy constructor and the copy operator. The
1776  * function ensures that when a memory allocation problem occurs:
1777  * - no memory leak occurs
1778  * - the hashtable returned is empty but in a coherent state
1779  * - an exception is thrown
1780  *
1781  * The function assumes that both this and table have arrays '__nodes' of
1782  * the same size.
1783  *
1784  * @param table The gum::HashTable to copy.
1785  * @tparam OtherAlloc The other gum::HashTable allocator.
1786  */
1787  template < typename OtherAlloc >
1788  void copy__(const HashTable< Key, Val, OtherAlloc >& table);
1789 
1790  /**
1791  * @brief Used by all default constructors (general and specialized).
1792  * @param size The size of the gum::HashTable to create.
1793  */
1794  void create__(Size size);
1795 
1796  /**
1797  * @brief Clear all the safe iterators.
1798  */
1799  void clearIterators__();
1800 
1801  /**
1802  * @brief Adds a new element (actually a copy of this element) in the hash
1803  * table.
1804  *
1805  * If there already exists an element with the same key in the list and the
1806  * uniqueness policy prevents multiple identical keys to belong to the same
1807  * hashtable, an exception DuplicateElement is thrown. If the uniqueness
1808  * policy is not set, the method runs in the worst case in constant time,
1809  * else if the automatic resizing policy is set, it runs in constant time
1810  * in average linear in the number of elements by slot.
1811  *
1812  * @param bucket The bucket inserted in the hash table.
1813  * @throw DuplicateElement is thrown when attempting to insert a pair
1814  * (key,val) in a hash table containing already a pair with the same key
1815  * and when the hash table's uniqueness policy is set.
1816  */
1817  void insert__(Bucket* bucket);
1818  };
1819 
1820 
1821  // ===========================================================================
1822  // === SAFE HASH TABLES CONST ITERATORS ===
1823  // ===========================================================================
1824 
1825  /**
1826  * @class HashTableIteratorStaticEnd
1827  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
1828  * @brief A class used to create the static iterator used by HashTables.
1829  * @ingroup hashtable_group
1830  *
1831  * The aim of using this class rather than just creating HashTableIterEnd__
1832  * as a global variable is to prevent other classes to access and modify
1833  * HashTableIterEnd__.
1834  */
1835  class HashTableIteratorStaticEnd {
1836  private:
1837  /// The unsafe iterator used by everyone.
1838  static const HashTableIterator< int, int >* HashTableIterEnd__;
1839 
1840  /// The safe iterator used by everyone.
1841  static const HashTableIteratorSafe< int, int >* HashTableIterEndSafe__;
1842 
1843  /**
1844  * @brief Creates (if needed) and returns the iterator HashTableIterEnd__.
1845  * @return Returns the iterator HashTableIterEnd__.
1846  */
1847  static const HashTableIterator< int, int >* end4Statics();
1848 
1849  /**
1850  * @brief Creates (if needed) and returns the iterator HashTableIterEnd__.
1851  * @return Returns the iterator HashTableIterEnd__.
1852  */
1853  static const HashTableConstIterator< int, int >* constEnd4Statics();
1854 
1855  /**
1856  * @brief Creates (if needed) and returns the iterator
1857  * HashTableIterEndSafe__.
1858  * @return Returns the iterator HashTableIterEndSafe__.
1859  */
1860  static const HashTableIteratorSafe< int, int >* endSafe4Statics();
1861 
1862  /**
1863  * @brief Creates (if needed) and returns the iterator
1864  * HashTableIterEndSafe__.
1865  * @return Returns the iterator HashTableIterEndSafe__.
1866  */
1867  static const HashTableConstIteratorSafe< int, int >* constEndSafe4Statics();
1868 
1869  /// Friends that have access to the iterator.
1870  template < typename Key, typename Val, typename Alloc >
1871  friend class HashTable;
1872  };
1873 
1874 
1875  // ===========================================================================
1876  // === SAFE HASH TABLES CONST ITERATORS ===
1877  // ===========================================================================
1878  /**
1879  * @class HashTableConstIteratorSafe
1880  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
1881  * @brief Safe Const Iterators for hashtables.
1882  * @ingroup hashtable_group
1883  *
1884  * HashTableConstIteratorSafe provides a safe way to parse HashTables. They
1885  * are safe because they are kept informed by the hashtable they belong to of
1886  * the elements deleted by the user. Hence, even if the user removes an
1887  * element pointed to by a HashTableConstIteratorSafe, using the latter to
1888  * access this element will never crash the application. Instead it will
1889  * properly throw a UndefinedIteratorValue exception.
1890  *
1891  * Developers may consider using HashTable<x,y>::const_iterator_safe instead
1892  * of HashTableConstIteratorSafe<x,y>.
1893  *
1894  * @par Usage example:
1895  * @code
1896  * // creation of a hash table with 10 elements
1897  * HashTable<int,string> table;
1898  * for (int i = 0; i< 10; ++i)
1899  * table.insert (i,"xxx" + string (i,'x'));
1900  *
1901  * // parse the hash table
1902  * for (HashTable<int,string>::const_iterator_safe iter = table.cbeginSafe ();
1903  * iter != table.cendSafe (); ++iter) {
1904  * // display the values
1905  * cerr << "at " << iter.key () << " value = " << iter.val () << endl;
1906  * const HashTable<int,string>::value_type& elt = *iter;
1907  * const std::pair<const int, string>& xelt = *iter;
1908  * }
1909  *
1910  * // check whether two iterators point toward the same element
1911  * HashTable<int,string>::const_iterator_safe iter1 = table1.cbeginSafe ();
1912  * HashTable<int,string>::const_iterator_safe iter2 = table1.cendSafe ();
1913  * if (iter1 != iter) {
1914  * cerr << "iter1 and iter2 point toward different elements";
1915  * }
1916  *
1917  * // make iter1 point toward nothing
1918  * iter1.clear ();
1919  * @endcode
1920  */
1921  template < typename Key, typename Val >
1922  class HashTableConstIteratorSafe {
1923  public:
1924  /// Types for STL compliance.
1925  /// @{
1926  using iterator_category = std::forward_iterator_tag;
1927  using key_type = Key;
1928  using mapped_type = Val;
1929  using value_type = std::pair< const Key, Val >;
1930  using reference = value_type&;
1931  using const_reference = const value_type&;
1932  using pointer = value_type*;
1933  using const_pointer = const value_type*;
1934  using difference_type = std::ptrdiff_t;
1935  /// @}
1936 
1937  // ============================================================================
1938  /// @name Constructors / Destructors
1939  // ============================================================================
1940  /// @{
1941 
1942  /**
1943  * @brief Basic constructor: creates an iterator pointing to nothing.
1944  */
1945  HashTableConstIteratorSafe();
1946 
1947  /**
1948  * @brief Constructor for an iterator pointing to the first element of a
1949  * hashtable.
1950  * @tparam Alloc The gum::HashTable allocator.
1951  * @param tab A gum::HashTable to iterate over.
1952  */
1953  template < typename Alloc >
1954  HashTableConstIteratorSafe(const HashTable< Key, Val, Alloc >& tab);
1955 
1956  ///
1957  /**
1958  * @brief Constructor for an iterator pointing to the nth element of a
1959  * hashtable.
1960  *
1961  * The method runs in time linear to ind_elt.
1962  *
1963  * @tparam Alloc The gum::HashTable allocator.
1964  * @param tab the hash table to which the so-called element belongs
1965  * @param ind_elt the position of the element in the hash table (0 means
1966  * the first element).
1967  * @throw UndefinedIteratorValue Raised if the element cannot be found.
1968  */
1969  template < typename Alloc >
1970  HashTableConstIteratorSafe(const HashTable< Key, Val, Alloc >& tab,
1971  Size ind_elt);
1972 
1973  /**
1974  * @brief Copy constructor.
1975  * @param from The gum::HashTableConstIteratorSafe to copy.
1976  */
1977  HashTableConstIteratorSafe(const HashTableConstIteratorSafe< Key, Val >& from);
1978 
1979  /**
1980  * @brief Copy constructor.
1981  * @param from The gum::HashTableConstIterator to copy.
1982  */
1983  explicit HashTableConstIteratorSafe(
1984  const HashTableConstIterator< Key, Val >& from);
1985 
1986  /**
1987  * @brief Move constructor.
1988  * @param from The gum::HashTableConstIteratorSafe to move.
1989  */
1990  HashTableConstIteratorSafe(HashTableConstIteratorSafe< Key, Val >&& from);
1991 
1992  /**
1993  * @brief Destructor.
1994  */
1995  ~HashTableConstIteratorSafe() noexcept;
1996 
1997  /// @}
1998  // ============================================================================
1999  /// @name Accessors / Modifiers
2000  // ============================================================================
2001  /// @{
2002 
2003  /**
2004  * @brief Returns the key pointed to by the iterator.
2005  * @return Returns the key pointed to by the iterator.
2006  * @throws UndefinedIteratorValue Raised when the iterator does not point
2007  * to a valid hash table element
2008  */
2009  const key_type& key() const;
2010 
2011  ///
2012  /**
2013  * @brief Returns the mapped value pointed to by the iterator.
2014  * @return Returns the mapped value pointed to by the iterator.
2015  * @throws UndefinedIteratorValue Raised when the iterator does not point
2016  * to a valid hash table element.
2017  */
2018  const mapped_type& val() const;
2019 
2020  /**
2021  * @brief Makes the iterator point toward nothing (in particular, it is not
2022  * related anymore to its current hash table).
2023  *
2024  * It is mainly used by the hashtable when the latter is deleted while the
2025  * iterator is still alive.
2026  */
2027  void clear() noexcept;
2028 
2029  /// @}
2030  // ============================================================================
2031  /// @name Operators
2032  // ============================================================================
2033  /// @{
2034 
2035  /**
2036  * @brief Copy operator.
2037  * @param from The gum::HashTableConstIteratorSafe to copy.
2038  * @return Returns this gum::HashTableConstIteratorSafe.
2039  */
2040  HashTableConstIteratorSafe< Key, Val >&
2041  operator=(const HashTableConstIteratorSafe< Key, Val >& from);
2042 
2043  /**
2044  * @brief Copy operator.
2045  * @param from The gum::HashTableConstIterator to copy.
2046  * @return Returns this gum::HashTableConstIteratorSafe.
2047  */
2048  HashTableConstIteratorSafe< Key, Val >&
2049  operator=(const HashTableConstIterator< Key, Val >& from);
2050 
2051  /**
2052  * @brief Move operator.
2053  * @param from The gum::HashTableConstIteratorSafe to move.
2054  * @return Returns this gum::HashTableConstIteratorSafe.
2055  */
2056  HashTableConstIteratorSafe< Key, Val >&
2057  operator=(HashTableConstIteratorSafe< Key, Val >&& from) noexcept;
2058 
2059  /**
2060  * @brief Makes the iterator point to the next element in the hash table.
2061  *
2062  * @code
2063  * for (iter = hash.beginSafe(); iter != hash.endSafe (); ++iter) { }
2064  * @endcode
2065  *
2066  * The above loop is guaranteed to parse the whole hash table as long as no
2067  * element is added to or deleted from the hash table while being in the
2068  * loop. Deleting elements during the loop is guaranteed to never produce a
2069  * segmentation fault.
2070  *
2071  * @return Returns this gum::HashTableConstIteratorSafe pointing to the
2072  * next element in the gum::HashTable it's iterating over.
2073  */
2074  HashTableConstIteratorSafe< Key, Val >& operator++() noexcept;
2075 
2076  /**
2077  * @brief Makes the iterator point to i elements further in the hashtable.
2078  * @param i The number of steps to increment the
2079  * gum::HashTableConstIteratorSafe.
2080  * @return Returns this gum::HashTableConstIteratorSafe.
2081  */
2082  HashTableConstIteratorSafe< Key, Val >& operator+=(Size i) noexcept;
2083 
2084  /**
2085  * @brief Returns a new iterator poiting to i elements further in the
2086  * hashtable.
2087  * @param i The number of steps to increment the
2088  * gum::HashTableConstIteratorSafe.
2089  * @return Returns a new gum::HashTableConstIteratorSafe.
2090  */
2091  HashTableConstIteratorSafe< Key, Val > operator+(Size i) const;
2092 
2093  /**
2094  * @brief Checks whether two iterators are not equal.
2095  * @param from from The iterator to test for inequality.
2096  * @return Returns true if from and this iterator are inequal.
2097  */
2098  bool operator!=(
2099  const HashTableConstIteratorSafe< Key, Val >& from) const noexcept;
2100 
2101  /**
2102  * @brief Checks whether two iterators are equal.
2103  * @param from from The iterator to test for equality.
2104  * @return Returns true if from and this iterator are equal.
2105  */
2106  bool operator==(
2107  const HashTableConstIteratorSafe< Key, Val >& from) const noexcept;
2108 
2109  /**
2110  * @brief Returns the element pointed to by the iterator.
2111  * @return Returns the element pointed to by the iterator.
2112  * @throws UndefinedIteratorValue Raised when the iterator does not point
2113  * to a valid hash table element.
2114  */
2115  const value_type& operator*() const;
2116 
2117  /// @}
2118 
2119  protected:
2120  /**
2121  * Class HashTable must be a friend because it stores iterator end and this
2122  * can be properly initialized only when the hashtable has been fully
2123  * allocated. Thus, proper initialization can only take place within the
2124  * constructor's code of the hashtable.
2125  */
2126  template < typename K, typename V, typename A >
2127  friend class HashTable;
2128 
2129  /// The hash table the iterator is pointing to.
2130  const HashTable< Key, Val >* table__{nullptr};
2131 
2132  /**
2133  * @brief the index of the chained list pointed to by the iterator in the
2134  * array nodes__ of the hash table.
2135  */
2136  Size index__{Size(0)};
2137 
2138  /// The bucket in the chained list pointed to by the iterator.
2139  HashTableBucket< Key, Val >* bucket__{nullptr};
2140 
2141  /**
2142  * @brief the bucket we should start from when we decide to do a ++.
2143  *
2144  * Usually it should be equal to nullptr. However, if the user has deleted
2145  * the object pointed to by bucket, this will point to another bucket. When
2146  * it is equal to nullptr, it means that the bucket reached after a ++
2147  * belongs to another slot of the hash table's '__node' vector.
2148  */
2149  HashTableBucket< Key, Val >* next_bucket__{nullptr};
2150 
2151  /// Returns the current iterator's bucket.
2152  HashTableBucket< Key, Val >* getBucket__() const noexcept;
2153 
2154  /**
2155  * @brief Returns the index in the hashtable's node vector pointed to by
2156  * the iterator.
2157  * @return Returns the index in the hashtable's node vector pointed to by
2158  * the iterator.
2159  */
2160  Size getIndex__() const noexcept;
2161 
2162  /**
2163  * @brief Removes the iterator from its hashtable' safe iterators list.
2164  */
2165  void removeFromSafeList__() const;
2166 
2167  /**
2168  * @brief Insert the iterator into the hashtable's list of safe iterators.
2169  */
2170  void insertIntoSafeList__() const;
2171  };
2172 
2173  // ===========================================================================
2174  // === HASH TABLES ITERATORS ===
2175  // ===========================================================================
2176 
2177  /**
2178  * @class HashTableIteratorSafe
2179  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
2180  * @brief Safe Iterators for hashtables.
2181  * @ingroup hashtable_group
2182  *
2183  * HashTableIteratorSafe provides a safe way to parse HashTables. They are
2184  * safe because they are kept informed by the hashtable they belong to of the
2185  * elements deleted by the user. Hence, even if the user removes an element
2186  * pointed to by a HashTableIteratorSafe, using the latter to access this
2187  * element will never crash the application. Instead it will properly throw
2188  * an UndefinedIteratorValue exception.
2189  *
2190  * Developers may consider using HashTable<x,y>::iterator_safe instead of
2191  * HashTableIteratorSafe<x,y>.
2192  *
2193  * @par Usage example:
2194  * @code
2195  * // creation of a hash table with 10 elements
2196  * HashTable<int,string> table;
2197  * for (int i = 0; i< 10; ++i)
2198  * table.insert (i,"xxx" + string (i,'x'));
2199  *
2200  * // parse the hash table
2201  * for (HashTable<int,string>::iterator_safe iter = table.beginSafe ();
2202  * iter != table.endSafe (); ++iter) {
2203  * // display the values
2204  * cerr << "at " << iter.key() << " value = " << iter.val () << endl;
2205  * HashTable<int,string>::value_type& elt = *iter;
2206  * std::pair<const int, string>& xelt = *iter;
2207  * }
2208  *
2209  * // check whether two iterators point toward the same element
2210  * HashTable<int,string>::iterator_safe iter1 = table1.beginSafe ();
2211  * HashTable<int,string>::iterator_safe iter2 = table1.endSafe ();
2212  * if (iter1 != iter) {
2213  * cerr << "iter1 and iter2 point toward different elements";
2214  * }
2215  *
2216  * // make iter1 point toward nothing
2217  * iter1.clear ();
2218  * @endcode
2219  *
2220  * @tparam Key The gum::HashTable key.
2221  * @tparam Val The gum::HashTable Value.
2222  */
2223  template < typename Key, typename Val >
2224  class HashTableIteratorSafe: public HashTableConstIteratorSafe< Key, Val > {
2225  public:
2226  /// Types for STL compliance.
2227  /// @{
2228  using iterator_category = std::forward_iterator_tag;
2229  using key_type = Key;
2230  using mapped_type = Val;
2231  using value_type = std::pair< const Key, Val >;
2232  using reference = value_type&;
2233  using const_reference = const value_type&;
2234  using pointer = value_type*;
2235  using const_pointer = const value_type*;
2236  using difference_type = std::ptrdiff_t;
2237  /// @}
2238 
2239  // ============================================================================
2240  /// @name Constructors / Destructors
2241  // ============================================================================
2242  /// @{
2243 
2244  /**
2245  * @brief Basic constructor: creates an iterator pointing to nothing.
2246  */
2247  HashTableIteratorSafe();
2248 
2249  /**
2250  * @brief Constructor for an iterator pointing to the first element of a
2251  * hashtable.
2252  * @tparam Alloc The gum::HashTable allocator.
2253  */
2254  template < typename Alloc >
2255  HashTableIteratorSafe(const HashTable< Key, Val, Alloc >& tab);
2256 
2257  /**
2258  * @brief Constructor for an iterator pointing to the nth element of a
2259  * hashtable.
2260  *
2261  * The method runs in time linear to ind_elt.
2262  *
2263  * @param tab the hash table to which the so-called element belongs
2264  * @param ind_elt the position of the element in the hash table (0 means
2265  * the first element).
2266  * @tparam Alloc The gum::HashTable allocator.
2267  * @throw UndefinedIteratorValue Raised if the element cannot be found
2268  */
2269  template < typename Alloc >
2270  HashTableIteratorSafe(const HashTable< Key, Val, Alloc >& tab, Size ind_elt);
2271 
2272  /**
2273  * @brief Copy constructor.
2274  * @param from the gum::HashTableIteratorSafe to copy.
2275  * @return This gum::HashTableIteratorSafe.
2276  */
2277  HashTableIteratorSafe(const HashTableIteratorSafe< Key, Val >& from);
2278 
2279  /**
2280  * @brief Copy constructor.
2281  * @param from the gum::HashTableIterator to copy.
2282  * @return This gum::HashTableIteratorSafe.
2283  */
2284  explicit HashTableIteratorSafe(const HashTableIterator< Key, Val >& from);
2285 
2286  /**
2287  * @brief Move constructor.
2288  * @param from The gum::HashTableIteratorSafe to move.
2289  * @return Returns this gum::HashTableIteratorSafe.
2290  */
2291  HashTableIteratorSafe(HashTableIteratorSafe< Key, Val >&& from) noexcept;
2292 
2293  /**
2294  * @brief Class destructor.
2295  */
2296  ~HashTableIteratorSafe() noexcept;
2297 
2298  /// @}
2299  // ============================================================================
2300  /// @name Accessors / Modifiers
2301  // ============================================================================
2302  /// @{
2303 
2304  /// Usefull Alias
2305  /// @{
2306  using HashTableConstIteratorSafe< Key, Val >::key;
2307  using HashTableConstIteratorSafe< Key, Val >::val;
2308  using HashTableConstIteratorSafe< Key, Val >::clear;
2309  /// @}
2310 
2311  /**
2312  * @brief Returns the mapped value pointed to by the iterator.
2313  * @return Returns the mapped value pointed to by the iterator.
2314  * @throws UndefinedIteratorValue Raised when the iterator does not point
2315  * to a valid hash table element.
2316  */
2317  mapped_type& val();
2318 
2319  /// @}
2320  // ============================================================================
2321  /// @name Operators
2322  // ============================================================================
2323  /// @{
2324 
2325  /**
2326  * @brief Copy operator.
2327  * @param from The gum::HashTableIteratorSafe to copy.
2328  * @return Returns this gum::HashTableIterator.
2329  */
2330  HashTableIteratorSafe< Key, Val >&
2331  operator=(const HashTableIteratorSafe< Key, Val >& from);
2332 
2333  /**
2334  * @brief Copy operator.
2335  * @param from The gum::HashTableIterator to copy.
2336  * @return Returns this gum::HashTableIterator.
2337  */
2338  HashTableIteratorSafe< Key, Val >&
2339  operator=(const HashTableIterator< Key, Val >& from);
2340 
2341  /**
2342  * @brief Move operator.
2343  * @param from The gum::HashTableIteratorSafe to move.
2344  * @return Returns this gum::HashTableIterator.
2345  */
2346  HashTableIteratorSafe< Key, Val >&
2347  operator=(HashTableIteratorSafe< Key, Val >&& from) noexcept;
2348 
2349  /**
2350  * @brief Makes the iterator point to the next element in the hash table.
2351  *
2352  * @code
2353  * for (iter = hash.beginSafe (); iter != hash.endSafe (); ++iter) { }
2354  * @endcode
2355  *
2356  * The above loop is guaranteed to parse the whole hash table as long as no
2357  * element is added to or deleted from the hash table while being in the
2358  * loop. Deleting elements during the loop is guaranteed to never produce a
2359  * segmentation fault.
2360  *
2361  * @return This gum::HashTableIteratorSafe.
2362  */
2363  HashTableIteratorSafe< Key, Val >& operator++() noexcept;
2364 
2365  /**
2366  * @brief Makes the iterator point to i elements further in the hashtable.
2367  * @param i The number of increments.
2368  * @return Return this gum::HashTableIteratorSafe.
2369  */
2370  HashTableIteratorSafe< Key, Val >& operator+=(Size i) noexcept;
2371 
2372  /**
2373  * @brief Returns a new iterator pointing to i elements further in the
2374  * hashtable.
2375  * @param i The number of increments.
2376  * @return Returns this gum::HashTableIteratorSafe.
2377  */
2378  HashTableIteratorSafe< Key, Val > operator+(Size i) const;
2379 
2380  /**
2381  * @brief Checks whether two iterators are pointing toward different
2382  * elements.
2383  * @param from The gum::HashTableIteratorSafe to test for inequality.
2384  * @return Returns true if this and from are not equal.
2385  */
2386  bool operator!=(const HashTableIteratorSafe< Key, Val >& from) const noexcept;
2387 
2388  /**
2389  * @brief Checks whether two iterators are pointing toward equal
2390  * elements.
2391  * @param from The gum::HashTableIteratorSafe to test for equality.
2392  * @return Returns true if this and from are equal.
2393  */
2394  bool operator==(const HashTableIteratorSafe< Key, Val >& from) const noexcept;
2395 
2396  /**
2397  * @brief Returns the value pointed to by the iterator.
2398  * @return Returns the value pointed to by the iterator.
2399  * @throws UndefinedIteratorValue Raised when the iterator does not point
2400  * to a valid hash table element
2401  */
2402  value_type& operator*();
2403 
2404  /**
2405  * @brief Returns the value pointed to by the iterator.
2406  * @return Returns the value pointed to by the iterator.
2407  *
2408  * @throws UndefinedIteratorValue Raised when the iterator
2409  * does not point to a valid hash table element.
2410  */
2411  const value_type& operator*() const;
2412 
2413  /// @}
2414  };
2415 
2416  // ===========================================================================
2417  // === UNSAFE HASH TABLES CONST ITERATORS ===
2418  // ===========================================================================
2419 
2420  /**
2421  * @class HashTableConstIterator
2422  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
2423  * @brief Unsafe Const Iterators for hashtables
2424  * @ingroup hashtable_group
2425  *
2426  * HashTableConstIterator provides a fast but unsafe way to parse HashTables.
2427  * They should @b only be used when parsing hashtables in which no element is
2428  * removed from the hashtable. Removing an element where the iterator points
2429  * to will mess the iterator as it will most certainly point to an
2430  * unallocated memory. So, this kind of iterator should only be used when
2431  * parsing "(key) constant" hash tables, e.g., when we wish to display the
2432  * content of a hash table or when we wish to update the mapped values of
2433  * some elements of the hash table without ever modifying their keys.
2434  *
2435  * Developers may consider using HashTable<x,y>::const_iterator instead of
2436  * HashTableConstIterator<x,y>.
2437  *
2438  * @par Usage example:
2439  * @code
2440  * // creation of a hash table with 10 elements
2441  * HashTable<int,string> table;
2442  * for (int i = 0; i< 10; ++i)
2443  * table.insert (i,"xxx" + string (i,'x'));
2444  *
2445  * // parse the hash table
2446  * for (HashTable<int,string>::const_iterator iter = table.cbegin ();
2447  * iter != table.cend (); ++iter) {
2448  * // display the values
2449  * cerr << "at " << iter.key() << " value = " << iter.val () << endl;
2450  * const HashTable<int,string>::value_type& elt = *iter;
2451  * const std::pair<const int, string>& xelt = *iter;
2452  * }
2453  *
2454  * // check whether two iterators point toward the same element
2455  * HashTable<int,string>::const_iterator iter1 = table1.cbegin();
2456  * HashTable<int,string>::const_iterator iter2 = table1.cend();
2457  * if (iter1 != iter) {
2458  * cerr << "iter1 and iter2 point toward different elements";
2459  * }
2460  *
2461  * // make iter1 point toward nothing
2462  * iter1.clear ();
2463  * @endcode
2464  *
2465  * @tparam Key The gum::HashTable key.
2466  * @tparam Val The gum::HashTable Value.
2467  */
2468  template < typename Key, typename Val >
2469  class HashTableConstIterator {
2470  public:
2471  /// Types for STL compliance.
2472  /// @{
2473  using iterator_category = std::forward_iterator_tag;
2474  using key_type = Key;
2475  using mapped_type = Val;
2476  using value_type = std::pair< const Key, Val >;
2477  using reference = value_type&;
2478  using const_reference = const value_type&;
2479  using pointer = value_type*;
2480  using const_pointer = const value_type*;
2481  using difference_type = std::ptrdiff_t;
2482  /// @}
2483 
2484  // ============================================================================
2485  /// @name Constructors / Destructors
2486  // ============================================================================
2487  /// @{
2488 
2489  /**
2490  * @brief Basic constructor: creates an iterator pointing to nothing.
2491  */
2492  HashTableConstIterator() noexcept;
2493 
2494  /**
2495  * @brief Constructor for an iterator pointing to the first element of a
2496  * hashtable.
2497  * @param tab The gum::HashTable to iterate over.
2498  * @tparam Alloc The gum::HashTable allocator.
2499  */
2500  template < typename Alloc >
2501  HashTableConstIterator(const HashTable< Key, Val, Alloc >& tab) noexcept;
2502 
2503  /**
2504  * @brief Constructor for an iterator pointing to the nth element of a
2505  * hashtable.
2506  *
2507  * The method runs in time linear to ind_elt.
2508  *
2509  * @param tab The hash table to which the so-called element belongs.
2510  * @param ind_elt The position of the element in the hash table (0 means
2511  * the first element).
2512  * @throw UndefinedIteratorValue Raised if the element cannot be found.
2513  */
2514  template < typename Alloc >
2515  HashTableConstIterator(const HashTable< Key, Val, Alloc >& tab, Size ind_elt);
2516 
2517  /**
2518  * @brief Copy constructor.
2519  * @param from The gum::HashTableConstIterator to copy.
2520  */
2521  HashTableConstIterator(
2522  const HashTableConstIterator< Key, Val >& from) noexcept;
2523 
2524  /**
2525  * @brief Move constructor.
2526  * @param from The gum::HashTableConstIterator to move.
2527  */
2528  HashTableConstIterator(HashTableConstIterator< Key, Val >&& from) noexcept;
2529 
2530  /**
2531  * @brief Class destructor.
2532  */
2533  ~HashTableConstIterator() noexcept;
2534 
2535  /// @}
2536  // ============================================================================
2537  /// @name Accessors / Modifiers
2538  // ============================================================================
2539  /// @{
2540 
2541  /**
2542  * @brief Returns the key corresponding to the element pointed to by the
2543  * iterator.
2544  *
2545  * @warning Using this method on an iterator that points to an element that
2546  * has been deleted will most certainly result in a segfault. If unsure,
2547  * use a safe iterator instead of an unsafe one.
2548  *
2549  * @return Returns the key corresponding to the element pointed to by the
2550  * iterator.
2551  */
2552  const key_type& key() const;
2553 
2554  /**
2555  * @brief Returns the mapped value pointed to by the iterator.
2556  *
2557  * @warning Using this method on an iterator that points to an element that
2558  * has been deleted will most certainly result in a segfault. If unsure, use
2559  * a safe iterator instead of an unsafe one.
2560  *
2561  * @return Returns the mapped value pointed to by the iterator.
2562  */
2563  const mapped_type& val() const;
2564 
2565  /**
2566  * @brief Makes the iterator point toward nothing (in particular, it is not
2567  * related anymore to its current hash table).
2568  */
2569  void clear() noexcept;
2570 
2571  /// @}
2572  // ============================================================================
2573  /// @name Operators
2574  // ============================================================================
2575  /// @{
2576 
2577  /**
2578  * @brief Copy operator.
2579  * @param from The gum::HashTableConstIterator to copy.
2580  * @return Returns this gum::HashTableConstIterator.
2581  */
2582  HashTableConstIterator< Key, Val >&
2583  operator=(const HashTableConstIterator< Key, Val >& from) noexcept;
2584 
2585  /**
2586  * @brief Move operator.
2587  * @param from The gum::HashTableConstIterator to move.
2588  * @return Returns this gum::HashTableConstIterator.
2589  */
2590  HashTableConstIterator< Key, Val >&
2591  operator=(HashTableConstIterator< Key, Val >&& from) noexcept;
2592 
2593  ///
2594  /**
2595  * @brief Makes the iterator point to the next element in the hash table.
2596  *
2597  * @code
2598  * for (iter = cbegin (); iter != cend(); ++iter ) { }
2599  * @endcode
2600  *
2601  * The above loop is guaranteed to parse the whole hash table as long as no
2602  * element is added to or deleted from the hash table while being in the
2603  * loop.
2604  *
2605  * @warning performing a ++ on an iterator that points to an element that
2606  * has been deleted will most certainly result in a segfault.
2607  *
2608  * @return Returns this gum::HashTableConstIterator.
2609  */
2610  HashTableConstIterator< Key, Val >& operator++() noexcept;
2611 
2612  /**
2613  * @brief Makes the iterator point to i elements further in the hashtable.
2614  * @param i The number of increments.
2615  * @return Returns this gum::HashTableConstIterator.
2616  */
2617  HashTableConstIterator< Key, Val >& operator+=(Size i) noexcept;
2618 
2619  /**
2620  * @brief Returns a new iterator pointing to i elements further in the
2621  * hashtable.
2622  * @param i The number of increments.
2623  * @return Returns a new iterator pointing to i elements further in the
2624  * hashtable.
2625  */
2626  HashTableConstIterator< Key, Val > operator+(Size i) const noexcept;
2627 
2628  /**
2629  * @brief Checks whether two iterators are pointing toward different
2630  * elements.
2631  * @param from The gum::HashTableConstIterator to test for inequality.
2632  * @return Returns true if this and from are not equal.
2633  */
2634  bool operator!=(const HashTableConstIterator< Key, Val >& from) const noexcept;
2635 
2636  /**
2637  * @brief Checks whether two iterators are pointing toward equal
2638  * elements.
2639  * @param from The gum::HashTableConstIterator to test for equality.
2640  * @return Returns true if this and from are equal.
2641  */
2642  bool operator==(const HashTableConstIterator< Key, Val >& from) const noexcept;
2643 
2644 
2645  /**
2646  * @brief Returns the value pointed to by the iterator.
2647  *
2648  * @warning using this method on an iterator that points to an element that
2649  * has been deleted will most certainly result in a segfault. If unsure,
2650  * use a safe iterator instead of an unsafe one.
2651  *
2652  * @return Returns the value pointed to by the iterator.
2653  */
2654  const value_type& operator*() const;
2655 
2656  /// @}
2657 
2658  protected:
2659  /**
2660  * Class HashTable must be a friend because it stores iterator end and this
2661  * one can be properly initialized only when the hashtable has been fully
2662  * allocated. Thus, proper initialization can only take place within the
2663  * constructor's code of the hashtable.
2664  *
2665  * @tparam K The gum::HashTable keys type.
2666  * @tparam V The gum::HashTable values type.
2667  * @tparam A The gum::HashTable allocator.
2668  */
2669  template < typename K, typename V, typename A >
2670  friend class HashTable;
2671 
2672  /// For the safe copy constructor and operator.
2673  friend class HashTableConstIteratorSafe< Key, Val >;
2674 
2675  /// The hash table the iterator is pointing to.
2676  const HashTable< Key, Val >* table__{nullptr};
2677 
2678  /**
2679  * @brief The index of the chained list pointed by the iterator in the
2680  * array of nodes of the hash table.
2681  */
2682  Size index__{Size(0)};
2683 
2684  /// The bucket in the chained list pointed to by the iterator.
2685  typename HashTable< Key, Val >::Bucket* bucket__{nullptr};
2686 
2687  /**
2688  * @brief Returns the current iterator's bucket.
2689  * @return Returns the current iterator's bucket.
2690  */
2691  typename HashTable< Key, Val >::Bucket* getBucket__() const noexcept;
2692 
2693  /**
2694  * @brief Returns the index in the hashtable's node vector pointed to by
2695  * the iterator.
2696  * @return Returns the index in the hashtable's node vector pointed to by
2697  * the iterator.
2698  */
2699  Size getIndex__() const noexcept;
2700  };
2701 
2702  // ===========================================================================
2703  // === UNSAFE HASH TABLES ITERATORS ===
2704  // ===========================================================================
2705 
2706  /**
2707  * @class HashTableIterator
2708  * @headerfile hashTable.h <agrum/tools/core/hashTable.h>
2709  * @brief Unsafe Iterators for hashtables
2710  * @ingroup hashtable_group
2711  *
2712  * HashTableIterator provides a fast but unsafe way to parse HashTables.
2713  * They should @b only be used when parsing hashtables in which no element is
2714  * removed from the hashtable. Removing an element where the iterator points
2715  * to will mess the iterator as it will most certainly point to an
2716  * unallocated memory. So, this kind of iterator should only be used when
2717  * parsing "(key) constant" hash tables, e.g., when we wish to display the
2718  * content of a hash table or when we wish to update the mapped values of
2719  * some elements of the hash table without ever modifying their keys.
2720  *
2721  * Developers may consider using HashTable<x,y>::iterator instead of
2722  * HashTableIterator<x,y>.
2723  * @par Usage example:
2724  * @code
2725  * // creation of a hash table with 10 elements
2726  * HashTable<int,string> table;
2727  * for (int i = 0; i< 10; ++i)
2728  * table.insert (i,"xxx" + string (i,'x'));
2729  *
2730  * // parse the hash table
2731  * for (HashTable<int,string>::iterator iter = table.begin ();
2732  * iter != table.end (); ++iter) {
2733  * // display the values
2734  * cerr << "at " << iter.key() << " value = " << iter.val () << endl;
2735  * HashTable<int,string>::value_type& elt = *iter;
2736  * std::pair<const int, string>& xelt = *iter;
2737  * }
2738  *
2739  * // check whether two iterators point toward the same element
2740  * HashTable<int,string>::iterator iter1 = table1.begin();
2741  * HashTable<int,string>::iterator iter2 = table1.end();
2742  * if (iter1 != iter) {
2743  * cerr << "iter1 and iter2 point toward different elements";
2744  * }
2745  *
2746  * // make iter1 point toward nothing
2747  * iter1.clear ();
2748  * @endcode
2749  *
2750  * @tparam Key The gum::HashTable key.
2751  * @tparam Val The gum::HashTable Value.
2752  */
2753  template < typename Key, typename Val >
2754  class HashTableIterator: public HashTableConstIterator< Key, Val > {
2755  public:
2756  /// types for STL compliance
2757  /// @{
2758  using iterator_category = std::forward_iterator_tag;
2759  using key_type = Key;
2760  using mapped_type = Val;
2761  using value_type = std::pair< const Key, Val >;
2762  using reference = value_type&;
2763  using const_reference = const value_type&;
2764  using pointer = value_type*;
2765  using const_pointer = const value_type*;
2766  using difference_type = std::ptrdiff_t;
2767  /// @}
2768 
2769  // ############################################################################
2770  /// @name Constructors / Destructors
2771  // ############################################################################
2772  /// @{
2773 
2774  /**
2775  * @brief Basic constructor: creates an iterator pointing to nothing.
2776  */
2777  HashTableIterator() noexcept;
2778 
2779  /**
2780  * @brief Constructor for an iterator pointing to the first element of a
2781  * hashtable.
2782  * @tparam Alloc The gum::HashTable allocator.
2783  * @param tab The gum::HashTable to iterate over.
2784  */
2785  template < typename Alloc >
2786  HashTableIterator(const HashTable< Key, Val, Alloc >& tab) noexcept;
2787 
2788  ///
2789  /**
2790  * @brief Constructor for an iterator pointing to the nth element of a
2791  * hashtable.
2792  *
2793  * The method runs in time linear to ind_elt.
2794  *
2795  * @tparam Alloc The gum::HashTable allocator.
2796  * @param tab The hash table to which the so-called element belongs.
2797  * @param ind_elt The position of the element in the hash table (0 means
2798  * the first element).
2799  * @throw UndefinedIteratorValue Raised if the element cannot be found.
2800  */
2801  template < typename Alloc >
2802  HashTableIterator(const HashTable< Key, Val, Alloc >& tab, Size ind_elt);
2803 
2804  /**
2805  * @brief Copy constructor.
2806  * @param from The gum::HashTableIterator to copy.
2807  */
2808  HashTableIterator(const HashTableIterator< Key, Val >& from) noexcept;
2809 
2810  /**
2811  * @brief Move constructor.
2812  * @param from The gum::HashTableIterator to move.
2813  */
2814  HashTableIterator(HashTableIterator< Key, Val >&& from) noexcept;
2815 
2816  /**
2817  * @brief Class destructor.
2818  */
2819  ~HashTableIterator() noexcept;
2820 
2821  /// @}
2822  // ============================================================================
2823  /// @name Accessors / Modifiers
2824  // ============================================================================
2825  /// @{
2826 
2827  /// Usefull alias.
2828  /// @{
2829  using HashTableConstIterator< Key, Val >::key;
2830  using HashTableConstIterator< Key, Val >::val;
2831  using HashTableConstIterator< Key, Val >::clear;
2832  /// @}
2833 
2834  /**
2835  * @brief Returns the mapped value pointed to by the iterator.
2836  *
2837  * @warning using this method on an iterator that points to an element that
2838  * has been deleted will most certainly result in a segfault. If unsure,
2839  * use a safe iterator instead of an unsafe one.
2840  *
2841  * @return Returns the mapped value pointed to by the iterator.
2842  */
2843  mapped_type& val();
2844 
2845  /// @}
2846  // ============================================================================
2847  /// @name Operators
2848  // ============================================================================
2849  /// @{
2850 
2851  /**
2852  * @brief Copy operator.
2853  * @param from The gum::HashTableIterator to copy.
2854  * @return Returns this gum::HashTableIterator.
2855  */
2856  HashTableIterator< Key, Val >&
2857  operator=(const HashTableIterator< Key, Val >& from) noexcept;
2858 
2859  /**
2860  * @brief Move operator.
2861  * @param from The gum::HashTableIterator to move.
2862  * @return Returns this gum::HashTableIterator.
2863  */
2864  HashTableIterator< Key, Val >&
2865  operator=(HashTableIterator< Key, Val >&& from) noexcept;
2866 
2867  /**
2868  * @brief Makes the iterator point to the next element in the hash table.
2869  *
2870  * @code
2871  * for (iter = begin(); iter != end(); ++iter) { }
2872  * @endcode
2873  *
2874  * The above loop is guaranteed to parse the whole hash table as long as no
2875  * element is added to or deleted from the hash table while being in the
2876  * loop.
2877  *
2878  * @warning performing a ++ on an iterator that points to an element that
2879  * has been deleted will most certainly result in a segfault.
2880  *
2881  * @return Returns this gum::HashTableIterator.
2882  */
2883  HashTableIterator< Key, Val >& operator++() noexcept;
2884 
2885  /**
2886  * @brief Makes the iterator point to i elements further in the hashtable.
2887  * @param i The number of increments.
2888  * @return Returns this gum::HashTableIterator.
2889  */
2890  HashTableIterator< Key, Val >& operator+=(Size i) noexcept;
2891 
2892  /**
2893  * @brief Returns a new iterator.
2894  * @param i The number of increments.
2895  * @return Returns this gum::HashTableIterator.
2896  */
2897  HashTableIterator< Key, Val > operator+(Size i) const noexcept;
2898 
2899  /**
2900  * @brief Checks whether two iterators are pointing toward different
2901  * elements.
2902  * @param from The gum::HashTableIterator to test for inequality.
2903  * @return Returns true if this and from are not equal.
2904  */
2905  bool operator!=(const HashTableIterator< Key, Val >& from) const noexcept;
2906 
2907  /**
2908  * @brief Checks whether two iterators are pointing toward equal
2909  * elements.
2910  * @param from The gum::HashTableIterator to test for equality.
2911  * @return Returns true if this and from are equal.
2912  */
2913  bool operator==(const HashTableIterator< Key, Val >& from) const noexcept;
2914 
2915  /**
2916  * @brief Returns the value pointed to by the iterator.
2917  *
2918  * @warning using this method on an iterator that points to an element that
2919  * has been deleted will most certainly result in a segfault. If unsure,
2920  * use a safe iterator instead of an unsafe one.
2921  *
2922  * @return Returns the value pointed to by the iterator.
2923  */
2924  value_type& operator*();
2925 
2926  /**
2927  * @brief Returns the value pointed to by the iterator.
2928  *
2929  * @warning using this method on an iterator that points to an element that
2930  * has been deleted will most certainly result in a segfault. If unsure,
2931  * use a safe iterator instead of an unsafe one.
2932  *
2933  * @return Returns the value pointed to by the iterator.
2934  */
2935  const value_type& operator*() const;
2936 
2937  /// @}
2938  };
2939 
2940 } // namespace gum
2941 
2942 
2943 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2944 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2945 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2946 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2947 extern template class gum::HashTable< int, int >;
2948 # endif
2949 # endif
2950 # endif
2951 #endif
2952 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2953 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2954 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2955 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2956 extern template class gum::HashTable< int, std::string >;
2957 # endif
2958 # endif
2959 # endif
2960 #endif
2961 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2962 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2963 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2964 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2965 extern template class gum::HashTable< std::string, std::string >;
2966 # endif
2967 # endif
2968 # endif
2969 #endif
2970 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2971 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2972 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2973 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
2974 extern template class gum::HashTable< std::string, int >;
2975 # endif
2976 # endif
2977 # endif
2978 #endif
2979 
2980 
2981 // always include the implementation of the templates
2982 #include <agrum/tools/core/hashTable_tpl.h>
2983 
2984 #endif // GUM_HASHTABLE_H