libstdc++
unordered_set.h
Go to the documentation of this file.
1 // unordered_set implementation -*- C++ -*-
2 
3 // Copyright (C) 2010-2022 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // 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 General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/unordered_set.h
26  * This is an internal header file, included by other library headers.
27  * Do not attempt to use it directly. @headername{unordered_set}
28  */
29 
30 #ifndef _UNORDERED_SET_H
31 #define _UNORDERED_SET_H
32 
33 namespace std _GLIBCXX_VISIBILITY(default)
34 {
35 _GLIBCXX_BEGIN_NAMESPACE_VERSION
36 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
37 
38  /// Base types for unordered_set.
39  template<bool _Cache>
40  using __uset_traits = __detail::_Hashtable_traits<_Cache, true, true>;
41 
42  template<typename _Value,
43  typename _Hash = hash<_Value>,
44  typename _Pred = std::equal_to<_Value>,
45  typename _Alloc = std::allocator<_Value>,
47  using __uset_hashtable = _Hashtable<_Value, _Value, _Alloc,
48  __detail::_Identity, _Pred, _Hash,
49  __detail::_Mod_range_hashing,
50  __detail::_Default_ranged_hash,
51  __detail::_Prime_rehash_policy, _Tr>;
52 
53  /// Base types for unordered_multiset.
54  template<bool _Cache>
55  using __umset_traits = __detail::_Hashtable_traits<_Cache, true, false>;
56 
57  template<typename _Value,
58  typename _Hash = hash<_Value>,
59  typename _Pred = std::equal_to<_Value>,
60  typename _Alloc = std::allocator<_Value>,
62  using __umset_hashtable = _Hashtable<_Value, _Value, _Alloc,
63  __detail::_Identity,
64  _Pred, _Hash,
65  __detail::_Mod_range_hashing,
66  __detail::_Default_ranged_hash,
67  __detail::_Prime_rehash_policy, _Tr>;
68 
69  template<class _Value, class _Hash, class _Pred, class _Alloc>
70  class unordered_multiset;
71 
72  /**
73  * @brief A standard container composed of unique keys (containing
74  * at most one of each key value) in which the elements' keys are
75  * the elements themselves.
76  *
77  * @ingroup unordered_associative_containers
78  *
79  * @tparam _Value Type of key objects.
80  * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
81 
82  * @tparam _Pred Predicate function object type, defaults to
83  * equal_to<_Value>.
84  *
85  * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
86  *
87  * Meets the requirements of a <a href="tables.html#65">container</a>, and
88  * <a href="tables.html#xx">unordered associative container</a>
89  *
90  * Base is _Hashtable, dispatched at compile time via template
91  * alias __uset_hashtable.
92  */
93  template<typename _Value,
94  typename _Hash = hash<_Value>,
95  typename _Pred = equal_to<_Value>,
96  typename _Alloc = allocator<_Value>>
98  {
99  typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
100  _Hashtable _M_h;
101 
102  public:
103  // typedefs:
104  ///@{
105  /// Public typedefs.
106  typedef typename _Hashtable::key_type key_type;
107  typedef typename _Hashtable::value_type value_type;
108  typedef typename _Hashtable::hasher hasher;
109  typedef typename _Hashtable::key_equal key_equal;
110  typedef typename _Hashtable::allocator_type allocator_type;
111  ///@}
112 
113  ///@{
114  /// Iterator-related typedefs.
115  typedef typename _Hashtable::pointer pointer;
116  typedef typename _Hashtable::const_pointer const_pointer;
117  typedef typename _Hashtable::reference reference;
118  typedef typename _Hashtable::const_reference const_reference;
119  typedef typename _Hashtable::iterator iterator;
120  typedef typename _Hashtable::const_iterator const_iterator;
121  typedef typename _Hashtable::local_iterator local_iterator;
122  typedef typename _Hashtable::const_local_iterator const_local_iterator;
123  typedef typename _Hashtable::size_type size_type;
124  typedef typename _Hashtable::difference_type difference_type;
125  ///@}
126 
127 #if __cplusplus > 201402L
128  using node_type = typename _Hashtable::node_type;
129  using insert_return_type = typename _Hashtable::insert_return_type;
130 #endif
131 
132  // construct/destroy/copy
133 
134  /// Default constructor.
135  unordered_set() = default;
136 
137  /**
138  * @brief Default constructor creates no elements.
139  * @param __n Minimal initial number of buckets.
140  * @param __hf A hash functor.
141  * @param __eql A key equality functor.
142  * @param __a An allocator object.
143  */
144  explicit
146  const hasher& __hf = hasher(),
147  const key_equal& __eql = key_equal(),
148  const allocator_type& __a = allocator_type())
149  : _M_h(__n, __hf, __eql, __a)
150  { }
151 
152  /**
153  * @brief Builds an %unordered_set from a range.
154  * @param __first An input iterator.
155  * @param __last An input iterator.
156  * @param __n Minimal initial number of buckets.
157  * @param __hf A hash functor.
158  * @param __eql A key equality functor.
159  * @param __a An allocator object.
160  *
161  * Create an %unordered_set consisting of copies of the elements from
162  * [__first,__last). This is linear in N (where N is
163  * distance(__first,__last)).
164  */
165  template<typename _InputIterator>
166  unordered_set(_InputIterator __first, _InputIterator __last,
167  size_type __n = 0,
168  const hasher& __hf = hasher(),
169  const key_equal& __eql = key_equal(),
170  const allocator_type& __a = allocator_type())
171  : _M_h(__first, __last, __n, __hf, __eql, __a)
172  { }
173 
174  /// Copy constructor.
175  unordered_set(const unordered_set&) = default;
176 
177  /// Move constructor.
179 
180  /**
181  * @brief Creates an %unordered_set with no elements.
182  * @param __a An allocator object.
183  */
184  explicit
186  : _M_h(__a)
187  { }
188 
189  /*
190  * @brief Copy constructor with allocator argument.
191  * @param __uset Input %unordered_set to copy.
192  * @param __a An allocator object.
193  */
194  unordered_set(const unordered_set& __uset,
195  const allocator_type& __a)
196  : _M_h(__uset._M_h, __a)
197  { }
198 
199  /*
200  * @brief Move constructor with allocator argument.
201  * @param __uset Input %unordered_set to move.
202  * @param __a An allocator object.
203  */
204  unordered_set(unordered_set&& __uset,
205  const allocator_type& __a)
206  noexcept( noexcept(_Hashtable(std::move(__uset._M_h), __a)) )
207  : _M_h(std::move(__uset._M_h), __a)
208  { }
209 
210  /**
211  * @brief Builds an %unordered_set from an initializer_list.
212  * @param __l An initializer_list.
213  * @param __n Minimal initial number of buckets.
214  * @param __hf A hash functor.
215  * @param __eql A key equality functor.
216  * @param __a An allocator object.
217  *
218  * Create an %unordered_set consisting of copies of the elements in the
219  * list. This is linear in N (where N is @a __l.size()).
220  */
222  size_type __n = 0,
223  const hasher& __hf = hasher(),
224  const key_equal& __eql = key_equal(),
225  const allocator_type& __a = allocator_type())
226  : _M_h(__l, __n, __hf, __eql, __a)
227  { }
228 
229  unordered_set(size_type __n, const allocator_type& __a)
230  : unordered_set(__n, hasher(), key_equal(), __a)
231  { }
232 
233  unordered_set(size_type __n, const hasher& __hf,
234  const allocator_type& __a)
235  : unordered_set(__n, __hf, key_equal(), __a)
236  { }
237 
238  template<typename _InputIterator>
239  unordered_set(_InputIterator __first, _InputIterator __last,
240  size_type __n,
241  const allocator_type& __a)
242  : unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
243  { }
244 
245  template<typename _InputIterator>
246  unordered_set(_InputIterator __first, _InputIterator __last,
247  size_type __n, const hasher& __hf,
248  const allocator_type& __a)
249  : unordered_set(__first, __last, __n, __hf, key_equal(), __a)
250  { }
251 
252  unordered_set(initializer_list<value_type> __l,
253  size_type __n,
254  const allocator_type& __a)
255  : unordered_set(__l, __n, hasher(), key_equal(), __a)
256  { }
257 
258  unordered_set(initializer_list<value_type> __l,
259  size_type __n, const hasher& __hf,
260  const allocator_type& __a)
261  : unordered_set(__l, __n, __hf, key_equal(), __a)
262  { }
263 
264  /// Copy assignment operator.
266  operator=(const unordered_set&) = default;
267 
268  /// Move assignment operator.
270  operator=(unordered_set&&) = default;
271 
272  /**
273  * @brief %Unordered_set list assignment operator.
274  * @param __l An initializer_list.
275  *
276  * This function fills an %unordered_set with copies of the elements in
277  * the initializer list @a __l.
278  *
279  * Note that the assignment completely changes the %unordered_set and
280  * that the resulting %unordered_set's size is the same as the number
281  * of elements assigned.
282  */
285  {
286  _M_h = __l;
287  return *this;
288  }
289 
290  /// Returns the allocator object used by the %unordered_set.
292  get_allocator() const noexcept
293  { return _M_h.get_allocator(); }
294 
295  // size and capacity:
296 
297  /// Returns true if the %unordered_set is empty.
298  _GLIBCXX_NODISCARD bool
299  empty() const noexcept
300  { return _M_h.empty(); }
301 
302  /// Returns the size of the %unordered_set.
303  size_type
304  size() const noexcept
305  { return _M_h.size(); }
306 
307  /// Returns the maximum size of the %unordered_set.
308  size_type
309  max_size() const noexcept
310  { return _M_h.max_size(); }
311 
312  // iterators.
313 
314  ///@{
315  /**
316  * Returns a read-only (constant) iterator that points to the first
317  * element in the %unordered_set.
318  */
319  iterator
320  begin() noexcept
321  { return _M_h.begin(); }
322 
324  begin() const noexcept
325  { return _M_h.begin(); }
326  ///@}
327 
328  ///@{
329  /**
330  * Returns a read-only (constant) iterator that points one past the last
331  * element in the %unordered_set.
332  */
333  iterator
334  end() noexcept
335  { return _M_h.end(); }
336 
338  end() const noexcept
339  { return _M_h.end(); }
340  ///@}
341 
342  /**
343  * Returns a read-only (constant) iterator that points to the first
344  * element in the %unordered_set.
345  */
347  cbegin() const noexcept
348  { return _M_h.begin(); }
349 
350  /**
351  * Returns a read-only (constant) iterator that points one past the last
352  * element in the %unordered_set.
353  */
355  cend() const noexcept
356  { return _M_h.end(); }
357 
358  // modifiers.
359 
360  /**
361  * @brief Attempts to build and insert an element into the
362  * %unordered_set.
363  * @param __args Arguments used to generate an element.
364  * @return A pair, of which the first element is an iterator that points
365  * to the possibly inserted element, and the second is a bool
366  * that is true if the element was actually inserted.
367  *
368  * This function attempts to build and insert an element into the
369  * %unordered_set. An %unordered_set relies on unique keys and thus an
370  * element is only inserted if it is not already present in the
371  * %unordered_set.
372  *
373  * Insertion requires amortized constant time.
374  */
375  template<typename... _Args>
377  emplace(_Args&&... __args)
378  { return _M_h.emplace(std::forward<_Args>(__args)...); }
379 
380  /**
381  * @brief Attempts to insert an element into the %unordered_set.
382  * @param __pos An iterator that serves as a hint as to where the
383  * element should be inserted.
384  * @param __args Arguments used to generate the element to be
385  * inserted.
386  * @return An iterator that points to the element with key equivalent to
387  * the one generated from @a __args (may or may not be the
388  * element itself).
389  *
390  * This function is not concerned about whether the insertion took place,
391  * and thus does not return a boolean like the single-argument emplace()
392  * does. Note that the first parameter is only a hint and can
393  * potentially improve the performance of the insertion process. A bad
394  * hint would cause no gains in efficiency.
395  *
396  * For more on @a hinting, see:
397  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
398  *
399  * Insertion requires amortized constant time.
400  */
401  template<typename... _Args>
402  iterator
403  emplace_hint(const_iterator __pos, _Args&&... __args)
404  { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
405 
406  ///@{
407  /**
408  * @brief Attempts to insert an element into the %unordered_set.
409  * @param __x Element to be inserted.
410  * @return A pair, of which the first element is an iterator that points
411  * to the possibly inserted element, and the second is a bool
412  * that is true if the element was actually inserted.
413  *
414  * This function attempts to insert an element into the %unordered_set.
415  * An %unordered_set relies on unique keys and thus an element is only
416  * inserted if it is not already present in the %unordered_set.
417  *
418  * Insertion requires amortized constant time.
419  */
421  insert(const value_type& __x)
422  { return _M_h.insert(__x); }
423 
426  { return _M_h.insert(std::move(__x)); }
427  ///@}
428 
429  ///@{
430  /**
431  * @brief Attempts to insert an element into the %unordered_set.
432  * @param __hint An iterator that serves as a hint as to where the
433  * element should be inserted.
434  * @param __x Element to be inserted.
435  * @return An iterator that points to the element with key of
436  * @a __x (may or may not be the element passed in).
437  *
438  * This function is not concerned about whether the insertion took place,
439  * and thus does not return a boolean like the single-argument insert()
440  * does. Note that the first parameter is only a hint and can
441  * potentially improve the performance of the insertion process. A bad
442  * hint would cause no gains in efficiency.
443  *
444  * For more on @a hinting, see:
445  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
446  *
447  * Insertion requires amortized constant.
448  */
449  iterator
450  insert(const_iterator __hint, const value_type& __x)
451  { return _M_h.insert(__hint, __x); }
452 
453  iterator
455  { return _M_h.insert(__hint, std::move(__x)); }
456  ///@}
457 
458  /**
459  * @brief A template function that attempts to insert a range of
460  * elements.
461  * @param __first Iterator pointing to the start of the range to be
462  * inserted.
463  * @param __last Iterator pointing to the end of the range.
464  *
465  * Complexity similar to that of the range constructor.
466  */
467  template<typename _InputIterator>
468  void
469  insert(_InputIterator __first, _InputIterator __last)
470  { _M_h.insert(__first, __last); }
471 
472  /**
473  * @brief Attempts to insert a list of elements into the %unordered_set.
474  * @param __l A std::initializer_list<value_type> of elements
475  * to be inserted.
476  *
477  * Complexity similar to that of the range constructor.
478  */
479  void
481  { _M_h.insert(__l); }
482 
483 #if __cplusplus > 201402L
484  /// Extract a node.
485  node_type
487  {
488  __glibcxx_assert(__pos != end());
489  return _M_h.extract(__pos);
490  }
491 
492  /// Extract a node.
493  node_type
494  extract(const key_type& __key)
495  { return _M_h.extract(__key); }
496 
497  /// Re-insert an extracted node.
498  insert_return_type
499  insert(node_type&& __nh)
500  { return _M_h._M_reinsert_node(std::move(__nh)); }
501 
502  /// Re-insert an extracted node.
503  iterator
504  insert(const_iterator, node_type&& __nh)
505  { return _M_h._M_reinsert_node(std::move(__nh)).position; }
506 #endif // C++17
507 
508  ///@{
509  /**
510  * @brief Erases an element from an %unordered_set.
511  * @param __position An iterator pointing to the element to be erased.
512  * @return An iterator pointing to the element immediately following
513  * @a __position prior to the element being erased. If no such
514  * element exists, end() is returned.
515  *
516  * This function erases an element, pointed to by the given iterator,
517  * from an %unordered_set. Note that this function only erases the
518  * element, and that if the element is itself a pointer, the pointed-to
519  * memory is not touched in any way. Managing the pointer is the user's
520  * responsibility.
521  */
522  iterator
523  erase(const_iterator __position)
524  { return _M_h.erase(__position); }
525 
526  // LWG 2059.
527  iterator
528  erase(iterator __position)
529  { return _M_h.erase(__position); }
530  ///@}
531 
532  /**
533  * @brief Erases elements according to the provided key.
534  * @param __x Key of element to be erased.
535  * @return The number of elements erased.
536  *
537  * This function erases all the elements located by the given key from
538  * an %unordered_set. For an %unordered_set the result of this function
539  * can only be 0 (not present) or 1 (present).
540  * Note that this function only erases the element, and that if
541  * the element is itself a pointer, the pointed-to memory is not touched
542  * in any way. Managing the pointer is the user's responsibility.
543  */
544  size_type
545  erase(const key_type& __x)
546  { return _M_h.erase(__x); }
547 
548  /**
549  * @brief Erases a [__first,__last) range of elements from an
550  * %unordered_set.
551  * @param __first Iterator pointing to the start of the range to be
552  * erased.
553  * @param __last Iterator pointing to the end of the range to
554  * be erased.
555  * @return The iterator @a __last.
556  *
557  * This function erases a sequence of elements from an %unordered_set.
558  * Note that this function only erases the element, and that if
559  * the element is itself a pointer, the pointed-to memory is not touched
560  * in any way. Managing the pointer is the user's responsibility.
561  */
562  iterator
564  { return _M_h.erase(__first, __last); }
565 
566  /**
567  * Erases all elements in an %unordered_set. Note that this function only
568  * erases the elements, and that if the elements themselves are pointers,
569  * the pointed-to memory is not touched in any way. Managing the pointer
570  * is the user's responsibility.
571  */
572  void
573  clear() noexcept
574  { _M_h.clear(); }
575 
576  /**
577  * @brief Swaps data with another %unordered_set.
578  * @param __x An %unordered_set of the same element and allocator
579  * types.
580  *
581  * This exchanges the elements between two sets in constant time.
582  * Note that the global std::swap() function is specialized such that
583  * std::swap(s1,s2) will feed to this function.
584  */
585  void
587  noexcept( noexcept(_M_h.swap(__x._M_h)) )
588  { _M_h.swap(__x._M_h); }
589 
590 #if __cplusplus > 201402L
591  template<typename, typename, typename>
592  friend class std::_Hash_merge_helper;
593 
594  template<typename _H2, typename _P2>
595  void
597  {
598  using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
599  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
600  }
601 
602  template<typename _H2, typename _P2>
603  void
604  merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
605  { merge(__source); }
606 
607  template<typename _H2, typename _P2>
608  void
609  merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
610  {
611  using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
612  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
613  }
614 
615  template<typename _H2, typename _P2>
616  void
617  merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
618  { merge(__source); }
619 #endif // C++17
620 
621  // observers.
622 
623  /// Returns the hash functor object with which the %unordered_set was
624  /// constructed.
625  hasher
627  { return _M_h.hash_function(); }
628 
629  /// Returns the key comparison object with which the %unordered_set was
630  /// constructed.
631  key_equal
632  key_eq() const
633  { return _M_h.key_eq(); }
634 
635  // lookup.
636 
637  ///@{
638  /**
639  * @brief Tries to locate an element in an %unordered_set.
640  * @param __x Element to be located.
641  * @return Iterator pointing to sought-after element, or end() if not
642  * found.
643  *
644  * This function takes a key and tries to locate the element with which
645  * the key matches. If successful the function returns an iterator
646  * pointing to the sought after element. If unsuccessful it returns the
647  * past-the-end ( @c end() ) iterator.
648  */
649  iterator
650  find(const key_type& __x)
651  { return _M_h.find(__x); }
652 
653 #if __cplusplus > 201703L
654  template<typename _Kt>
655  auto
656  find(const _Kt& __k)
657  -> decltype(_M_h._M_find_tr(__k))
658  { return _M_h._M_find_tr(__k); }
659 #endif
660 
662  find(const key_type& __x) const
663  { return _M_h.find(__x); }
664 
665 #if __cplusplus > 201703L
666  template<typename _Kt>
667  auto
668  find(const _Kt& __k) const
669  -> decltype(_M_h._M_find_tr(__k))
670  { return _M_h._M_find_tr(__k); }
671 #endif
672  ///@}
673 
674  ///@{
675  /**
676  * @brief Finds the number of elements.
677  * @param __x Element to located.
678  * @return Number of elements with specified key.
679  *
680  * This function only makes sense for unordered_multisets; for
681  * unordered_set the result will either be 0 (not present) or 1
682  * (present).
683  */
684  size_type
685  count(const key_type& __x) const
686  { return _M_h.count(__x); }
687 
688 #if __cplusplus > 201703L
689  template<typename _Kt>
690  auto
691  count(const _Kt& __k) const
692  -> decltype(_M_h._M_count_tr(__k))
693  { return _M_h._M_count_tr(__k); }
694 #endif
695  ///@}
696 
697 #if __cplusplus > 201703L
698  ///@{
699  /**
700  * @brief Finds whether an element with the given key exists.
701  * @param __x Key of elements to be located.
702  * @return True if there is any element with the specified key.
703  */
704  bool
705  contains(const key_type& __x) const
706  { return _M_h.find(__x) != _M_h.end(); }
707 
708  template<typename _Kt>
709  auto
710  contains(const _Kt& __k) const
711  -> decltype(_M_h._M_find_tr(__k), void(), true)
712  { return _M_h._M_find_tr(__k) != _M_h.end(); }
713  ///@}
714 #endif
715 
716  ///@{
717  /**
718  * @brief Finds a subsequence matching given key.
719  * @param __x Key to be located.
720  * @return Pair of iterators that possibly points to the subsequence
721  * matching given key.
722  *
723  * This function probably only makes sense for multisets.
724  */
726  equal_range(const key_type& __x)
727  { return _M_h.equal_range(__x); }
728 
729 #if __cplusplus > 201703L
730  template<typename _Kt>
731  auto
732  equal_range(const _Kt& __k)
733  -> decltype(_M_h._M_equal_range_tr(__k))
734  { return _M_h._M_equal_range_tr(__k); }
735 #endif
736 
738  equal_range(const key_type& __x) const
739  { return _M_h.equal_range(__x); }
740 
741 #if __cplusplus > 201703L
742  template<typename _Kt>
743  auto
744  equal_range(const _Kt& __k) const
745  -> decltype(_M_h._M_equal_range_tr(__k))
746  { return _M_h._M_equal_range_tr(__k); }
747 #endif
748  ///@}
749 
750  // bucket interface.
751 
752  /// Returns the number of buckets of the %unordered_set.
753  size_type
754  bucket_count() const noexcept
755  { return _M_h.bucket_count(); }
756 
757  /// Returns the maximum number of buckets of the %unordered_set.
758  size_type
759  max_bucket_count() const noexcept
760  { return _M_h.max_bucket_count(); }
761 
762  /*
763  * @brief Returns the number of elements in a given bucket.
764  * @param __n A bucket index.
765  * @return The number of elements in the bucket.
766  */
767  size_type
768  bucket_size(size_type __n) const
769  { return _M_h.bucket_size(__n); }
770 
771  /*
772  * @brief Returns the bucket index of a given element.
773  * @param __key A key instance.
774  * @return The key bucket index.
775  */
776  size_type
777  bucket(const key_type& __key) const
778  { return _M_h.bucket(__key); }
779 
780  ///@{
781  /**
782  * @brief Returns a read-only (constant) iterator pointing to the first
783  * bucket element.
784  * @param __n The bucket index.
785  * @return A read-only local iterator.
786  */
789  { return _M_h.begin(__n); }
790 
792  begin(size_type __n) const
793  { return _M_h.begin(__n); }
794 
796  cbegin(size_type __n) const
797  { return _M_h.cbegin(__n); }
798  ///@}
799 
800  ///@{
801  /**
802  * @brief Returns a read-only (constant) iterator pointing to one past
803  * the last bucket elements.
804  * @param __n The bucket index.
805  * @return A read-only local iterator.
806  */
809  { return _M_h.end(__n); }
810 
812  end(size_type __n) const
813  { return _M_h.end(__n); }
814 
816  cend(size_type __n) const
817  { return _M_h.cend(__n); }
818  ///@}
819 
820  // hash policy.
821 
822  /// Returns the average number of elements per bucket.
823  float
824  load_factor() const noexcept
825  { return _M_h.load_factor(); }
826 
827  /// Returns a positive number that the %unordered_set tries to keep the
828  /// load factor less than or equal to.
829  float
830  max_load_factor() const noexcept
831  { return _M_h.max_load_factor(); }
832 
833  /**
834  * @brief Change the %unordered_set maximum load factor.
835  * @param __z The new maximum load factor.
836  */
837  void
838  max_load_factor(float __z)
839  { _M_h.max_load_factor(__z); }
840 
841  /**
842  * @brief May rehash the %unordered_set.
843  * @param __n The new number of buckets.
844  *
845  * Rehash will occur only if the new number of buckets respect the
846  * %unordered_set maximum load factor.
847  */
848  void
850  { _M_h.rehash(__n); }
851 
852  /**
853  * @brief Prepare the %unordered_set for a specified number of
854  * elements.
855  * @param __n Number of elements required.
856  *
857  * Same as rehash(ceil(n / max_load_factor())).
858  */
859  void
861  { _M_h.reserve(__n); }
862 
863  template<typename _Value1, typename _Hash1, typename _Pred1,
864  typename _Alloc1>
865  friend bool
868  };
869 
870 #if __cpp_deduction_guides >= 201606
871 
872  template<typename _InputIterator,
873  typename _Hash =
874  hash<typename iterator_traits<_InputIterator>::value_type>,
875  typename _Pred =
876  equal_to<typename iterator_traits<_InputIterator>::value_type>,
877  typename _Allocator =
878  allocator<typename iterator_traits<_InputIterator>::value_type>,
879  typename = _RequireInputIter<_InputIterator>,
880  typename = _RequireNotAllocatorOrIntegral<_Hash>,
881  typename = _RequireNotAllocator<_Pred>,
882  typename = _RequireAllocator<_Allocator>>
883  unordered_set(_InputIterator, _InputIterator,
885  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
886  -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
887  _Hash, _Pred, _Allocator>;
888 
889  template<typename _Tp, typename _Hash = hash<_Tp>,
890  typename _Pred = equal_to<_Tp>,
891  typename _Allocator = allocator<_Tp>,
892  typename = _RequireNotAllocatorOrIntegral<_Hash>,
893  typename = _RequireNotAllocator<_Pred>,
894  typename = _RequireAllocator<_Allocator>>
895  unordered_set(initializer_list<_Tp>,
897  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
898  -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
899 
900  template<typename _InputIterator, typename _Allocator,
901  typename = _RequireInputIter<_InputIterator>,
902  typename = _RequireAllocator<_Allocator>>
903  unordered_set(_InputIterator, _InputIterator,
904  unordered_set<int>::size_type, _Allocator)
906  hash<
907  typename iterator_traits<_InputIterator>::value_type>,
908  equal_to<
909  typename iterator_traits<_InputIterator>::value_type>,
910  _Allocator>;
911 
912  template<typename _InputIterator, typename _Hash, typename _Allocator,
913  typename = _RequireInputIter<_InputIterator>,
914  typename = _RequireNotAllocatorOrIntegral<_Hash>,
915  typename = _RequireAllocator<_Allocator>>
916  unordered_set(_InputIterator, _InputIterator,
918  _Hash, _Allocator)
920  _Hash,
921  equal_to<
922  typename iterator_traits<_InputIterator>::value_type>,
923  _Allocator>;
924 
925  template<typename _Tp, typename _Allocator,
926  typename = _RequireAllocator<_Allocator>>
927  unordered_set(initializer_list<_Tp>,
928  unordered_set<int>::size_type, _Allocator)
929  -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
930 
931  template<typename _Tp, typename _Hash, typename _Allocator,
932  typename = _RequireNotAllocatorOrIntegral<_Hash>,
933  typename = _RequireAllocator<_Allocator>>
934  unordered_set(initializer_list<_Tp>,
935  unordered_set<int>::size_type, _Hash, _Allocator)
936  -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
937 
938 #endif
939 
940  /**
941  * @brief A standard container composed of equivalent keys
942  * (possibly containing multiple of each key value) in which the
943  * elements' keys are the elements themselves.
944  *
945  * @ingroup unordered_associative_containers
946  *
947  * @tparam _Value Type of key objects.
948  * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
949  * @tparam _Pred Predicate function object type, defaults
950  * to equal_to<_Value>.
951  * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
952  *
953  * Meets the requirements of a <a href="tables.html#65">container</a>, and
954  * <a href="tables.html#xx">unordered associative container</a>
955  *
956  * Base is _Hashtable, dispatched at compile time via template
957  * alias __umset_hashtable.
958  */
959  template<typename _Value,
960  typename _Hash = hash<_Value>,
961  typename _Pred = equal_to<_Value>,
962  typename _Alloc = allocator<_Value>>
964  {
965  typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
966  _Hashtable _M_h;
967 
968  public:
969  // typedefs:
970  ///@{
971  /// Public typedefs.
972  typedef typename _Hashtable::key_type key_type;
973  typedef typename _Hashtable::value_type value_type;
974  typedef typename _Hashtable::hasher hasher;
975  typedef typename _Hashtable::key_equal key_equal;
976  typedef typename _Hashtable::allocator_type allocator_type;
977  ///@}
978 
979  ///@{
980  /// Iterator-related typedefs.
981  typedef typename _Hashtable::pointer pointer;
982  typedef typename _Hashtable::const_pointer const_pointer;
983  typedef typename _Hashtable::reference reference;
984  typedef typename _Hashtable::const_reference const_reference;
985  typedef typename _Hashtable::iterator iterator;
986  typedef typename _Hashtable::const_iterator const_iterator;
987  typedef typename _Hashtable::local_iterator local_iterator;
988  typedef typename _Hashtable::const_local_iterator const_local_iterator;
989  typedef typename _Hashtable::size_type size_type;
990  typedef typename _Hashtable::difference_type difference_type;
991  ///@}
992 
993 #if __cplusplus > 201402L
994  using node_type = typename _Hashtable::node_type;
995 #endif
996 
997  // construct/destroy/copy
998 
999  /// Default constructor.
1000  unordered_multiset() = default;
1001 
1002  /**
1003  * @brief Default constructor creates no elements.
1004  * @param __n Minimal initial number of buckets.
1005  * @param __hf A hash functor.
1006  * @param __eql A key equality functor.
1007  * @param __a An allocator object.
1008  */
1009  explicit
1011  const hasher& __hf = hasher(),
1012  const key_equal& __eql = key_equal(),
1013  const allocator_type& __a = allocator_type())
1014  : _M_h(__n, __hf, __eql, __a)
1015  { }
1016 
1017  /**
1018  * @brief Builds an %unordered_multiset from a range.
1019  * @param __first An input iterator.
1020  * @param __last An input iterator.
1021  * @param __n Minimal initial number of buckets.
1022  * @param __hf A hash functor.
1023  * @param __eql A key equality functor.
1024  * @param __a An allocator object.
1025  *
1026  * Create an %unordered_multiset consisting of copies of the elements
1027  * from [__first,__last). This is linear in N (where N is
1028  * distance(__first,__last)).
1029  */
1030  template<typename _InputIterator>
1031  unordered_multiset(_InputIterator __first, _InputIterator __last,
1032  size_type __n = 0,
1033  const hasher& __hf = hasher(),
1034  const key_equal& __eql = key_equal(),
1035  const allocator_type& __a = allocator_type())
1036  : _M_h(__first, __last, __n, __hf, __eql, __a)
1037  { }
1038 
1039  /// Copy constructor.
1041 
1042  /// Move constructor.
1044 
1045  /**
1046  * @brief Builds an %unordered_multiset from an initializer_list.
1047  * @param __l An initializer_list.
1048  * @param __n Minimal initial number of buckets.
1049  * @param __hf A hash functor.
1050  * @param __eql A key equality functor.
1051  * @param __a An allocator object.
1052  *
1053  * Create an %unordered_multiset consisting of copies of the elements in
1054  * the list. This is linear in N (where N is @a __l.size()).
1055  */
1057  size_type __n = 0,
1058  const hasher& __hf = hasher(),
1059  const key_equal& __eql = key_equal(),
1060  const allocator_type& __a = allocator_type())
1061  : _M_h(__l, __n, __hf, __eql, __a)
1062  { }
1063 
1064  /// Copy assignment operator.
1066  operator=(const unordered_multiset&) = default;
1067 
1068  /// Move assignment operator.
1071 
1072  /**
1073  * @brief Creates an %unordered_multiset with no elements.
1074  * @param __a An allocator object.
1075  */
1076  explicit
1078  : _M_h(__a)
1079  { }
1080 
1081  /*
1082  * @brief Copy constructor with allocator argument.
1083  * @param __uset Input %unordered_multiset to copy.
1084  * @param __a An allocator object.
1085  */
1086  unordered_multiset(const unordered_multiset& __umset,
1087  const allocator_type& __a)
1088  : _M_h(__umset._M_h, __a)
1089  { }
1090 
1091  /*
1092  * @brief Move constructor with allocator argument.
1093  * @param __umset Input %unordered_multiset to move.
1094  * @param __a An allocator object.
1095  */
1097  const allocator_type& __a)
1098  noexcept( noexcept(_Hashtable(std::move(__umset._M_h), __a)) )
1099  : _M_h(std::move(__umset._M_h), __a)
1100  { }
1101 
1103  : unordered_multiset(__n, hasher(), key_equal(), __a)
1104  { }
1105 
1106  unordered_multiset(size_type __n, const hasher& __hf,
1107  const allocator_type& __a)
1108  : unordered_multiset(__n, __hf, key_equal(), __a)
1109  { }
1110 
1111  template<typename _InputIterator>
1112  unordered_multiset(_InputIterator __first, _InputIterator __last,
1113  size_type __n,
1114  const allocator_type& __a)
1115  : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
1116  { }
1117 
1118  template<typename _InputIterator>
1119  unordered_multiset(_InputIterator __first, _InputIterator __last,
1120  size_type __n, const hasher& __hf,
1121  const allocator_type& __a)
1122  : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
1123  { }
1124 
1125  unordered_multiset(initializer_list<value_type> __l,
1126  size_type __n,
1127  const allocator_type& __a)
1128  : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
1129  { }
1130 
1131  unordered_multiset(initializer_list<value_type> __l,
1132  size_type __n, const hasher& __hf,
1133  const allocator_type& __a)
1134  : unordered_multiset(__l, __n, __hf, key_equal(), __a)
1135  { }
1136 
1137  /**
1138  * @brief %Unordered_multiset list assignment operator.
1139  * @param __l An initializer_list.
1140  *
1141  * This function fills an %unordered_multiset with copies of the elements
1142  * in the initializer list @a __l.
1143  *
1144  * Note that the assignment completely changes the %unordered_multiset
1145  * and that the resulting %unordered_multiset's size is the same as the
1146  * number of elements assigned.
1147  */
1150  {
1151  _M_h = __l;
1152  return *this;
1153  }
1154 
1155  /// Returns the allocator object used by the %unordered_multiset.
1157  get_allocator() const noexcept
1158  { return _M_h.get_allocator(); }
1159 
1160  // size and capacity:
1161 
1162  /// Returns true if the %unordered_multiset is empty.
1163  _GLIBCXX_NODISCARD bool
1164  empty() const noexcept
1165  { return _M_h.empty(); }
1166 
1167  /// Returns the size of the %unordered_multiset.
1168  size_type
1169  size() const noexcept
1170  { return _M_h.size(); }
1171 
1172  /// Returns the maximum size of the %unordered_multiset.
1173  size_type
1174  max_size() const noexcept
1175  { return _M_h.max_size(); }
1176 
1177  // iterators.
1178 
1179  ///@{
1180  /**
1181  * Returns a read-only (constant) iterator that points to the first
1182  * element in the %unordered_multiset.
1183  */
1184  iterator
1185  begin() noexcept
1186  { return _M_h.begin(); }
1187 
1189  begin() const noexcept
1190  { return _M_h.begin(); }
1191  ///@}
1192 
1193  ///@{
1194  /**
1195  * Returns a read-only (constant) iterator that points one past the last
1196  * element in the %unordered_multiset.
1197  */
1198  iterator
1199  end() noexcept
1200  { return _M_h.end(); }
1201 
1203  end() const noexcept
1204  { return _M_h.end(); }
1205  ///@}
1206 
1207  /**
1208  * Returns a read-only (constant) iterator that points to the first
1209  * element in the %unordered_multiset.
1210  */
1212  cbegin() const noexcept
1213  { return _M_h.begin(); }
1214 
1215  /**
1216  * Returns a read-only (constant) iterator that points one past the last
1217  * element in the %unordered_multiset.
1218  */
1220  cend() const noexcept
1221  { return _M_h.end(); }
1222 
1223  // modifiers.
1224 
1225  /**
1226  * @brief Builds and insert an element into the %unordered_multiset.
1227  * @param __args Arguments used to generate an element.
1228  * @return An iterator that points to the inserted element.
1229  *
1230  * Insertion requires amortized constant time.
1231  */
1232  template<typename... _Args>
1233  iterator
1234  emplace(_Args&&... __args)
1235  { return _M_h.emplace(std::forward<_Args>(__args)...); }
1236 
1237  /**
1238  * @brief Inserts an element into the %unordered_multiset.
1239  * @param __pos An iterator that serves as a hint as to where the
1240  * element should be inserted.
1241  * @param __args Arguments used to generate the element to be
1242  * inserted.
1243  * @return An iterator that points to the inserted element.
1244  *
1245  * Note that the first parameter is only a hint and can potentially
1246  * improve the performance of the insertion process. A bad hint would
1247  * cause no gains in efficiency.
1248  *
1249  * For more on @a hinting, see:
1250  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1251  *
1252  * Insertion requires amortized constant time.
1253  */
1254  template<typename... _Args>
1255  iterator
1256  emplace_hint(const_iterator __pos, _Args&&... __args)
1257  { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
1258 
1259  ///@{
1260  /**
1261  * @brief Inserts an element into the %unordered_multiset.
1262  * @param __x Element to be inserted.
1263  * @return An iterator that points to the inserted element.
1264  *
1265  * Insertion requires amortized constant time.
1266  */
1267  iterator
1268  insert(const value_type& __x)
1269  { return _M_h.insert(__x); }
1270 
1271  iterator
1273  { return _M_h.insert(std::move(__x)); }
1274  ///@}
1275 
1276  ///@{
1277  /**
1278  * @brief Inserts an element into the %unordered_multiset.
1279  * @param __hint An iterator that serves as a hint as to where the
1280  * element should be inserted.
1281  * @param __x Element to be inserted.
1282  * @return An iterator that points to the inserted element.
1283  *
1284  * Note that the first parameter is only a hint and can potentially
1285  * improve the performance of the insertion process. A bad hint would
1286  * cause no gains in efficiency.
1287  *
1288  * For more on @a hinting, see:
1289  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1290  *
1291  * Insertion requires amortized constant.
1292  */
1293  iterator
1294  insert(const_iterator __hint, const value_type& __x)
1295  { return _M_h.insert(__hint, __x); }
1296 
1297  iterator
1299  { return _M_h.insert(__hint, std::move(__x)); }
1300  ///@}
1301 
1302  /**
1303  * @brief A template function that inserts a range of elements.
1304  * @param __first Iterator pointing to the start of the range to be
1305  * inserted.
1306  * @param __last Iterator pointing to the end of the range.
1307  *
1308  * Complexity similar to that of the range constructor.
1309  */
1310  template<typename _InputIterator>
1311  void
1312  insert(_InputIterator __first, _InputIterator __last)
1313  { _M_h.insert(__first, __last); }
1314 
1315  /**
1316  * @brief Inserts a list of elements into the %unordered_multiset.
1317  * @param __l A std::initializer_list<value_type> of elements to be
1318  * inserted.
1319  *
1320  * Complexity similar to that of the range constructor.
1321  */
1322  void
1324  { _M_h.insert(__l); }
1325 
1326 #if __cplusplus > 201402L
1327  /// Extract a node.
1328  node_type
1330  {
1331  __glibcxx_assert(__pos != end());
1332  return _M_h.extract(__pos);
1333  }
1334 
1335  /// Extract a node.
1336  node_type
1337  extract(const key_type& __key)
1338  { return _M_h.extract(__key); }
1339 
1340  /// Re-insert an extracted node.
1341  iterator
1342  insert(node_type&& __nh)
1343  { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
1344 
1345  /// Re-insert an extracted node.
1346  iterator
1347  insert(const_iterator __hint, node_type&& __nh)
1348  { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
1349 #endif // C++17
1350 
1351  ///@{
1352  /**
1353  * @brief Erases an element from an %unordered_multiset.
1354  * @param __position An iterator pointing to the element to be erased.
1355  * @return An iterator pointing to the element immediately following
1356  * @a __position prior to the element being erased. If no such
1357  * element exists, end() is returned.
1358  *
1359  * This function erases an element, pointed to by the given iterator,
1360  * from an %unordered_multiset.
1361  *
1362  * Note that this function only erases the element, and that if the
1363  * element is itself a pointer, the pointed-to memory is not touched in
1364  * any way. Managing the pointer is the user's responsibility.
1365  */
1366  iterator
1367  erase(const_iterator __position)
1368  { return _M_h.erase(__position); }
1369 
1370  // LWG 2059.
1371  iterator
1372  erase(iterator __position)
1373  { return _M_h.erase(__position); }
1374  ///@}
1375 
1376 
1377  /**
1378  * @brief Erases elements according to the provided key.
1379  * @param __x Key of element to be erased.
1380  * @return The number of elements erased.
1381  *
1382  * This function erases all the elements located by the given key from
1383  * an %unordered_multiset.
1384  *
1385  * Note that this function only erases the element, and that if the
1386  * element is itself a pointer, the pointed-to memory is not touched in
1387  * any way. Managing the pointer is the user's responsibility.
1388  */
1389  size_type
1390  erase(const key_type& __x)
1391  { return _M_h.erase(__x); }
1392 
1393  /**
1394  * @brief Erases a [__first,__last) range of elements from an
1395  * %unordered_multiset.
1396  * @param __first Iterator pointing to the start of the range to be
1397  * erased.
1398  * @param __last Iterator pointing to the end of the range to
1399  * be erased.
1400  * @return The iterator @a __last.
1401  *
1402  * This function erases a sequence of elements from an
1403  * %unordered_multiset.
1404  *
1405  * Note that this function only erases the element, and that if
1406  * the element is itself a pointer, the pointed-to memory is not touched
1407  * in any way. Managing the pointer is the user's responsibility.
1408  */
1409  iterator
1411  { return _M_h.erase(__first, __last); }
1412 
1413  /**
1414  * Erases all elements in an %unordered_multiset.
1415  *
1416  * Note that this function only erases the elements, and that if the
1417  * elements themselves are pointers, the pointed-to memory is not touched
1418  * in any way. Managing the pointer is the user's responsibility.
1419  */
1420  void
1421  clear() noexcept
1422  { _M_h.clear(); }
1423 
1424  /**
1425  * @brief Swaps data with another %unordered_multiset.
1426  * @param __x An %unordered_multiset of the same element and allocator
1427  * types.
1428  *
1429  * This exchanges the elements between two sets in constant time.
1430  * Note that the global std::swap() function is specialized such that
1431  * std::swap(s1,s2) will feed to this function.
1432  */
1433  void
1435  noexcept( noexcept(_M_h.swap(__x._M_h)) )
1436  { _M_h.swap(__x._M_h); }
1437 
1438 #if __cplusplus > 201402L
1439  template<typename, typename, typename>
1440  friend class std::_Hash_merge_helper;
1441 
1442  template<typename _H2, typename _P2>
1443  void
1445  {
1446  using _Merge_helper
1447  = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1448  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1449  }
1450 
1451  template<typename _H2, typename _P2>
1452  void
1453  merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
1454  { merge(__source); }
1455 
1456  template<typename _H2, typename _P2>
1457  void
1458  merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
1459  {
1460  using _Merge_helper
1461  = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1462  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1463  }
1464 
1465  template<typename _H2, typename _P2>
1466  void
1467  merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
1468  { merge(__source); }
1469 #endif // C++17
1470 
1471  // observers.
1472 
1473  /// Returns the hash functor object with which the %unordered_multiset
1474  /// was constructed.
1475  hasher
1477  { return _M_h.hash_function(); }
1478 
1479  /// Returns the key comparison object with which the %unordered_multiset
1480  /// was constructed.
1481  key_equal
1482  key_eq() const
1483  { return _M_h.key_eq(); }
1484 
1485  // lookup.
1486 
1487  ///@{
1488  /**
1489  * @brief Tries to locate an element in an %unordered_multiset.
1490  * @param __x Element to be located.
1491  * @return Iterator pointing to sought-after element, or end() if not
1492  * found.
1493  *
1494  * This function takes a key and tries to locate the element with which
1495  * the key matches. If successful the function returns an iterator
1496  * pointing to the sought after element. If unsuccessful it returns the
1497  * past-the-end ( @c end() ) iterator.
1498  */
1499  iterator
1500  find(const key_type& __x)
1501  { return _M_h.find(__x); }
1502 
1503 #if __cplusplus > 201703L
1504  template<typename _Kt>
1505  auto
1506  find(const _Kt& __x)
1507  -> decltype(_M_h._M_find_tr(__x))
1508  { return _M_h._M_find_tr(__x); }
1509 #endif
1510 
1512  find(const key_type& __x) const
1513  { return _M_h.find(__x); }
1514 
1515 #if __cplusplus > 201703L
1516  template<typename _Kt>
1517  auto
1518  find(const _Kt& __x) const
1519  -> decltype(_M_h._M_find_tr(__x))
1520  { return _M_h._M_find_tr(__x); }
1521 #endif
1522  ///@}
1523 
1524  ///@{
1525  /**
1526  * @brief Finds the number of elements.
1527  * @param __x Element to located.
1528  * @return Number of elements with specified key.
1529  */
1530  size_type
1531  count(const key_type& __x) const
1532  { return _M_h.count(__x); }
1533 
1534 #if __cplusplus > 201703L
1535  template<typename _Kt>
1536  auto
1537  count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
1538  { return _M_h._M_count_tr(__x); }
1539 #endif
1540  ///@}
1541 
1542 #if __cplusplus > 201703L
1543  ///@{
1544  /**
1545  * @brief Finds whether an element with the given key exists.
1546  * @param __x Key of elements to be located.
1547  * @return True if there is any element with the specified key.
1548  */
1549  bool
1550  contains(const key_type& __x) const
1551  { return _M_h.find(__x) != _M_h.end(); }
1552 
1553  template<typename _Kt>
1554  auto
1555  contains(const _Kt& __x) const
1556  -> decltype(_M_h._M_find_tr(__x), void(), true)
1557  { return _M_h._M_find_tr(__x) != _M_h.end(); }
1558  ///@}
1559 #endif
1560 
1561  ///@{
1562  /**
1563  * @brief Finds a subsequence matching given key.
1564  * @param __x Key to be located.
1565  * @return Pair of iterators that possibly points to the subsequence
1566  * matching given key.
1567  */
1569  equal_range(const key_type& __x)
1570  { return _M_h.equal_range(__x); }
1571 
1572 #if __cplusplus > 201703L
1573  template<typename _Kt>
1574  auto
1575  equal_range(const _Kt& __x)
1576  -> decltype(_M_h._M_equal_range_tr(__x))
1577  { return _M_h._M_equal_range_tr(__x); }
1578 #endif
1579 
1581  equal_range(const key_type& __x) const
1582  { return _M_h.equal_range(__x); }
1583 
1584 #if __cplusplus > 201703L
1585  template<typename _Kt>
1586  auto
1587  equal_range(const _Kt& __x) const
1588  -> decltype(_M_h._M_equal_range_tr(__x))
1589  { return _M_h._M_equal_range_tr(__x); }
1590 #endif
1591  ///@}
1592 
1593  // bucket interface.
1594 
1595  /// Returns the number of buckets of the %unordered_multiset.
1596  size_type
1597  bucket_count() const noexcept
1598  { return _M_h.bucket_count(); }
1599 
1600  /// Returns the maximum number of buckets of the %unordered_multiset.
1601  size_type
1602  max_bucket_count() const noexcept
1603  { return _M_h.max_bucket_count(); }
1604 
1605  /*
1606  * @brief Returns the number of elements in a given bucket.
1607  * @param __n A bucket index.
1608  * @return The number of elements in the bucket.
1609  */
1610  size_type
1611  bucket_size(size_type __n) const
1612  { return _M_h.bucket_size(__n); }
1613 
1614  /*
1615  * @brief Returns the bucket index of a given element.
1616  * @param __key A key instance.
1617  * @return The key bucket index.
1618  */
1619  size_type
1620  bucket(const key_type& __key) const
1621  { return _M_h.bucket(__key); }
1622 
1623  ///@{
1624  /**
1625  * @brief Returns a read-only (constant) iterator pointing to the first
1626  * bucket element.
1627  * @param __n The bucket index.
1628  * @return A read-only local iterator.
1629  */
1632  { return _M_h.begin(__n); }
1633 
1635  begin(size_type __n) const
1636  { return _M_h.begin(__n); }
1637 
1639  cbegin(size_type __n) const
1640  { return _M_h.cbegin(__n); }
1641  ///@}
1642 
1643  ///@{
1644  /**
1645  * @brief Returns a read-only (constant) iterator pointing to one past
1646  * the last bucket elements.
1647  * @param __n The bucket index.
1648  * @return A read-only local iterator.
1649  */
1652  { return _M_h.end(__n); }
1653 
1655  end(size_type __n) const
1656  { return _M_h.end(__n); }
1657 
1659  cend(size_type __n) const
1660  { return _M_h.cend(__n); }
1661  ///@}
1662 
1663  // hash policy.
1664 
1665  /// Returns the average number of elements per bucket.
1666  float
1667  load_factor() const noexcept
1668  { return _M_h.load_factor(); }
1669 
1670  /// Returns a positive number that the %unordered_multiset tries to keep the
1671  /// load factor less than or equal to.
1672  float
1673  max_load_factor() const noexcept
1674  { return _M_h.max_load_factor(); }
1675 
1676  /**
1677  * @brief Change the %unordered_multiset maximum load factor.
1678  * @param __z The new maximum load factor.
1679  */
1680  void
1681  max_load_factor(float __z)
1682  { _M_h.max_load_factor(__z); }
1683 
1684  /**
1685  * @brief May rehash the %unordered_multiset.
1686  * @param __n The new number of buckets.
1687  *
1688  * Rehash will occur only if the new number of buckets respect the
1689  * %unordered_multiset maximum load factor.
1690  */
1691  void
1693  { _M_h.rehash(__n); }
1694 
1695  /**
1696  * @brief Prepare the %unordered_multiset for a specified number of
1697  * elements.
1698  * @param __n Number of elements required.
1699  *
1700  * Same as rehash(ceil(n / max_load_factor())).
1701  */
1702  void
1704  { _M_h.reserve(__n); }
1705 
1706  template<typename _Value1, typename _Hash1, typename _Pred1,
1707  typename _Alloc1>
1708  friend bool
1711  };
1712 
1713 
1714 #if __cpp_deduction_guides >= 201606
1715 
1716  template<typename _InputIterator,
1717  typename _Hash =
1718  hash<typename iterator_traits<_InputIterator>::value_type>,
1719  typename _Pred =
1720  equal_to<typename iterator_traits<_InputIterator>::value_type>,
1721  typename _Allocator =
1722  allocator<typename iterator_traits<_InputIterator>::value_type>,
1723  typename = _RequireInputIter<_InputIterator>,
1724  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1725  typename = _RequireNotAllocator<_Pred>,
1726  typename = _RequireAllocator<_Allocator>>
1727  unordered_multiset(_InputIterator, _InputIterator,
1729  _Hash = _Hash(), _Pred = _Pred(),
1730  _Allocator = _Allocator())
1731  -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1732  _Hash, _Pred, _Allocator>;
1733 
1734  template<typename _Tp, typename _Hash = hash<_Tp>,
1735  typename _Pred = equal_to<_Tp>,
1736  typename _Allocator = allocator<_Tp>,
1737  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1738  typename = _RequireNotAllocator<_Pred>,
1739  typename = _RequireAllocator<_Allocator>>
1740  unordered_multiset(initializer_list<_Tp>,
1742  _Hash = _Hash(), _Pred = _Pred(),
1743  _Allocator = _Allocator())
1744  -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1745 
1746  template<typename _InputIterator, typename _Allocator,
1747  typename = _RequireInputIter<_InputIterator>,
1748  typename = _RequireAllocator<_Allocator>>
1749  unordered_multiset(_InputIterator, _InputIterator,
1752  hash<typename
1753  iterator_traits<_InputIterator>::value_type>,
1754  equal_to<typename
1755  iterator_traits<_InputIterator>::value_type>,
1756  _Allocator>;
1757 
1758  template<typename _InputIterator, typename _Hash, typename _Allocator,
1759  typename = _RequireInputIter<_InputIterator>,
1760  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1761  typename = _RequireAllocator<_Allocator>>
1762  unordered_multiset(_InputIterator, _InputIterator,
1764  _Hash, _Allocator)
1765  -> unordered_multiset<typename
1766  iterator_traits<_InputIterator>::value_type,
1767  _Hash,
1768  equal_to<
1769  typename
1770  iterator_traits<_InputIterator>::value_type>,
1771  _Allocator>;
1772 
1773  template<typename _Tp, typename _Allocator,
1774  typename = _RequireAllocator<_Allocator>>
1775  unordered_multiset(initializer_list<_Tp>,
1777  -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1778 
1779  template<typename _Tp, typename _Hash, typename _Allocator,
1780  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1781  typename = _RequireAllocator<_Allocator>>
1782  unordered_multiset(initializer_list<_Tp>,
1783  unordered_multiset<int>::size_type, _Hash, _Allocator)
1784  -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1785 
1786 #endif
1787 
1788  template<class _Value, class _Hash, class _Pred, class _Alloc>
1789  inline void
1790  swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1791  unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1792  noexcept(noexcept(__x.swap(__y)))
1793  { __x.swap(__y); }
1794 
1795  template<class _Value, class _Hash, class _Pred, class _Alloc>
1796  inline void
1797  swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1798  unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1799  noexcept(noexcept(__x.swap(__y)))
1800  { __x.swap(__y); }
1801 
1802  template<class _Value, class _Hash, class _Pred, class _Alloc>
1803  inline bool
1804  operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1805  const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1806  { return __x._M_h._M_equal(__y._M_h); }
1807 
1808 #if __cpp_impl_three_way_comparison < 201907L
1809  template<class _Value, class _Hash, class _Pred, class _Alloc>
1810  inline bool
1811  operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1812  const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1813  { return !(__x == __y); }
1814 #endif
1815 
1816  template<class _Value, class _Hash, class _Pred, class _Alloc>
1817  inline bool
1818  operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1819  const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1820  { return __x._M_h._M_equal(__y._M_h); }
1821 
1822 #if __cpp_impl_three_way_comparison < 201907L
1823  template<class _Value, class _Hash, class _Pred, class _Alloc>
1824  inline bool
1825  operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1826  const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1827  { return !(__x == __y); }
1828 #endif
1829 
1830 _GLIBCXX_END_NAMESPACE_CONTAINER
1831 
1832 #if __cplusplus > 201402L
1833  // Allow std::unordered_set access to internals of compatible sets.
1834  template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
1835  typename _Hash2, typename _Eq2>
1836  struct _Hash_merge_helper<
1837  _GLIBCXX_STD_C::unordered_set<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2>
1838  {
1839  private:
1840  template<typename... _Tp>
1841  using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
1842  template<typename... _Tp>
1843  using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
1844 
1845  friend unordered_set<_Val, _Hash1, _Eq1, _Alloc>;
1846 
1847  static auto&
1848  _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
1849  { return __set._M_h; }
1850 
1851  static auto&
1852  _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
1853  { return __set._M_h; }
1854  };
1855 
1856  // Allow std::unordered_multiset access to internals of compatible sets.
1857  template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
1858  typename _Hash2, typename _Eq2>
1859  struct _Hash_merge_helper<
1860  _GLIBCXX_STD_C::unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>,
1861  _Hash2, _Eq2>
1862  {
1863  private:
1864  template<typename... _Tp>
1865  using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
1866  template<typename... _Tp>
1867  using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
1868 
1869  friend unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>;
1870 
1871  static auto&
1872  _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
1873  { return __set._M_h; }
1874 
1875  static auto&
1876  _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
1877  { return __set._M_h; }
1878  };
1879 #endif // C++17
1880 
1881 _GLIBCXX_END_NAMESPACE_VERSION
1882 } // namespace std
1883 
1884 #endif /* _UNORDERED_SET_H */
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:104
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:429
ISO C++ entities toplevel namespace is std.
__detail::_Hashtable_traits< _Cache, true, true > __uset_traits
Base types for unordered_set.
Definition: unordered_set.h:40
__detail::_Hashtable_traits< _Cache, true, false > __umset_traits
Base types for unordered_multiset.
Definition: unordered_set.h:55
initializer_list
Primary class template hash.
The standard allocator, as per C++03 [20.4.1].
Definition: allocator.h:125
One of the comparison functors.
Definition: stl_function.h:374
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:187
Common iterator class.
A standard container composed of equivalent keys (possibly containing multiple of each key value) in ...
auto find(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x))
Tries to locate an element in an unordered_multiset.
iterator begin() noexcept
auto find(const _Kt &__x) -> decltype(_M_h._M_find_tr(__x))
Tries to locate an element in an unordered_multiset.
iterator insert(const_iterator __hint, const value_type &__x)
Inserts an element into the unordered_multiset.
_Hashtable::difference_type difference_type
Iterator-related typedefs.
void insert(initializer_list< value_type > __l)
Inserts a list of elements into the unordered_multiset.
_Hashtable::pointer pointer
Iterator-related typedefs.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
void rehash(size_type __n)
May rehash the unordered_multiset.
local_iterator begin(size_type __n)
Returns a read-only (constant) iterator pointing to the first bucket element.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_multiset.
float max_load_factor() const noexcept
Returns a positive number that the unordered_multiset tries to keep the load factor less than or equa...
bool empty() const noexcept
Returns true if the unordered_multiset is empty.
const_iterator cend() const noexcept
_Hashtable::local_iterator local_iterator
Iterator-related typedefs.
node_type extract(const key_type &__key)
Extract a node.
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
iterator emplace(_Args &&... __args)
Builds and insert an element into the unordered_multiset.
unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_multiset from a range.
_Hashtable::const_iterator const_iterator
Iterator-related typedefs.
unordered_multiset(const allocator_type &__a)
Creates an unordered_multiset with no elements.
_Hashtable::allocator_type allocator_type
Public typedefs.
const_local_iterator end(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
iterator find(const key_type &__x)
Tries to locate an element in an unordered_multiset.
_Hashtable::value_type value_type
Public typedefs.
float load_factor() const noexcept
Returns the average number of elements per bucket.
unordered_multiset()=default
Default constructor.
iterator insert(const_iterator __hint, node_type &&__nh)
Re-insert an extracted node.
_Hashtable::size_type size_type
Iterator-related typedefs.
auto equal_range(const _Kt &__x) -> decltype(_M_h._M_equal_range_tr(__x))
Finds a subsequence matching given key.
_Hashtable::key_type key_type
Public typedefs.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
hasher hash_function() const
Returns the hash functor object with which the unordered_multiset was constructed.
unordered_multiset(initializer_list< value_type > __l, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_multiset from an initializer_list.
auto contains(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x), void(), true)
Finds whether an element with the given key exists.
auto count(const _Kt &__x) const -> decltype(_M_h._M_count_tr(__x))
Finds the number of elements.
size_type count(const key_type &__x) const
Finds the number of elements.
iterator erase(const_iterator __position)
Erases an element from an unordered_multiset.
unordered_multiset(unordered_multiset &&)=default
Move constructor.
_Hashtable::reference reference
Iterator-related typedefs.
iterator end() noexcept
iterator emplace_hint(const_iterator __pos, _Args &&... __args)
Inserts an element into the unordered_multiset.
void swap(unordered_multiset &__x) noexcept(noexcept(_M_h.swap(__x._M_h)))
Swaps data with another unordered_multiset.
const_iterator begin() const noexcept
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_multiset.
const_iterator cbegin() const noexcept
void insert(_InputIterator __first, _InputIterator __last)
A template function that inserts a range of elements.
key_equal key_eq() const
Returns the key comparison object with which the unordered_multiset was constructed.
unordered_multiset & operator=(const unordered_multiset &)=default
Copy assignment operator.
_Hashtable::const_pointer const_pointer
Iterator-related typedefs.
iterator insert(value_type &&__x)
Inserts an element into the unordered_multiset.
iterator insert(const value_type &__x)
Inserts an element into the unordered_multiset.
const_iterator end() const noexcept
void reserve(size_type __n)
Prepare the unordered_multiset for a specified number of elements.
iterator insert(const_iterator __hint, value_type &&__x)
Inserts an element into the unordered_multiset.
_Hashtable::const_reference const_reference
Iterator-related typedefs.
iterator erase(iterator __position)
Erases an element from an unordered_multiset.
const_local_iterator cend(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
unordered_multiset & operator=(unordered_multiset &&)=default
Move assignment operator.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_multiset.
iterator insert(node_type &&__nh)
Re-insert an extracted node.
_Hashtable::hasher hasher
Public typedefs.
unordered_multiset(size_type __n, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Default constructor creates no elements.
size_type size() const noexcept
Returns the size of the unordered_multiset.
_Hashtable::iterator iterator
Iterator-related typedefs.
local_iterator end(size_type __n)
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
unordered_multiset & operator=(initializer_list< value_type > __l)
Unordered_multiset list assignment operator.
auto equal_range(const _Kt &__x) const -> decltype(_M_h._M_equal_range_tr(__x))
Finds a subsequence matching given key.
node_type extract(const_iterator __pos)
Extract a node.
size_type max_size() const noexcept
Returns the maximum size of the unordered_multiset.
const_local_iterator cbegin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_multiset(const unordered_multiset &)=default
Copy constructor.
_Hashtable::const_local_iterator const_local_iterator
Iterator-related typedefs.
size_type erase(const key_type &__x)
Erases elements according to the provided key.
const_iterator find(const key_type &__x) const
Tries to locate an element in an unordered_multiset.
allocator_type get_allocator() const noexcept
Returns the allocator object used by the unordered_multiset.
_Hashtable::key_equal key_equal
Public typedefs.
void max_load_factor(float __z)
Change the unordered_multiset maximum load factor.
A standard container composed of unique keys (containing at most one of each key value) in which the ...
Definition: unordered_set.h:98
_Hashtable::iterator iterator
Iterator-related typedefs.
unordered_set(initializer_list< value_type > __l, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_set from an initializer_list.
void max_load_factor(float __z)
Change the unordered_set maximum load factor.
_Hashtable::reference reference
Iterator-related typedefs.
const_local_iterator end(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
_Hashtable::value_type value_type
Public typedefs.
const_iterator cend() const noexcept
auto find(const _Kt &__k) -> decltype(_M_h._M_find_tr(__k))
Tries to locate an element in an unordered_set.
const_iterator find(const key_type &__x) const
Tries to locate an element in an unordered_set.
_Hashtable::key_type key_type
Public typedefs.
size_type count(const key_type &__x) const
Finds the number of elements.
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_set & operator=(const unordered_set &)=default
Copy assignment operator.
auto equal_range(const _Kt &__k) -> decltype(_M_h._M_equal_range_tr(__k))
Finds a subsequence matching given key.
const_local_iterator cbegin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_set & operator=(initializer_list< value_type > __l)
Unordered_set list assignment operator.
auto count(const _Kt &__k) const -> decltype(_M_h._M_count_tr(__k))
Finds the number of elements.
const_iterator begin() const noexcept
_Hashtable::hasher hasher
Public typedefs.
_Hashtable::local_iterator local_iterator
Iterator-related typedefs.
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
_Hashtable::size_type size_type
Iterator-related typedefs.
const_iterator cbegin() const noexcept
bool empty() const noexcept
Returns true if the unordered_set is empty.
iterator erase(iterator __position)
Erases an element from an unordered_set.
unordered_set(unordered_set &&)=default
Move constructor.
unordered_set(const allocator_type &__a)
Creates an unordered_set with no elements.
const_local_iterator cend(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
auto contains(const _Kt &__k) const -> decltype(_M_h._M_find_tr(__k), void(), true)
Finds whether an element with the given key exists.
_Hashtable::const_pointer const_pointer
Iterator-related typedefs.
void swap(unordered_set &__x) noexcept(noexcept(_M_h.swap(__x._M_h)))
Swaps data with another unordered_set.
iterator insert(const_iterator __hint, const value_type &__x)
Attempts to insert an element into the unordered_set.
float load_factor() const noexcept
Returns the average number of elements per bucket.
void rehash(size_type __n)
May rehash the unordered_set.
local_iterator end(size_type __n)
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
_Hashtable::key_equal key_equal
Public typedefs.
size_type size() const noexcept
Returns the size of the unordered_set.
iterator insert(const_iterator, node_type &&__nh)
Re-insert an extracted node.
_Hashtable::const_iterator const_iterator
Iterator-related typedefs.
_Hashtable::difference_type difference_type
Iterator-related typedefs.
_Hashtable::const_reference const_reference
Iterator-related typedefs.
hasher hash_function() const
Returns the hash functor object with which the unordered_set was constructed.
unordered_set(const unordered_set &)=default
Copy constructor.
auto find(const _Kt &__k) const -> decltype(_M_h._M_find_tr(__k))
Tries to locate an element in an unordered_set.
iterator emplace_hint(const_iterator __pos, _Args &&... __args)
Attempts to insert an element into the unordered_set.
key_equal key_eq() const
Returns the key comparison object with which the unordered_set was constructed.
_Hashtable::allocator_type allocator_type
Public typedefs.
iterator insert(const_iterator __hint, value_type &&__x)
Attempts to insert an element into the unordered_set.
const_iterator end() const noexcept
iterator end() noexcept
node_type extract(const key_type &__key)
Extract a node.
local_iterator begin(size_type __n)
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_set()=default
Default constructor.
void insert(_InputIterator __first, _InputIterator __last)
A template function that attempts to insert a range of elements.
std::pair< iterator, bool > insert(value_type &&__x)
Attempts to insert an element into the unordered_set.
float max_load_factor() const noexcept
Returns a positive number that the unordered_set tries to keep the load factor less than or equal to.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
size_type erase(const key_type &__x)
Erases elements according to the provided key.
std::pair< iterator, bool > insert(const value_type &__x)
Attempts to insert an element into the unordered_set.
unordered_set(size_type __n, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Default constructor creates no elements.
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_set.
iterator erase(const_iterator __position)
Erases an element from an unordered_set.
allocator_type get_allocator() const noexcept
Returns the allocator object used by the unordered_set.
auto equal_range(const _Kt &__k) const -> decltype(_M_h._M_equal_range_tr(__k))
Finds a subsequence matching given key.
_Hashtable::const_local_iterator const_local_iterator
Iterator-related typedefs.
void clear() noexcept
void insert(initializer_list< value_type > __l)
Attempts to insert a list of elements into the unordered_set.
unordered_set(_InputIterator __first, _InputIterator __last, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_set from a range.
unordered_set & operator=(unordered_set &&)=default
Move assignment operator.
std::pair< iterator, bool > emplace(_Args &&... __args)
Attempts to build and insert an element into the unordered_set.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_set.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
void reserve(size_type __n)
Prepare the unordered_set for a specified number of elements.
node_type extract(const_iterator __pos)
Extract a node.
_Hashtable::pointer pointer
Iterator-related typedefs.
iterator begin() noexcept
iterator find(const key_type &__x)
Tries to locate an element in an unordered_set.
size_type max_size() const noexcept
Returns the maximum size of the unordered_set.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_set.