aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
set.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 Sets of elements (i.e. the mathematical notion of a set).
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  */
28 #ifndef GUM_SET_H
29 #define GUM_SET_H
30 
31 #include <initializer_list>
32 #include <iostream>
33 #include <sstream>
34 #include <string>
35 
36 #include <agrum/tools/core/debug.h>
37 #include <agrum/tools/core/hashTable.h>
38 #include <agrum/tools/core/list.h>
39 
40 namespace gum {
41 
42 #ifndef DOXYGEN_SHOULD_SKIP_THIS
43 
44  template < typename Key >
45  class SetIteratorSafe;
46  template < typename Key >
47  class SetIterator;
48  template < typename Key, typename Alloc >
49  class Set;
50 
51  template < typename Key >
52  using SetConstIterator = SetIterator< Key >;
53  template < typename Key >
54  using SetConstIteratorSafe = SetIteratorSafe< Key >;
55 
56 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
57 
58  /**
59  * @class SetIteratorStaticEnd
60  * @headerfile set.h <agrum/tools/core/set.h>
61  * @brief A class used to create the static iterator used by Sets.
62  * @ingroup set_group
63  *
64  * The aim of using this class rather than just creating SetIterEnd__ as a
65  * global variable is to prevent other classes to access and modify
66  * SetIterEnd__.
67  */
68  class SetIteratorStaticEnd {
69  private:
70  /**
71  * @brief The safe iterator used by everyone.
72  * @return Returns the safe iterator used by everyone.
73  */
74  static const SetIteratorSafe< int >* SetIterEndSafe__;
75 
76  /**
77  * @brief The unsafe iterator used by everyone.
78  * @return Returns the unsafe iterator used by everyone.
79  */
80  static const SetIterator< int >* SetIterEnd__;
81 
82  /**
83  * @brief Creates (if needed) and returns the iterator SetIterEndSafe__.
84  * @return Returns the iterator SetIterEndSafe__.
85  */
86  static const SetIteratorSafe< int >* endSafe4Statics();
87 
88  /**
89  * @brief Creates (if needed) and returns the iterator SetIterEndSafe__.
90  * @return Returns the iterator SetIterEndSafe__.
91  */
92  static const SetIteratorSafe< int >* constEndSafe4Statics();
93 
94  /**
95  * @brief Creates (if needed) and returns the iterator SetIterEnd__.
96  * @return Returns the iterator SetIterEnd__.
97  */
98  static const SetIterator< int >* end4Statics();
99 
100  /**
101  * @brief Creates (if needed) and returns the iterator SetIterEnd__.
102  * @return Returns the iterator SetIterEnd__.
103  */
104  static const SetIterator< int >* constEnd4Statics();
105 
106  /// Friends that have access to the iterator.
107  template < typename Key, typename Alloc >
108  friend class Set;
109  };
110 
111 
112  // ===========================================================================
113  // === GUM_SET ===
114  // ===========================================================================
115 
116  /**
117  * @class Set
118  * @headerfile set.h <agrum/tools/core/set.h>
119  * @brief Representation of a set
120  * @ingroup basicstruct_group
121  * @ingroup set_group
122  *
123  * A Set is a structure that contains arbitrary elements. Note that, as in
124  * mathematics, an element cannot appear twice in a given set. Sets have
125  * unsafe and safe iterators. The safe iterators (SetIteratorSafe<> a.k.a.
126  * Set<>::iterator_safe are slightly slower than the unsafe ones
127  * (SetIterator<> a.k.a. Set<>::iterator) but they guarantee that even if
128  * they point to a deleted element, using their operators ++ or * cannot
129  * produce a segfault. In such cases, they simply raise an exception. On the
130  * contrary, unsafe iterators should @b never be used on elements that can be
131  * deleted because, as in the STL, they will most probably produce a
132  * segfault.
133  *
134  * @par Usage example:
135  * @code
136  * // creation of a set with 10 elements
137  * Set<int> set;
138  * for (int i = 0; i< 10; ++i)
139  * set<<i;
140  * Set<int> set2 { 1, 2, 3 };
141  *
142  * // parse the set
143  * for (const auto iter = set.begin (); iter != set.end (); ++iter) {
144  * // display the values
145  * cerr << *iter << endl;
146  * }
147  *
148  * // use an iterator to point the element we wish to erase
149  * Set<int>::iterator iter = set.begin ();
150  * set.erase ( iter );
151  *
152  * // check whether two iterators point toward the same element
153  * Set<int>::iterator iter1 = set.begin();
154  * Set<int>::iterator iter2 = set.end();
155  * if (iter1 != iter2)
156  * cerr << "iter1 and iter2 point toward different elements";
157  *
158  * @endcode
159  *
160  * @tparam Key The elements type.
161  * @tparam Alloc The elements allocator.
162  */
163  template < typename Key, typename Alloc = std::allocator< Key > >
164  class Set {
165  public:
166  /// Types for STL compliance.
167  /// @{
168  using value_type = Key;
169  using reference = Key&;
170  using const_reference = const Key&;
171  using pointer = Key*;
172  using const_pointer = const Key*;
173  using size_type = std::size_t;
174  using difference_type = std::ptrdiff_t;
175  using allocator_type = Alloc;
176  using iterator = SetIterator< Key >;
177  using const_iterator = SetIterator< Key >;
178  using iterator_safe = SetIteratorSafe< Key >;
179  using const_iterator_safe = SetIteratorSafe< Key >;
180  /// @}
181 
182  // ============================================================================
183  /// @name Constructors / Destructors
184  // ============================================================================
185  /// @{
186 
187  /**
188  * @brief Default constructor.
189  *
190  * Sets rely on hashtables to store their items. The optional parameters of
191  * this constructor enable a fine memory management of these hashtables.
192  *
193  * @param capacity The number of slots allocated to the hashtable (see the
194  * HashTable default constructor)
195  * @param resize_policy Enables the hashtable to resize itself
196  * automatically when its number of elements is sufficiently high that it
197  * induces slow retrievals of elements.
198  */
199  explicit Set(Size capacity = HashTableConst::default_size,
200  bool resize_policy = true);
201 
202  /**
203  * @brief Initializer list constructor.
204  * @param list The initializer list.
205  */
206  Set(std::initializer_list< Key > list);
207 
208  /**
209  * @brief Copy constructor.
210  * @param aHT The gum::Set to copy.
211  */
212  Set(const Set< Key, Alloc >& aHT);
213 
214  /**
215  * @brief Generalized copy constructor.
216  * @param aHT The gum::Set to copy.
217  * @tparam OtherAlloc The other gum::Set allocator.
218  */
219  template < typename OtherAlloc >
220  Set(const Set< Key, OtherAlloc >& aHT);
221 
222  /**
223  * @brief Move constructor.
224  * @param aHT The gum::Set to move.
225  */
226  Set(Set< Key, Alloc >&& aHT);
227 
228  /**
229  * @brief Class destructor.
230  */
231  ~Set();
232 
233  /// @}
234  // ============================================================================
235  /// @name Operators
236  // ============================================================================
237  /// @{
238 
239  /**
240  * @brief Copy operator.
241  * @param from The gum::Set to copy.
242  * @return Returns this gum::Set.
243  */
244  Set< Key, Alloc >& operator=(const Set< Key, Alloc >& from);
245 
246  /**
247  * @brief Generalized copy operator.
248  * @param from The gum::Set to copy.
249  * @tparam OtherAlloc The other gum::Set allocator.
250  * @return Returns this gum::Set.
251  */
252  template < typename OtherAlloc >
253  Set< Key, Alloc >& operator=(const Set< Key, OtherAlloc >& from);
254 
255  /**
256  * @brief Move operator.
257  * @param from The gum::Set to move.
258  * @return Returns this gum::Set.
259  */
260  Set< Key, Alloc >& operator=(Set< Key, Alloc >&& from);
261 
262  /**
263  * @brief Mathematical equality between two sets.
264  * @param s2 The gum::Set to test for equality.
265  * @tparam OtherAlloc The other gum::Set allocator.
266  * @return Returns true if both gum::Set are equal.
267  */
268  template < typename OtherAlloc >
269  bool operator==(const Set< Key, OtherAlloc >& s2) const;
270 
271  /**
272  * @brief Mathematical inequality between two sets.
273  * @param s2 The gum::Set to test for inequality.
274  * @tparam OtherAlloc The other gum::Set allocator.
275  * @return Returns true if both gum::Set are not equal.
276  */
277  template < typename OtherAlloc >
278  bool operator!=(const Set< Key, OtherAlloc >& s2) const;
279 
280  /**
281  * @brief Intersection update operator
282  * @tparam OtherAlloc The other gum::Set allocator.
283  * @param s2 The gum::Set to intersect.
284  * @return Returns this. Now this contains the elements belonging
285  * both to this and s2.
286  */
287  template < typename OtherAlloc >
288  const Set< Key, Alloc >& operator*=(const Set< Key, OtherAlloc >& s2);
289 
290  /**
291  * @brief Intersection operator.
292  * @tparam OtherAlloc The other gum::Set allocator.
293  * @param s2 The gum::Set to intersect.
294  * @return Returns a Set containing the elements belonging both to this and
295  * s2.
296  */
297  template < typename OtherAlloc >
298  Set< Key, Alloc > operator*(const Set< Key, OtherAlloc >& s2) const;
299 
300  /**
301  * @brief Union update operator
302  * @tparam OtherAlloc The other gum::Set allocator.
303  * @param s2 The gum::Set to update
304  * @return Returns this. Now this contains the elements belonging
305  * both to this or to s2.
306  */
307  template < typename OtherAlloc >
308  const Set< Key, Alloc >& operator+=(const Set< Key, OtherAlloc >& s2);
309 
310  /**
311  * @brief Union operator.
312  * @tparam OtherAlloc The other gum::Set allocator.
313  * @param s2 The gum::Set to union.
314  * @return Returns a new Set containing the union of the elements of this
315  * and s2.
316  */
317  template < typename OtherAlloc >
318  Set< Key, Alloc > operator+(const Set< Key, OtherAlloc >& s2) const;
319 
320 
321  /**
322  * @brief Disjunction operator.
323  * @tparam OtherAlloc The other gum::Set allocator.
324  * @param s2 The gum::Set to disjunct.
325  * @return Returns a Set whose elements belong to this but not to s2.
326  * @warning Unlike + and *, the - operator is not commutative!
327  */
328  template < typename OtherAlloc >
329  Set< Key, Alloc > operator-(const Set< Key, OtherAlloc >& s2) const;
330 
331  /**
332  * @brief Adds a new element to the set (alias for insert).
333  * @param k The new element to add.
334  * @return Returns this gum::Set.
335  */
336  Set< Key, Alloc >& operator<<(const Key& k);
337 
338  /**
339  * @brief Adds a new element to the set (alias for insert).
340  * @param k The new element to add.
341  * @return Returns this gum::Set.
342  */
343  Set< Key, Alloc >& operator<<(Key&& k);
344 
345  /**
346  * @brief Removes an element from the set (alias for erase).
347  * @param k The element to remove.
348  * @return Return this gum::Set.
349  */
350  Set< Key, Alloc >& operator>>(const Key& k);
351 
352  /// @}
353  // ============================================================================
354  /// @name Accessors / Modifiers
355  // ============================================================================
356  /// @{
357 
358  /**
359  * @brief Inserts a new element into the set.
360  * @param k The new element to insert.
361  * @warning if the set already contains the element, nothing is done. In
362  * particular, it is not added to the set and no exception is thrown.
363  */
364  void insert(const Key& k);
365 
366  /**
367  * @brief Inserts a new element into the set.
368  * @param k The new element to insert.
369  * @warning if the set already contains the element, nothing is done. In
370  * particular, it is not added to the set and no exception is thrown.
371  */
372  void insert(Key&& k);
373 
374  /**
375  * @brief Emplace a new element in the set.
376  *
377  * Emplace is a method that allows to construct directly an element of type
378  * Key by passing to its constructor all the arguments it needs.
379  *
380  * @param args the arguments passed to the constructor
381  * @warning if the set already contains the element, nothing is done. In
382  * particular, it is not added to the set and no exception is thrown.
383  */
384  template < typename... Args >
385  void emplace(Args&&... args);
386 
387  /**
388  * @brief Erases an element from the set.
389  *
390  * @param k The element to remove.
391  * @warning if the set does not contain the element, nothing is done. In
392  * particular, no exception is thrown.
393  */
394  void erase(const Key& k);
395 
396  /**
397  * @brief Erases an element from the set.
398  * @param k The iterator pointing to the element to remove.
399  * @warning if the set does not contain the element, nothing is done. In
400  * particular, no exception is thrown.
401  */
402  void erase(const iterator_safe& k);
403 
404  /**
405  * @brief Removes all the elements, if any, from the set.
406  */
407  void clear();
408 
409  /**
410  * @brief Returns the number of elements in the set.
411  * @return Returns the number of elements in the set.
412  */
413  Size size() const noexcept;
414 
415  /**
416  * @brief Indicates whether a given elements belong to the set.
417  * @return Returns true if a given elements belong to the set.
418  */
419  bool contains(const Key& k) const;
420 
421  /**
422  * @return Returns true if *this is a proper subset of s
423  */
424  template < typename OtherAlloc >
425  bool isProperSubsetOf(const Set< Key, OtherAlloc >& s) const;
426 
427  /**
428  * @return Returns true if *this is a proper superset of s
429  */
430  template < typename OtherAlloc >
431  bool isProperSupersetOf(const Set< Key, OtherAlloc >& s) const;
432 
433  /**
434  * @return Returns true if *this is a subset of s (or equal to s)
435  */
436  template < typename OtherAlloc >
437  bool isSubsetOrEqual(const Set< Key, OtherAlloc >& s) const;
438 
439  /**
440  * @return Returns true if *this is a superset of s (or equal to s)
441  */
442  template < typename OtherAlloc >
443  bool isSupersetOrEqual(const Set< Key, OtherAlloc >& s) const;
444 
445  /**
446  * @brief Indicates whether a given elements belong to the set.
447  * @return Returns true if a given elements belong to the set.
448  */
449  bool exists(const Key& k) const;
450 
451  /**
452  * @brief Indicates whether the set is the empty set.
453  * @return Returns true if the set is empty.
454  */
455  bool empty() const noexcept;
456 
457  /**
458  * @brief Prints the content of the set.
459  * @return Returns the content of the set.
460  */
461  std::string toString() const;
462 
463  /// @}
464  // ============================================================================
465  /// @name Iterators
466  // ============================================================================
467  /// @{
468 
469  /**
470  * @brief The usual safe begin iterator to parse the set.
471  * @return Returns The usual safe begin iterator to parse the set.
472  */
473  iterator_safe beginSafe() const;
474 
475  /**
476  * @brief The usual safe begin iterator to parse the set.
477  * @return Returns the usual safe begin iterator to parse the set.
478  */
479  const_iterator_safe cbeginSafe() const;
480 
481  /**
482  * @brief The usual safe end iterator to parse the set.
483  * @return Returns the usual safe end iterator to parse the set.
484  */
485  const iterator_safe& endSafe() const noexcept;
486 
487  /**
488  * @brief The usual safe end iterator to parse the set.
489  * @return Returns the usual safe end iterator to parse the set.
490  */
491  const const_iterator_safe& cendSafe() const noexcept;
492 
493  /**
494  * @brief The usual unsafe begin iterator to parse the set.
495  * @return Returns the usual unsafe begin iterator to parse the set.
496  */
497  iterator begin() const;
498 
499  /**
500  * @brief The usual unsafe begin iterator to parse the set.
501  * @return Returns the usual unsafe begin iterator to parse the set.
502  */
503  const_iterator cbegin() const;
504 
505  /**
506  * @brief The usual unsafe end iterator to parse the set.
507  * @return Returns the usual unsafe end iterator to parse the set.
508  */
509  const iterator& end() const noexcept;
510 
511  /**
512  * @brief The usual unsafe end iterator to parse the set.
513  * @return Returns the usual unsafe end iterator to parse the set.
514  */
515  const const_iterator& cend() const noexcept;
516 
517  /**
518  * @brief Returns the end iterator for other classes' statics (read the
519  * detailed description of this method).
520  *
521  * To reduce the Sets memory consumption (which are heavily used in aGrUM)
522  * while allowing fast for(iter=begin(); iter!=end();++iter) loops, end
523  * iterators are created just once as a static member of a non-template
524  * Set. While this scheme is efficient and it works quite effectively when
525  * manipulating sets, it has a drawback: other classes with static members
526  * using the Set's end() iterator may fail to work due to the well known
527  * "static initialization order fiasco" (see Marshall Cline's C++ FAQ for
528  * more details about this C++ feature). OK, so what is the problem?
529  * Consider a class, say X, containing a Set that stores all its elements
530  * in a convenient way. To reduce memory consumption, X::end iterator is a
531  * static member that is initialized with a Set::end iterator. If the
532  * compiler decides to initialize X::end before initializing Set::end, then
533  * X::end will be in an incoherent state. Unfortunately, we cannot know for
534  * sure in which order static members will be initialized (the order is a
535  * compiler's decision). Hence, we shall enfore the fact that Set::end is
536  * initialized before X::end. Using method Set::end4Statics will ensure
537  * this fact: it uses the C++ "construct on first use" idiom (see the C++
538  * FAQ) that ensures that the order fiasco is avoided. More precisely,
539  * end4Statics uses a global variable that is the very end iterator used by
540  * all Sets. Now, this induces a small overhead. So, we also provide a
541  * Set::end() method that returns the Set::end iterator without this small
542  * overhead, but assuming that function end4Statics has already been called
543  * once (which is always the case) when a Set has been created.
544  *
545  * So, to summarize: when initializing static members, use end4Statics()
546  * rather than end(). In all the other cases, use simply the usual method
547  * end().
548  *
549  * @return Returns the end iterator for other classes' statics (read the
550  * detailed description of this method).
551  */
552  static const iterator& end4Statics();
553 
554  /**
555  * @brief Returns the end iterator for other classes' statics (read the
556  * detailed description of this method).
557  *
558  * To reduce the Sets memory consumption (which are heavily used in aGrUM)
559  * while allowing fast for(iter=begin(); iter!=end();++iter) loops, end
560  * iterators are created just once as a static member of a non-template
561  * Set. While this scheme is efficient and it works quite effectively when
562  * manipulating sets, it has a drawback: other classes with static members
563  * using the Set's end() iterator may fail to work due to the well known
564  * "static initialization order fiasco" (see Marshall Cline's C++ FAQ for
565  * more details about this C++ feature). OK, so what is the problem?
566  * Consider a class, say X, containing a Set that stores all its elements
567  * in a convenient way. To reduce memory consumption, X::end iterator is a
568  * static member that is initialized with a Set::end iterator. If the
569  * compiler decides to initialize X::end before initializing Set::end, then
570  * X::end will be in an incoherent state. Unfortunately, we cannot know for
571  * sure in which order static members will be initialized (the order is a
572  * compiler's decision). Hence, we shall enfore the fact that Set::end is
573  * initialized before X::end. Using method Set::end4Statics will ensure
574  * this fact: it uses the C++ "construct on first use" idiom (see the C++
575  * FAQ) that ensures that the order fiasco is avoided. More precisely,
576  * end4Statics uses a global variable that is the very end iterator used by
577  * all Sets. Now, this induces a small overhead. So, we also provide a
578  * Set::end() method that returns the Set::end iterator without this small
579  * overhead, but assuming that function end4Statics has already been called
580  * once (which is always the case) when a Set has been created.
581  *
582  * So, to summarize: when initializing static members, use
583  * constEnd4Statics() rather than cend(). In all the other cases, use
584  * simply the usual method cend().
585  *
586  * @return Returns the end iterator for other classes' statics (read the
587  * detailed description of this method).
588  */
589  static const const_iterator& constEnd4Statics();
590 
591  /**
592  * @brief Returns the end iterator for other classes' statics (read the
593  * detailed description of this method).
594  *
595  * To reduce the Sets memory consumption (which are heavily used in aGrUM)
596  * while allowing fast for(iter=begin(); iter!=end();++iter) loops, end
597  * iterators are created just once as a static member of a non-template
598  * Set. While this scheme is efficient and it works quite effectively when
599  * manipulating sets, it has a drawback: other classes with static members
600  * using the Set's end() iterator may fail to work due to the well known
601  * "static initialization order fiasco" (see Marshall Cline's C++ FAQ for
602  * more details about this C++ feature). OK, so what is the problem?
603  * Consider a class, say X, containing a Set that stores all its elements
604  * in a convenient way. To reduce memory consumption, X::end iterator is a
605  * static member that is initialized with a Set::end iterator. If the
606  * compiler decides to initialize X::end before initializing Set::end, then
607  * X::end will be in an incoherent state. Unfortunately, we cannot know for
608  * sure in which order static members will be initialized (the order is a
609  * compiler's decision). Hence, we shall enfore the fact that Set::end is
610  * initialized before X::end. Using method Set::end4Statics will ensure
611  * this fact: it uses the C++ "construct on first use" idiom (see the C++
612  * FAQ) that ensures that the order fiasco is avoided. More precisely,
613  * end4Statics uses a global variable that is the very end iterator used by
614  * all Sets. Now, this induces a small overhead. So, we also provide a
615  * Set::end() method that returns the Set::end iterator without this small
616  * overhead, but assuming that function end4Statics has already been called
617  * once (which is always the case) when a Set has been created.
618  *
619  * So, to summarize: when initializing static members, use
620  * endSafe4Statics() rather than endSafe (). In all the other cases, use
621  * simply the usual method endSafe ().
622  *
623  * @return Returns the end iterator for other classes' statics (read the
624  * detailed description of this method).
625  */
626  static const iterator_safe& endSafe4Statics();
627 
628  /**
629  * @brief Returns the end iterator for other classes' statics (read the
630  * detailed description of this method).
631  *
632  * To reduce the Sets memory consumption (which are heavily used in aGrUM)
633  * while allowing fast for(iter=begin(); iter!=end();++iter) loops, end
634  * iterators are created just once as a static member of a non-template
635  * Set. While this scheme is efficient and it works quite effectively when
636  * manipulating sets, it has a drawback: other classes with static members
637  * using the Set's end() iterator may fail to work due to the well known
638  * "static initialization order fiasco" (see Marshall Cline's C++ FAQ for
639  * more details about this C++ feature). OK, so what is the problem?
640  * Consider a class, say X, containing a Set that stores all its elements
641  * in a convenient way. To reduce memory consumption, X::end iterator is a
642  * static member that is initialized with a Set::end iterator. If the
643  * compiler decides to initialize X::end before initializing Set::end, then
644  * X::end will be in an incoherent state. Unfortunately, we cannot know for
645  * sure in which order static members will be initialized (the order is a
646  * compiler's decision). Hence, we shall enfore the fact that Set::end is
647  * initialized before X::end. Using method Set::end4Statics will ensure
648  * this fact: it uses the C++ "construct on first use" idiom (see the C++
649  * FAQ) that ensures that the order fiasco is avoided. More precisely,
650  * end4Statics uses a global variable that is the very end iterator used by
651  * all Sets. Now, this induces a small overhead. So, we also provide a
652  * Set::end() method that returns the Set::end iterator without this small
653  * overhead, but assuming that function end4Statics has already been called
654  * once (which is always the case) when a Set has been created.
655  *
656  * So, to summarize: when initializing static members, use
657  * constEndSafe4Statics() rather than cendSafe(). In all the other cases,
658  * use simply the usual method cendSafe ().
659  *
660  * @return Returns the end iterator for other classes' statics (read the
661  * detailed description of this method).
662  */
663  static const const_iterator_safe& constEndSafe4Statics();
664 
665  /// @}
666  // ============================================================================
667  /// @name Fine tuning
668  // ============================================================================
669  /// @{
670 
671  /**
672  * @brief Returns the capacity of the underlying hash table containing the
673  * set.
674  *
675  * The method runs in constant time.
676  *
677  * @return Returns the capacity of the underlying hash table containing the
678  * set.
679  */
680  Size capacity() const;
681 
682  /**
683  * @brief Changes the size of the underlying hash table containing the set.
684  *
685  * See gum::HashTable::resize(Size) method resize for more details.
686  *
687  * @param new_capacity The underlying hash table new size.
688  */
689  void resize(Size new_capacity);
690 
691  /**
692  * @brief Enables the user to change dynamically the resizing policy of the
693  * underlying hash table.
694  *
695  * When new_policy is false, the set will not try to change its memory
696  * size, hence resulting in potentially slower accesses.
697  *
698  * @param new_policy If true the set updates dynamically its memory
699  * consumption to guarantee that its elements are fast to retrieve.
700  */
701  void setResizePolicy(const bool new_policy);
702 
703  /**
704  * @brief Returns the current resizing policy of the underlying hash table.
705  * @return Returns the current resizing policy of the underlying hash
706  * table.
707  */
708  bool resizePolicy() const;
709 
710  /// @}
711  // ============================================================================
712  /// @name Mapper
713  // ============================================================================
714  /// @{
715 
716  /**
717  * @brief Creates a hashtable of NewKey from the set.
718  *
719  * @warning The order in the resulting hashtable may not be similar to that
720  * of the original set. Hence iterators on the former may not parse it in
721  * the same order as iterators on the latter.
722  *
723  * @param f A function that maps Key into a NewKey
724  * @param capacity The size of the resulting hashtable. When equal to 0, a
725  * default size is computed that is a good trade-off between space
726  * consumption and efficiency of new elements insertions.
727  */
728  template < typename NewKey,
729  typename NewAlloc
730  = typename Alloc::template rebind< NewKey >::other >
731  HashTable< Key, NewKey, NewAlloc > hashMap(NewKey (*f)(const Key&),
732  Size capacity = 0) const;
733 
734  /**
735  * @brief Creates a hash table of NewKey from the set.
736  *
737  * @warning The order in the resulting hash table may not be similar to
738  * that of the original set. Hence iterators on the former may not parse it
739  * in the same order as iterators on the latter.
740  *
741  * @param val The value taken by all the elements of the resulting
742  * hashtable.
743  * @param size The size of the resulting hash table. When equal to 0, a
744  * default size is computed that is a good trade-off between space
745  * consumption and efficiency of new elements insertions.
746  */
747  template < typename NewKey,
748  typename NewAlloc
749  = typename Alloc::template rebind< NewKey >::other >
750  HashTable< Key, NewKey, NewAlloc > hashMap(const NewKey& val,
751  Size size = 0) const;
752 
753  /**
754  * @brief A method to create a List of NewKey from the set.
755  *
756  * @warning The order of the NewKey elements in the resulting list is
757  * arbitrary.
758  *
759  * @param f A function that maps a Key into a NewKey
760  */
761  template < typename NewKey,
762  typename NewAlloc
763  = typename Alloc::template rebind< NewKey >::other >
764  List< NewKey, NewAlloc > listMap(NewKey (*f)(const Key&)) const;
765 
766  /// @}
767 
768  private:
769  /// Friends to speed up access
770  /// @{
771  friend class SetIterator< Key >;
772  friend class SetIteratorSafe< Key >;
773  template < typename K, typename A >
774  friend class Set;
775  /// @}
776 
777  /// A set of X's is actually a hash table whose keys are the X's.
778  HashTable< Key, bool, Alloc > inside__;
779 
780  /// Convert a hash table into a set of keys.
781  Set(const HashTable< Key, bool, Alloc >& h);
782  };
783 
784 
785  // ===========================================================================
786  // === SAFE SET ITERATORS ===
787  // ===========================================================================
788 
789  /**
790  * @class SetIteratorSafe
791  * @headerfile set.h <agrum/tools/core/set.h>
792  * @brief Safe iterators for the Set class
793  * @ingroup set_group
794  *
795  * Developers may consider using Set<x>::iterator_safe instead of
796  * SetIteratorSafe<x>.
797  *
798  * @par Usage example:
799  * @code
800  * // creation of a set with 10 elements
801  * Set<int> set;
802  * for (int i = 0; i< 10; ++i)
803  * set<<i;
804  *
805  * // parse the set
806  * for (const auto iter = table.beginSafe (); iter != table.endSafe (); ++iter) {
807  * // display the values
808  * cerr << *iter << endl;
809  * }
810  *
811  * // check whether two iterators point toward the same element
812  * Set<int>::iterator_safe iter1 = table1.beginSafe();
813  * Set<int>::iterator_safe iter2 = table1.endSafe();
814  * if (iter1 != iter)
815  * cerr << "iter1 and iter2 point toward different elements";
816  *
817  * @endcode
818  *
819  * @tparam Key The elements type.
820  */
821  template < typename Key >
822  class SetIteratorSafe {
823  public:
824  /// Types for STL compliance.
825  /// @{
826  using iterator_category = std::forward_iterator_tag;
827  using value_type = Key;
828  using reference = value_type&;
829  using const_reference = const value_type&;
830  using pointer = value_type*;
831  using const_pointer = const value_type*;
832  using difference_type = std::ptrdiff_t;
833  /// @}
834 
835  /**
836  * @brief An enumeration to position the iterator at the beginning or the
837  * end of the set.
838  */
839  enum Position
840  {
841  BEGIN,
842  END
843  };
844 
845  // ============================================================================
846  /// @name Constructors / Destructors
847  // ============================================================================
848  /// @{
849 
850  /**
851  * @brief Default constructor: the iterator points toward nothing.
852  */
853  SetIteratorSafe();
854 
855  /**
856  * @brief Creates an iterator for a given set.
857  *
858  * By default, the iterator points to the beginning of the set, but, using
859  * optional argument pos, you can make it point to end().
860  *
861  * @tparam Alloc The gum::Set allocator.
862  * @param from The gum::Set to iterate over.
863  * @param pos Where to start iterating.
864  */
865  template < typename Alloc >
866  SetIteratorSafe(const Set< Key, Alloc >& from, Position pos = BEGIN);
867 
868  /**
869  * @brief Copy constructor.
870  * @param from The iterator to copy.
871  */
872  SetIteratorSafe(const SetIteratorSafe< Key >& from);
873 
874  /**
875  * @brief Copy constructor.
876  * @param from The iterator to copy.
877  */
878  explicit SetIteratorSafe(const SetIterator< Key >& from);
879 
880  /**
881  * @brief Move constructor.
882  * @param from The iterator to move.
883  */
884  SetIteratorSafe(SetIteratorSafe< Key >&& from);
885 
886  /**
887  * Class destructor.
888  */
889  ~SetIteratorSafe() noexcept;
890 
891  /// @}
892  // ============================================================================
893  /// @name Operators
894  // ============================================================================
895  /// @{
896 
897  /**
898  * @brief Assignment operator.
899  * @param from The iterator to copy.
900  * @return Returns this iterator.
901  */
902  SetIteratorSafe< Key >& operator=(const SetIteratorSafe< Key >& from);
903 
904  /**
905  * @brief Assignment operator.
906  * @param from The iterator to copy.
907  * @return Returns this iterator.
908  */
909  SetIteratorSafe< Key >& operator=(const SetIterator< Key >& from);
910 
911  /**
912  * @brief Assignment operator.
913  * @param from The iterator to move.
914  * @return Returns this iterator.
915  */
916  SetIteratorSafe< Key >& operator=(SetIteratorSafe< Key >&& from) noexcept;
917 
918  /**
919  * @brief Increments the iterator.
920  * @return This iterator.
921  */
922  SetIteratorSafe< Key >& operator++() noexcept;
923 
924  /**
925  * @brief Makes the iterator point to i elements further in the set.
926  * @param i The number of increments.
927  * @return Returns this iterator.
928  */
929  SetIteratorSafe< Key >& operator+=(Size i) noexcept;
930 
931  /**
932  * @brief Returns a new iterator.
933  * @param i The number of increments.
934  * @return Returns a new iterator.
935  */
936  SetIteratorSafe< Key > operator+(Size i) const;
937 
938  /**
939  * @brief Indicates whether two iterators point to different elements or
940  * sets.
941  * @param from The iterator to test for inequality.
942  * @return Returns true if both iterator are not equal.
943  */
944  bool operator!=(const SetIteratorSafe< Key >& from) const noexcept;
945 
946  /**
947  * @brief Indicates whether two iterators point toward the same element of
948  * a same set.
949  * @param from The iterator to test for equality.
950  * @return Returns true if both iterator are equal.
951  */
952  bool operator==(const SetIteratorSafe< Key >& from) const noexcept;
953 
954  /**
955  * @brief Returns the element pointed to by the iterator.
956  *
957  * @throws UndefinedIteratorValue Raised if the iterator does not point
958  * to an element of the set (for instance if the set or the element
959  * previously pointed to by the iterator have been deleted).
960  *
961  * @return Returns the element pointed to by the iterator.
962  */
963  const Key& operator*() const;
964 
965  /**
966  * @brief Returns a pointer to the element pointed to by the iterator.
967  *
968  * @throws UndefinedIteratorValue Raised if the iterator does not point
969  * to an element of the set (for instance if the set or the element
970  * previously pointed to by the iterator have been deleted).
971  *
972  * @return Returns a pointer to the element pointed to by the iterator.
973  */
974  const Key* operator->() const;
975 
976  /// @}
977  // ============================================================================
978  /// @name Accessors / Modifiers
979  // ============================================================================
980  /// @{
981 
982  /**
983  * @brief makes the iterator point toward nothing (in particular, it is not
984  * related anymore to its current set).
985  */
986  void clear() noexcept;
987 
988  /// @}
989 
990  private:
991  /// For efficiency, Set should be able to modify the hash table iterator.
992  template < typename K, typename A >
993  friend class Set;
994 
995  /// The underlying iterator for the set's hash table containing the data.
996  HashTableConstIteratorSafe< Key, bool > ht_iter__;
997  };
998 
999  // ===========================================================================
1000  // === UNSAFE SET ITERATORS ===
1001  // ===========================================================================
1002 
1003  /**
1004  * @class SetIterator
1005  * @headerfile set.h <agrum/tools/core/set.h>
1006  * @brief Unsafe iterators for the Set class.
1007  * @ingroup set_group
1008  *
1009  * Developers may consider using Set<x>::iterator instead of SetIterator<x>.
1010  *
1011  * @warning Use SetIterator only if you are sure that the iterator will never
1012  * point to a deleted element. Pointing to a deleted element will most
1013  * probably result in a segfault. If you are unsure, prefer using the safe
1014  * iterators Set<>::iterator_safe.
1015  *
1016  * @par Usage example:
1017  * @code
1018  * // creation of a set with 10 elements
1019  * Set<int> set;
1020  * for (int i = 0; i< 10; ++i)
1021  * set<<i;
1022  *
1023  * // parse the set
1024  * for (const auto iter = table.begin (); iter != table.end (); *++iter) {
1025  * // display the values
1026  * cerr << *iter << endl;
1027  * }
1028  *
1029  * // check whether two iterators point toward the same element
1030  * Set<int>::iterator iter1 = table1.begin();
1031  * Set<int>::iterator iter2 = table1.end();
1032  * if (iter1 != iter)
1033  * cerr << "iter1 and iter2 point toward different elements";
1034  *
1035  * @endcode
1036  *
1037  * @tparam Key The elements type.
1038  */
1039  template < typename Key >
1040  class SetIterator {
1041  public:
1042  /// Types for STL compliance.
1043  /// @{
1044  using iterator_category = std::forward_iterator_tag;
1045  using value_type = Key;
1046  using reference = value_type&;
1047  using const_reference = const value_type&;
1048  using pointer = value_type*;
1049  using const_pointer = const value_type*;
1050  using difference_type = std::ptrdiff_t;
1051  /// @}
1052 
1053  /**
1054  * @brief An enumeration to position the iterator at the beginning or the
1055  * end of the set.
1056  */
1057  enum Position
1058  {
1059  BEGIN,
1060  END
1061  };
1062 
1063  // ============================================================================
1064  /// @name Constructors / Destructors
1065  // ============================================================================
1066  /// @{
1067 
1068  /**
1069  * @brief Default constructor: the iterator points toward nothing.
1070  */
1071  SetIterator() noexcept;
1072 
1073  /**
1074  * @brief Creates an iterator for a given set.
1075  *
1076  * By default, the iterator points to the beginning of the set, but, using
1077  * optional argument pos, you can make it point to end().
1078  *
1079  * @tparam Alloc The gum::Set allocator.
1080  * @param from The gum::Set to iterator over.
1081  * @param pos Where to start iterating.
1082  */
1083  template < typename Alloc >
1084  SetIterator(const Set< Key, Alloc >& from, Position pos = BEGIN);
1085 
1086  /**
1087  * @brief Copy constructor.
1088  * @param from The iterator to copy.
1089  */
1090  SetIterator(const SetIterator< Key >& from) noexcept;
1091 
1092  /**
1093  * @brief Move constructor.
1094  * @param from The iterator to move.
1095  */
1096  SetIterator(SetIterator< Key >&& from) noexcept;
1097 
1098  /**
1099  * @brief Class destructor.
1100  */
1101  ~SetIterator() noexcept;
1102 
1103  /// @}
1104  // ============================================================================
1105  /// @name Operators
1106  // ============================================================================
1107  /// @{
1108 
1109  /**
1110  * @brief Assignment operator.
1111  * @param from The iterator to copy.
1112  * @return Returns this iterator.
1113  */
1114  SetIterator< Key >& operator=(const SetIterator< Key >& from) noexcept;
1115 
1116  /**
1117  * @brief Assignment operator.
1118  * @param from The iterator to copy.
1119  * @return Returns this iterator.
1120  */
1121  SetIterator< Key >& operator=(SetIterator< Key >&& from) noexcept;
1122 
1123  /**
1124  * @brief Increments the iterator.
1125  * @return This iterator.
1126  */
1127  SetIterator< Key >& operator++() noexcept;
1128 
1129  /**
1130  * @brief Makes the iterator point to i elements further in the set.
1131  * @param i The number of increments.
1132  * @return Returns this iterator.
1133  */
1134  SetIterator< Key >& operator+=(Size i) noexcept;
1135 
1136  /**
1137  * @brief Returns a new iterator.
1138  * @param i The number of increments.
1139  * @return Returns a new iterator.
1140  */
1141  SetIterator< Key > operator+(Size i) const noexcept;
1142 
1143  /**
1144  * @brief Indicates whether two iterators point to different elements or
1145  * sets.
1146  * @param from The iterator to test for inequality.
1147  * @return Returns true if both iterator are not equal.
1148  */
1149  bool operator!=(const SetIterator< Key >& from) const noexcept;
1150 
1151  /**
1152  * @brief Indicates whether two iterators point toward the same element of
1153  * a same set.
1154  * @param from The iterator to test for equality.
1155  * @return Returns true if both iterator are equal.
1156  */
1157  bool operator==(const SetIterator< Key >& from) const noexcept;
1158 
1159  /**
1160  * @brief Returns the element pointed to by the iterator.
1161  *
1162  * @throws UndefinedIteratorValue Raised if the iterator does not point
1163  * to an element of the set (for instance if the set or the element
1164  * previously pointed to by the iterator have been deleted).
1165  *
1166  * @return Returns the element pointed to by the iterator.
1167  */
1168  const Key& operator*() const;
1169 
1170  /**
1171  * @brief Returns a pointer to the element pointed to by the iterator.
1172  *
1173  * @throws UndefinedIteratorValue Raised if the iterator does not point
1174  * to an element of the set (for instance if the set or the element
1175  * previously pointed to by the iterator have been deleted).
1176  *
1177  * @return Returns a pointer to the element pointed to by the iterator.
1178  */
1179  const Key* operator->() const;
1180 
1181  /// @}
1182  // ============================================================================
1183  /// @name Accessors / Modifiers
1184  // ============================================================================
1185  /// @{
1186 
1187  /**
1188  * @brief makes the iterator point toward nothing (in particular, it is not
1189  * related anymore to its current set).
1190  */
1191  void clear() noexcept;
1192 
1193  /// @}
1194 
1195  private:
1196  /// For efficiency, Set should be able to modify the hash table iterator.
1197  template < typename K, typename A >
1198  friend class Set;
1199  friend class SetIteratorSafe< Key >;
1200 
1201  /// The underlying iterator for the set's hash table containing the data.
1202  HashTableConstIterator< Key, bool > ht_iter__;
1203  };
1204 
1205 
1206  /// @brief A << operator for HashTableList.
1207  template < typename Key, typename Alloc >
1208  std::ostream& operator<<(std::ostream&, const Set< Key, Alloc >&);
1209 
1210 
1211  /// the hash function for sets of int
1212  template < typename T, typename Alloc >
1213  class HashFunc< Set< T, Alloc > >: public HashFuncBase< Set< T, Alloc > > {
1214  public:
1215  /**
1216  * @brief Returns the value of a key as a Size.
1217  * @param key The value to return as a Size.
1218  * @return Returns the value of a key as a Size.
1219  */
1220  static Size castToSize(const Set< T, Alloc >& key);
1221 
1222  /// computes the hashed value of a key
1223  virtual Size operator()(const Set< T, Alloc >& key) const override final;
1224  };
1225 
1226 } /* namespace gum */
1227 
1228 
1229 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1230 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1231 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1232 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1233 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1234 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1235 extern template class gum::Set< int >;
1236 # endif
1237 # endif
1238 # endif
1239 # endif
1240 # endif
1241 #endif
1242 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1243 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1244 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1245 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1246 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1247 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1248 extern template class gum::Set< long >;
1249 # endif
1250 # endif
1251 # endif
1252 # endif
1253 # endif
1254 #endif
1255 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1256 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1257 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1258 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1259 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1260 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1261 extern template class gum::Set< unsigned int >;
1262 # endif
1263 # endif
1264 # endif
1265 # endif
1266 # endif
1267 #endif
1268 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1269 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1270 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1271 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1272 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1273 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1274 extern template class gum::Set< unsigned long >;
1275 # endif
1276 # endif
1277 # endif
1278 # endif
1279 # endif
1280 #endif
1281 
1282 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1283 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1284 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1285 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1286 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1287 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1288 extern template class gum::Set< double >;
1289 # endif
1290 # endif
1291 # endif
1292 # endif
1293 # endif
1294 #endif
1295 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1296 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1297 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1298 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1299 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1300 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1301 extern template class gum::Set< std::string >;
1302 # endif
1303 # endif
1304 # endif
1305 # endif
1306 # endif
1307 #endif
1308 
1309 
1310 // always include the implementation of the templates
1311 #include <agrum/tools/core/set_tpl.h>
1312 
1313 #endif // GUM_SET_H