libstdc++
unordered_map.h
Go to the documentation of this file.
1 // unordered_map implementation -*- C++ -*-
2 
3 // Copyright (C) 2010-2026 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_map.h
26  * This is an internal header file, included by other library headers.
27  * Do not attempt to use it directly. @headername{unordered_map}
28  */
29 
30 #ifndef _UNORDERED_MAP_H
31 #define _UNORDERED_MAP_H
32 
33 #include <bits/hashtable.h>
34 #include <bits/allocator.h>
35 #include <bits/functional_hash.h> // hash
36 #include <bits/stl_function.h> // equal_to
37 #if __glibcxx_containers_ranges // C++ >= 23
38 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc.
39 #endif
40 
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
45 
46  /// Base types for unordered_map.
47  template<bool _Cache>
48  using __umap_traits = __detail::_Hashtable_traits<_Cache, false, true>;
49 
50  template<typename _Key,
51  typename _Tp,
52  typename _Hash = hash<_Key>,
53  typename _Pred = std::equal_to<_Key>,
56  using __umap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>,
57  _Alloc, __detail::_Select1st,
58  _Pred, _Hash,
59  __detail::_Mod_range_hashing,
60  __detail::_Default_ranged_hash,
61  __detail::_Prime_rehash_policy, _Tr>;
62 
63  /// Base types for unordered_multimap.
64  template<bool _Cache>
65  using __ummap_traits = __detail::_Hashtable_traits<_Cache, false, false>;
66 
67  template<typename _Key,
68  typename _Tp,
69  typename _Hash = hash<_Key>,
70  typename _Pred = std::equal_to<_Key>,
73  using __ummap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>,
74  _Alloc, __detail::_Select1st,
75  _Pred, _Hash,
76  __detail::_Mod_range_hashing,
77  __detail::_Default_ranged_hash,
78  __detail::_Prime_rehash_policy, _Tr>;
79 
80  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
81  class unordered_multimap;
82 
83  /**
84  * @brief A standard container composed of unique keys (containing
85  * at most one of each key value) that associates values of another type
86  * with the keys.
87  *
88  * @ingroup unordered_associative_containers
89  * @headerfile unordered_map
90  * @since C++11
91  *
92  * @tparam _Key Type of key objects.
93  * @tparam _Tp Type of mapped objects.
94  * @tparam _Hash Hashing function object type, defaults to hash<_Key>.
95  * @tparam _Pred Predicate function object type, defaults
96  * to equal_to<_Key>.
97  * @tparam _Alloc Allocator type, defaults to
98  * std::allocator<std::pair<const _Key, _Tp>>.
99  *
100  * Meets the requirements of a <a href="tables.html#65">container</a>, and
101  * <a href="tables.html#xx">unordered associative container</a>
102  *
103  * The resulting value type of the container is std::pair<const _Key, _Tp>.
104  *
105  * Base is _Hashtable, dispatched at compile time via template
106  * alias __umap_hashtable.
107  */
108  template<typename _Key, typename _Tp,
109  typename _Hash = hash<_Key>,
110  typename _Pred = equal_to<_Key>,
111  typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
113  {
114  typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
115  _Hashtable _M_h;
116 
117  public:
118  // typedefs:
119  ///@{
120  /// Public typedefs.
121  typedef typename _Hashtable::key_type key_type;
122  typedef typename _Hashtable::value_type value_type;
123  typedef typename _Hashtable::mapped_type mapped_type;
124  typedef typename _Hashtable::hasher hasher;
125  typedef typename _Hashtable::key_equal key_equal;
126  typedef typename _Hashtable::allocator_type allocator_type;
127  ///@}
128 
129  ///@{
130  /// Iterator-related typedefs.
131  typedef typename _Hashtable::pointer pointer;
132  typedef typename _Hashtable::const_pointer const_pointer;
133  typedef typename _Hashtable::reference reference;
134  typedef typename _Hashtable::const_reference const_reference;
135  typedef typename _Hashtable::iterator iterator;
136  typedef typename _Hashtable::const_iterator const_iterator;
137  typedef typename _Hashtable::local_iterator local_iterator;
138  typedef typename _Hashtable::const_local_iterator const_local_iterator;
139  typedef typename _Hashtable::size_type size_type;
140  typedef typename _Hashtable::difference_type difference_type;
141  ///@}
142 
143 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
144  using node_type = typename _Hashtable::node_type;
145  using insert_return_type = typename _Hashtable::insert_return_type;
146 #endif
147 
148  //construct/destroy/copy
149 
150  /// Default constructor.
151  unordered_map() = default;
152 
153  /**
154  * @brief Default constructor creates no elements.
155  * @param __n Minimal initial number of buckets.
156  * @param __hf A hash functor.
157  * @param __eql A key equality functor.
158  * @param __a An allocator object.
159  */
160  explicit
162  const hasher& __hf = hasher(),
163  const key_equal& __eql = key_equal(),
164  const allocator_type& __a = allocator_type())
165  : _M_h(__n, __hf, __eql, __a)
166  { }
167 
168  /**
169  * @brief Builds an %unordered_map from a range.
170  * @param __first An input iterator.
171  * @param __last An input iterator.
172  * @param __n Minimal initial number of buckets.
173  * @param __hf A hash functor.
174  * @param __eql A key equality functor.
175  * @param __a An allocator object.
176  *
177  * Create an %unordered_map consisting of copies of the elements from
178  * [__first,__last). This is linear in N (where N is
179  * distance(__first,__last)).
180  */
181  template<typename _InputIterator>
182  unordered_map(_InputIterator __first, _InputIterator __last,
183  size_type __n = 0,
184  const hasher& __hf = hasher(),
185  const key_equal& __eql = key_equal(),
186  const allocator_type& __a = allocator_type())
187  : _M_h(__first, __last, __n, __hf, __eql, __a)
188  { }
189 
190  /// Copy constructor.
191  unordered_map(const unordered_map&) = default;
192 
193  /// Move constructor.
195 
196  /**
197  * @brief Creates an %unordered_map with no elements.
198  * @param __a An allocator object.
199  */
200  explicit
202  : _M_h(__a)
203  { }
204 
205  /*
206  * @brief Copy constructor with allocator argument.
207  * @param __uset Input %unordered_map to copy.
208  * @param __a An allocator object.
209  */
210  unordered_map(const unordered_map& __umap,
211  const allocator_type& __a)
212  : _M_h(__umap._M_h, __a)
213  { }
214 
215  /*
216  * @brief Move constructor with allocator argument.
217  * @param __uset Input %unordered_map to move.
218  * @param __a An allocator object.
219  */
220  unordered_map(unordered_map&& __umap,
221  const allocator_type& __a)
222  noexcept( noexcept(_Hashtable(std::move(__umap._M_h), __a)) )
223  : _M_h(std::move(__umap._M_h), __a)
224  { }
225 
226  /**
227  * @brief Builds an %unordered_map from an initializer_list.
228  * @param __l An initializer_list.
229  * @param __n Minimal initial number of buckets.
230  * @param __hf A hash functor.
231  * @param __eql A key equality functor.
232  * @param __a An allocator object.
233  *
234  * Create an %unordered_map consisting of copies of the elements in the
235  * list. This is linear in N (where N is @a __l.size()).
236  */
238  size_type __n = 0,
239  const hasher& __hf = hasher(),
240  const key_equal& __eql = key_equal(),
241  const allocator_type& __a = allocator_type())
242  : _M_h(__l, __n, __hf, __eql, __a)
243  { }
244 
245  unordered_map(size_type __n, const allocator_type& __a)
246  : unordered_map(__n, hasher(), key_equal(), __a)
247  { }
248 
249  unordered_map(size_type __n, const hasher& __hf,
250  const allocator_type& __a)
251  : unordered_map(__n, __hf, key_equal(), __a)
252  { }
253 
254  // _GLIBCXX_RESOLVE_LIB_DEFECTS
255  // 2713. More missing allocator-extended constructors for unordered containers
256  template<typename _InputIterator>
257  unordered_map(_InputIterator __first, _InputIterator __last,
258  const allocator_type& __a)
259  : unordered_map(__first, __last, 0, hasher(), key_equal(), __a)
260  { }
261 
262  template<typename _InputIterator>
263  unordered_map(_InputIterator __first, _InputIterator __last,
264  size_type __n,
265  const allocator_type& __a)
266  : unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
267  { }
268 
269  template<typename _InputIterator>
270  unordered_map(_InputIterator __first, _InputIterator __last,
271  size_type __n, const hasher& __hf,
272  const allocator_type& __a)
273  : unordered_map(__first, __last, __n, __hf, key_equal(), __a)
274  { }
275 
276  unordered_map(initializer_list<value_type> __l,
277  size_type __n,
278  const allocator_type& __a)
279  : unordered_map(__l, __n, hasher(), key_equal(), __a)
280  { }
281 
282  // _GLIBCXX_RESOLVE_LIB_DEFECTS
283  // 2713. More missing allocator-extended constructors for unordered containers
284  unordered_map(initializer_list<value_type> __l,
285  const allocator_type& __a)
286  : unordered_map(__l, 0, hasher(), key_equal(), __a)
287  { }
288 
289  unordered_map(initializer_list<value_type> __l,
290  size_type __n, const hasher& __hf,
291  const allocator_type& __a)
292  : unordered_map(__l, __n, __hf, key_equal(), __a)
293  { }
294 
295 #if __glibcxx_containers_ranges // C++ >= 23
296  /**
297  * @brief Builds an %unordered_map from a range.
298  * @since C++23
299  * @param __rg An input range of elements that can be converted to
300  * the maps's value type.
301  * @param __n Minimal initial number of buckets.
302  * @param __hf A hash functor.
303  * @param __eql A key equality functor.
304  * @param __a An allocator object.
305  *
306  * Create an %unordered_map consisting of copies of the elements in the
307  * range. This is linear in N (where N is `std::ranges::size(__rg)`).
308  */
309  template<__detail::__container_compatible_range<value_type> _Rg>
310  unordered_map(from_range_t, _Rg&& __rg,
311  size_type __n = 0,
312  const hasher& __hf = hasher(),
313  const key_equal& __eql = key_equal(),
314  const allocator_type& __a = allocator_type())
315  : _M_h(__n, __hf, __eql, __a)
316  { insert_range(std::forward<_Rg>(__rg)); }
317 
318  // _GLIBCXX_RESOLVE_LIB_DEFECTS
319  // 2713. More missing allocator-extended constructors for unordered containers
320  template<__detail::__container_compatible_range<value_type> _Rg>
321  unordered_map(from_range_t, _Rg&& __rg, const allocator_type& __a)
322  : _M_h(0, hasher(), key_equal(), __a)
323  { insert_range(std::forward<_Rg>(__rg)); }
324 
325  template<__detail::__container_compatible_range<value_type> _Rg>
326  unordered_map(from_range_t, _Rg&& __rg, size_type __n,
327  const allocator_type& __a)
328  : _M_h(__n, hasher(), key_equal(), __a)
329  { insert_range(std::forward<_Rg>(__rg)); }
330 
331  template<__detail::__container_compatible_range<value_type> _Rg>
332  unordered_map(from_range_t, _Rg&& __rg, size_type __n,
333  const hasher& __hf, const allocator_type& __a)
334  : _M_h(__n, __hf, key_equal(), __a)
335  { insert_range(std::forward<_Rg>(__rg)); }
336 #endif
337 
338  /// Copy assignment operator.
340  operator=(const unordered_map&) = default;
341 
342  /// Move assignment operator.
344  operator=(unordered_map&&) = default;
345 
346  /**
347  * @brief %Unordered_map list assignment operator.
348  * @param __l An initializer_list.
349  *
350  * This function fills an %unordered_map with copies of the elements in
351  * the initializer list @a __l.
352  *
353  * Note that the assignment completely changes the %unordered_map and
354  * that the resulting %unordered_map's size is the same as the number
355  * of elements assigned.
356  */
359  {
360  _M_h = __l;
361  return *this;
362  }
363 
364  /// Returns the allocator object used by the %unordered_map.
366  get_allocator() const noexcept
367  { return _M_h.get_allocator(); }
368 
369  // size and capacity:
370 
371  /// Returns true if the %unordered_map is empty.
372  _GLIBCXX_NODISCARD bool
373  empty() const noexcept
374  { return _M_h.empty(); }
375 
376  /// Returns the size of the %unordered_map.
377  size_type
378  size() const noexcept
379  { return _M_h.size(); }
380 
381  /// Returns the maximum size of the %unordered_map.
382  size_type
383  max_size() const noexcept
384  { return _M_h.max_size(); }
385 
386  // iterators.
387 
388  /**
389  * Returns a read/write iterator that points to the first element in the
390  * %unordered_map.
391  */
392  iterator
393  begin() noexcept
394  { return _M_h.begin(); }
395 
396  ///@{
397  /**
398  * Returns a read-only (constant) iterator that points to the first
399  * element in the %unordered_map.
400  */
402  begin() const noexcept
403  { return _M_h.begin(); }
404 
406  cbegin() const noexcept
407  { return _M_h.begin(); }
408  ///@}
409 
410  /**
411  * Returns a read/write iterator that points one past the last element in
412  * the %unordered_map.
413  */
414  iterator
415  end() noexcept
416  { return _M_h.end(); }
417 
418  ///@{
419  /**
420  * Returns a read-only (constant) iterator that points one past the last
421  * element in the %unordered_map.
422  */
424  end() const noexcept
425  { return _M_h.end(); }
426 
428  cend() const noexcept
429  { return _M_h.end(); }
430  ///@}
431 
432  // modifiers.
433 
434  /**
435  * @brief Attempts to build and insert a std::pair into the
436  * %unordered_map.
437  *
438  * @param __args Arguments used to generate a new pair instance (see
439  * std::piecewise_contruct for passing arguments to each
440  * part of the pair constructor).
441  *
442  * @return A pair, of which the first element is an iterator that points
443  * to the possibly inserted pair, and the second is a bool that
444  * is true if the pair was actually inserted.
445  *
446  * This function attempts to build and insert a (key, value) %pair into
447  * the %unordered_map.
448  * An %unordered_map relies on unique keys and thus a %pair is only
449  * inserted if its first element (the key) is not already present in the
450  * %unordered_map.
451  *
452  * Insertion requires amortized constant time.
453  */
454  template<typename... _Args>
456  emplace(_Args&&... __args)
457  { return _M_h.emplace(std::forward<_Args>(__args)...); }
458 
459  ///@{
460  /**
461  * @brief Attempts to build and insert a std::pair into the
462  * %unordered_map.
463  *
464  * @param __pos An iterator that serves as a hint as to where the pair
465  * should be inserted.
466  * @param __args Arguments used to generate a new pair instance (see
467  * std::piecewise_contruct for passing arguments to each
468  * part of the pair constructor).
469  * @return An iterator that points to the element with key of the
470  * std::pair built from @a __args (may or may not be that
471  * std::pair).
472  *
473  * This function is not concerned about whether the insertion took place,
474  * and thus does not return a boolean like the single-argument emplace()
475  * does.
476  * Note that the first parameter is only a hint and can potentially
477  * improve the performance of the insertion process. A bad hint would
478  * cause no gains in efficiency.
479  *
480  * See
481  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
482  * for more on @a hinting.
483  *
484  * Insertion requires amortized constant time.
485  */
486  template<typename... _Args>
487  iterator
488  emplace_hint(const_iterator __pos, _Args&&... __args)
489  { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
490 
491 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
492  /// Extract a node.
493  node_type
495  {
496  __glibcxx_assert(__pos != end());
497  return _M_h.extract(__pos);
498  }
499 
500  /// Extract a node.
501  node_type
502  extract(const key_type& __key)
503  { return _M_h.extract(__key); }
504 
505 #ifdef __glibcxx_associative_heterogeneous_erasure // C++23
506  template <__heterogeneous_hash_key<unordered_map> _Kt>
507  node_type
508  extract(_Kt&& __key)
509  { return _M_h._M_extract_tr(__key); }
510 #endif
511 
512  /// Re-insert an extracted node.
513  insert_return_type
514  insert(node_type&& __nh)
515  { return _M_h._M_reinsert_node(std::move(__nh)); }
516 
517  /// Re-insert an extracted node.
518  iterator
519  insert(const_iterator, node_type&& __nh)
520  { return _M_h._M_reinsert_node(std::move(__nh)).position; }
521 #endif // node_extract
522 
523 #ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED
524  ///@{
525  /**
526  * @brief Attempts to build and insert a std::pair into the
527  * %unordered_map.
528  *
529  * @param __k Key to use for finding a possibly existing pair in
530  * the unordered_map.
531  * @param __args Arguments used to generate the .second for a
532  * new pair instance.
533  *
534  * @return A pair, of which the first element is an iterator that points
535  * to the possibly inserted pair, and the second is a bool that
536  * is true if the pair was actually inserted.
537  *
538  * This function attempts to build and insert a (key, value) %pair into
539  * the %unordered_map.
540  * An %unordered_map relies on unique keys and thus a %pair is only
541  * inserted if its first element (the key) is not already present in the
542  * %unordered_map.
543  * If a %pair is not inserted, this function has no effect.
544  *
545  * Insertion requires amortized constant time.
546  */
547  template <typename... _Args>
549  try_emplace(const key_type& __k, _Args&&... __args)
550  {
551  return _M_h.try_emplace(cend(), __k, std::forward<_Args>(__args)...);
552  }
553 
554  // move-capable overload
555  template <typename... _Args>
557  try_emplace(key_type&& __k, _Args&&... __args)
558  {
559  return _M_h.try_emplace(cend(), std::move(__k),
560  std::forward<_Args>(__args)...);
561  }
562 
563 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
564  template <__heterogeneous_hash_key<unordered_map> _Kt, typename ..._Args>
566  try_emplace(_Kt&& __k, _Args&&... __args)
567  {
568  return _M_h.try_emplace(cend(),
569  std::forward<_Kt>(__k), std::forward<_Args>(__args)...);
570  }
571 #endif
572  ///@}
573 
574  ///@{
575  /**
576  * @brief Attempts to build and insert a std::pair into the
577  * %unordered_map.
578  *
579  * @param __hint An iterator that serves as a hint as to where the pair
580  * should be inserted.
581  * @param __k Key to use for finding a possibly existing pair in
582  * the unordered_map.
583  * @param __args Arguments used to generate the .second for a
584  * new pair instance.
585  * @return An iterator that points to the element with key of the
586  * std::pair built from @a __args (may or may not be that
587  * std::pair).
588  *
589  * This function is not concerned about whether the insertion took place,
590  * and thus does not return a boolean like the single-argument emplace()
591  * does. However, if insertion did not take place,
592  * this function has no effect.
593  * Note that the first parameter is only a hint and can potentially
594  * improve the performance of the insertion process. A bad hint would
595  * cause no gains in efficiency.
596  *
597  * See
598  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
599  * for more on @a hinting.
600  *
601  * Insertion requires amortized constant time.
602  */
603  template <typename... _Args>
604  iterator
605  try_emplace(const_iterator __hint, const key_type& __k,
606  _Args&&... __args)
607  {
608  return _M_h.try_emplace(__hint, __k,
609  std::forward<_Args>(__args)...).first;
610  }
611 
612  // move-capable overload
613  template <typename... _Args>
614  iterator
615  try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
616  {
617  return _M_h.try_emplace(__hint, std::move(__k),
618  std::forward<_Args>(__args)...).first;
619  }
620 #endif // __glibcxx_unordered_map_try_emplace
621 
622 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
623  template <__heterogeneous_hash_key<unordered_map> _Kt, typename ..._Args>
624  iterator
625  try_emplace(const_iterator __hint, _Kt&& __k, _Args&&... __args)
626  {
627  return _M_h.try_emplace(__hint,
628  std::forward<_Kt>(__k), std::forward<_Args>(__args)...).first;
629  }
630 #endif
631  ///@}
632 
633  ///@{
634  /**
635  * @brief Attempts to insert a std::pair into the %unordered_map.
636 
637  * @param __x Pair to be inserted (see std::make_pair for easy
638  * creation of pairs).
639  *
640  * @return A pair, of which the first element is an iterator that
641  * points to the possibly inserted pair, and the second is
642  * a bool that is true if the pair was actually inserted.
643  *
644  * This function attempts to insert a (key, value) %pair into the
645  * %unordered_map. An %unordered_map relies on unique keys and thus a
646  * %pair is only inserted if its first element (the key) is not already
647  * present in the %unordered_map.
648  *
649  * Insertion requires amortized constant time.
650  */
652  insert(const value_type& __x)
653  { return _M_h.insert(__x); }
654 
655  // _GLIBCXX_RESOLVE_LIB_DEFECTS
656  // 2354. Unnecessary copying when inserting into maps with braced-init
659  { return _M_h.insert(std::move(__x)); }
660 
661  template<typename _Pair>
662  __enable_if_t<is_constructible<value_type, _Pair&&>::value,
664  insert(_Pair&& __x)
665  { return _M_h.emplace(std::forward<_Pair>(__x)); }
666  ///@}
667 
668  ///@{
669  /**
670  * @brief Attempts to insert a std::pair into the %unordered_map.
671  * @param __hint An iterator that serves as a hint as to where the
672  * pair should be inserted.
673  * @param __x Pair to be inserted (see std::make_pair for easy creation
674  * of pairs).
675  * @return An iterator that points to the element with key of
676  * @a __x (may or may not be the %pair passed in).
677  *
678  * This function is not concerned about whether the insertion took place,
679  * and thus does not return a boolean like the single-argument insert()
680  * does. Note that the first parameter is only a hint and can
681  * potentially improve the performance of the insertion process. A bad
682  * hint would cause no gains in efficiency.
683  *
684  * See
685  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
686  * for more on @a hinting.
687  *
688  * Insertion requires amortized constant time.
689  */
690  iterator
691  insert(const_iterator __hint, const value_type& __x)
692  { return _M_h.insert(__hint, __x); }
693 
694  // _GLIBCXX_RESOLVE_LIB_DEFECTS
695  // 2354. Unnecessary copying when inserting into maps with braced-init
696  iterator
698  { return _M_h.insert(__hint, std::move(__x)); }
699 
700  template<typename _Pair>
701  __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
702  insert(const_iterator __hint, _Pair&& __x)
703  { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); }
704  ///@}
705 
706  /**
707  * @brief A template function that attempts to insert a range of
708  * elements.
709  * @param __first Iterator pointing to the start of the range to be
710  * inserted.
711  * @param __last Iterator pointing to the end of the range.
712  *
713  * Complexity similar to that of the range constructor.
714  */
715  template<typename _InputIterator>
716  void
717  insert(_InputIterator __first, _InputIterator __last)
718  { _M_h.insert(__first, __last); }
719 
720  /**
721  * @brief Attempts to insert a list of elements into the %unordered_map.
722  * @param __l A std::initializer_list<value_type> of elements
723  * to be inserted.
724  *
725  * Complexity similar to that of the range constructor.
726  */
727  void
729  { _M_h.insert(__l); }
730 
731 #if __glibcxx_containers_ranges // C++ >= 23
732  /**
733  * @brief Inserts a range of elements.
734  * @since C++23
735  * @param __rg An input range of elements that can be converted to
736  * the map's value type.
737  */
738  template<__detail::__container_compatible_range<value_type> _Rg>
739  void
740  insert_range(_Rg&& __rg)
741  {
742  auto __first = ranges::begin(__rg);
743  const auto __last = ranges::end(__rg);
744  for (; __first != __last; ++__first)
745  _M_h.emplace(*__first);
746  }
747 #endif
748 
749 #ifdef __glibcxx_unordered_map_try_emplace // >= C++17 && HOSTED
750  ///@{
751  /**
752  * @brief Attempts to insert a std::pair into the %unordered_map.
753  * @param __k Key to use for finding a possibly existing pair in
754  * the map.
755  * @param __obj Argument used to generate the .second for a pair
756  * instance.
757  *
758  * @return A pair, of which the first element is an iterator that
759  * points to the possibly inserted pair, and the second is
760  * a bool that is true if the pair was actually inserted.
761  *
762  * This function attempts to insert a (key, value) %pair into the
763  * %unordered_map. An %unordered_map relies on unique keys and thus a
764  * %pair is only inserted if its first element (the key) is not already
765  * present in the %unordered_map.
766  * If the %pair was already in the %unordered_map, the .second of
767  * the %pair is assigned from __obj.
768  *
769  * Insertion requires amortized constant time.
770  */
771  template <typename _Obj>
772  pair<iterator, bool>
773  insert_or_assign(const key_type& __k, _Obj&& __obj)
774  {
775  auto __ret = _M_h.try_emplace(cend(), __k,
776  std::forward<_Obj>(__obj));
777  if (!__ret.second)
778  __ret.first->second = std::forward<_Obj>(__obj);
779  return __ret;
780  }
781 
782  // move-capable overload
783  template <typename _Obj>
785  insert_or_assign(key_type&& __k, _Obj&& __obj)
786  {
787  auto __ret = _M_h.try_emplace(cend(), std::move(__k),
788  std::forward<_Obj>(__obj));
789  if (!__ret.second)
790  __ret.first->second = std::forward<_Obj>(__obj);
791  return __ret;
792  }
793 
794 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
795  template <__heterogeneous_hash_key<unordered_map> _Kt, typename _Obj>
797  insert_or_assign(_Kt&& __k, _Obj&& __obj)
798  {
799  auto __ret = _M_h.try_emplace(
800  cend(), std::forward<_Kt>(__k), std::forward<_Obj>(__obj));
801  if (!__ret.second)
802  __ret.first->second = std::forward<_Obj>(__obj);
803  return __ret;
804  }
805 #endif
806  ///@}
807 
808  ///@{
809  /**
810  * @brief Attempts to insert a std::pair into the %unordered_map.
811  * @param __hint An iterator that serves as a hint as to where the
812  * pair should be inserted.
813  * @param __k Key to use for finding a possibly existing pair in
814  * the unordered_map.
815  * @param __obj Argument used to generate the .second for a pair
816  * instance.
817  * @return An iterator that points to the element with key of
818  * @a __x (may or may not be the %pair passed in).
819  *
820  * This function is not concerned about whether the insertion took place,
821  * and thus does not return a boolean like the single-argument insert()
822  * does.
823  * If the %pair was already in the %unordered map, the .second of
824  * the %pair is assigned from __obj.
825  * Note that the first parameter is only a hint and can
826  * potentially improve the performance of the insertion process. A bad
827  * hint would cause no gains in efficiency.
828  *
829  * See
830  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
831  * for more on @a hinting.
832  *
833  * Insertion requires amortized constant time.
834  */
835  template <typename _Obj>
836  iterator
838  _Obj&& __obj)
839  {
840  auto __ret = _M_h.try_emplace(__hint, __k, std::forward<_Obj>(__obj));
841  if (!__ret.second)
842  __ret.first->second = std::forward<_Obj>(__obj);
843  return __ret.first;
844  }
845 
846  // move-capable overload
847  template <typename _Obj>
848  iterator
849  insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
850  {
851  auto __ret = _M_h.try_emplace(__hint, std::move(__k),
852  std::forward<_Obj>(__obj));
853  if (!__ret.second)
854  __ret.first->second = std::forward<_Obj>(__obj);
855  return __ret.first;
856  }
857 
858 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
859  template <__heterogeneous_hash_key<unordered_map> _Kt, typename _Obj>
860  iterator
861  insert_or_assign(const_iterator __hint, _Kt&& __k, _Obj&& __obj)
862  {
863  auto __ret = _M_h.try_emplace(__hint,
864  std::forward<_Kt>(__k), std::forward<_Obj>(__obj));
865  if (!__ret.second)
866  __ret.first->second = std::forward<_Obj>(__obj);
867  return __ret.first;
868  }
869 #endif
870  ///@}
871 #endif // unordered_map_try_emplace
872 
873  ///@{
874  /**
875  * @brief Erases an element from an %unordered_map.
876  * @param __position An iterator pointing to the element to be erased.
877  * @return An iterator pointing to the element immediately following
878  * @a __position prior to the element being erased. If no such
879  * element exists, end() is returned.
880  *
881  * This function erases an element, pointed to by the given iterator,
882  * from an %unordered_map.
883  * Note that this function only erases the element, and that if the
884  * element is itself a pointer, the pointed-to memory is not touched in
885  * any way. Managing the pointer is the user's responsibility.
886  */
887  iterator
888  erase(const_iterator __position)
889  { return _M_h.erase(__position); }
890 
891  // LWG 2059.
892  iterator
893  erase(iterator __position)
894  { return _M_h.erase(__position); }
895  ///@}
896 
897  ///@{
898  /**
899  * @brief Erases elements according to the provided key.
900  * @param __x Key of element to be erased.
901  * @return The number of elements erased.
902  *
903  * This function erases all the elements located by the given key from
904  * an %unordered_map. For an %unordered_map the result of this function
905  * can only be 0 (not present) or 1 (present).
906  * Note that this function only erases the element, and that if the
907  * element is itself a pointer, the pointed-to memory is not touched in
908  * any way. Managing the pointer is the user's responsibility.
909  */
910  size_type
911  erase(const key_type& __x)
912  { return _M_h.erase(__x); }
913 
914 #ifdef __glibcxx_associative_heterogeneous_erasure // C++23
915  template <__heterogeneous_hash_key<unordered_map> _Kt>
916  size_type
917  erase(_Kt&& __key)
918  { return _M_h._M_erase_tr(__key); }
919 #endif
920  ///@}
921 
922  /**
923  * @brief Erases a [__first,__last) range of elements from an
924  * %unordered_map.
925  * @param __first Iterator pointing to the start of the range to be
926  * erased.
927  * @param __last Iterator pointing to the end of the range to
928  * be erased.
929  * @return The iterator @a __last.
930  *
931  * This function erases a sequence of elements from an %unordered_map.
932  * Note that this function only erases the elements, and that if
933  * the element is itself a pointer, the pointed-to memory is not touched
934  * in any way. Managing the pointer is the user's responsibility.
935  */
936  iterator
938  { return _M_h.erase(__first, __last); }
939 
940  /**
941  * Erases all elements in an %unordered_map.
942  * Note that this function only erases the elements, and that if the
943  * elements themselves are pointers, the pointed-to memory is not touched
944  * in any way. Managing the pointer is the user's responsibility.
945  */
946  void
947  clear() noexcept
948  { _M_h.clear(); }
949 
950  /**
951  * @brief Swaps data with another %unordered_map.
952  * @param __x An %unordered_map of the same element and allocator
953  * types.
954  *
955  * This exchanges the elements between two %unordered_map in constant
956  * time.
957  * Note that the global std::swap() function is specialized such that
958  * std::swap(m1,m2) will feed to this function.
959  */
960  void
962  noexcept( noexcept(_M_h.swap(__x._M_h)) )
963  { _M_h.swap(__x._M_h); }
964 
965 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
966  template<typename, typename, typename>
967  friend class std::_Hash_merge_helper;
968 
969  template<typename _H2, typename _P2>
970  void
972  {
973  if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
974  if (std::__addressof(__source) == this) [[__unlikely__]]
975  return;
976 
977  using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
978  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
979  }
980 
981  template<typename _H2, typename _P2>
982  void
983  merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
984  {
985  using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
986  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
987  }
988 
989  template<typename _H2, typename _P2>
990  void
991  merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
992  {
993  using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
994  _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
995  }
996 
997  template<typename _H2, typename _P2>
998  void
999  merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
1000  { merge(__source); }
1001 #endif // node_extract
1002 
1003  // observers.
1004 
1005  /// Returns the hash functor object with which the %unordered_map was
1006  /// constructed.
1007  hasher
1009  { return _M_h.hash_function(); }
1010 
1011  /// Returns the key comparison object with which the %unordered_map was
1012  /// constructed.
1013  key_equal
1014  key_eq() const
1015  { return _M_h.key_eq(); }
1016 
1017  // lookup.
1018 
1019  ///@{
1020  /**
1021  * @brief Tries to locate an element in an %unordered_map.
1022  * @param __x Key to be located.
1023  * @return Iterator pointing to sought-after element, or end() if not
1024  * found.
1025  *
1026  * This function takes a key and tries to locate the element with which
1027  * the key matches. If successful the function returns an iterator
1028  * pointing to the sought after element. If unsuccessful it returns the
1029  * past-the-end ( @c end() ) iterator.
1030  */
1031  iterator
1032  find(const key_type& __x)
1033  { return _M_h.find(__x); }
1034 
1035 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1036  template<typename _Kt>
1037  auto
1038  find(const _Kt& __x) -> decltype(_M_h._M_find_tr(__x))
1039  { return _M_h._M_find_tr(__x); }
1040 #endif
1041 
1043  find(const key_type& __x) const
1044  { return _M_h.find(__x); }
1045 
1046 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1047  template<typename _Kt>
1048  auto
1049  find(const _Kt& __x) const -> decltype(_M_h._M_find_tr(__x))
1050  { return _M_h._M_find_tr(__x); }
1051 #endif
1052  ///@}
1053 
1054  ///@{
1055  /**
1056  * @brief Finds the number of elements.
1057  * @param __x Key to count.
1058  * @return Number of elements with specified key.
1059  *
1060  * This function only makes sense for %unordered_multimap; for
1061  * %unordered_map the result will either be 0 (not present) or 1
1062  * (present).
1063  */
1064  size_type
1065  count(const key_type& __x) const
1066  { return _M_h.count(__x); }
1067 
1068 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1069  template<typename _Kt>
1070  auto
1071  count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
1072  { return _M_h._M_count_tr(__x); }
1073 #endif
1074  ///@}
1075 
1076 #if __cplusplus > 201703L
1077  ///@{
1078  /**
1079  * @brief Finds whether an element with the given key exists.
1080  * @param __x Key of elements to be located.
1081  * @return True if there is any element with the specified key.
1082  */
1083  bool
1084  contains(const key_type& __x) const
1085  { return _M_h.find(__x) != _M_h.end(); }
1086 
1087  template<typename _Kt>
1088  auto
1089  contains(const _Kt& __x) const
1090  -> decltype(_M_h._M_find_tr(__x), void(), true)
1091  { return _M_h._M_find_tr(__x) != _M_h.end(); }
1092  ///@}
1093 #endif
1094 
1095  ///@{
1096  /**
1097  * @brief Finds a subsequence matching given key.
1098  * @param __x Key to be located.
1099  * @return Pair of iterators that possibly points to the subsequence
1100  * matching given key.
1101  *
1102  * This function probably only makes sense for %unordered_multimap.
1103  */
1105  equal_range(const key_type& __x)
1106  { return _M_h.equal_range(__x); }
1107 
1108 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1109  template<typename _Kt>
1110  auto
1111  equal_range(const _Kt& __x)
1112  -> decltype(_M_h._M_equal_range_tr(__x))
1113  { return _M_h._M_equal_range_tr(__x); }
1114 #endif
1115 
1117  equal_range(const key_type& __x) const
1118  { return _M_h.equal_range(__x); }
1119 
1120 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1121  template<typename _Kt>
1122  auto
1123  equal_range(const _Kt& __x) const
1124  -> decltype(_M_h._M_equal_range_tr(__x))
1125  { return _M_h._M_equal_range_tr(__x); }
1126 #endif
1127  ///@}
1128 
1129  ///@{
1130  /**
1131  * @brief Subscript ( @c [] ) access to %unordered_map data.
1132  * @param __k The key for which data should be retrieved.
1133  * @return A reference to the data of the (key,data) %pair.
1134  *
1135  * Allows for easy lookup with the subscript ( @c [] )operator. Returns
1136  * data associated with the key specified in subscript. If the key does
1137  * not exist, a pair with that key is created using default values, which
1138  * is then returned.
1139  *
1140  * Lookup requires constant time.
1141  */
1142  mapped_type&
1143  operator[](const key_type& __k)
1144  { return _M_h[__k]; }
1145 
1146  mapped_type&
1148  { return _M_h[std::move(__k)]; }
1149 
1150 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
1151  template <__heterogeneous_hash_key<unordered_map> _Kt>
1152  mapped_type&
1153  operator[](_Kt&& __k)
1154  {
1155  return try_emplace(std::forward<_Kt>(__k)).first->second;
1156  }
1157 #endif
1158  ///@}
1159 
1160  ///@{
1161  /**
1162  * @brief Access to %unordered_map data.
1163  * @param __k The key for which data should be retrieved.
1164  * @return A reference to the data whose key is equal to @a __k, if
1165  * such a data is present in the %unordered_map.
1166  * @throw std::out_of_range If no such data is present.
1167  */
1168  mapped_type&
1169  at(const key_type& __k)
1170  { return _M_h.at(__k); }
1171 
1172 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
1173  template <__heterogeneous_hash_key<unordered_map> _Kt>
1174  mapped_type&
1175  at(const _Kt& __k)
1176  { return _M_h._M_at_tr(__k); }
1177 #endif
1178 
1179  const mapped_type&
1180  at(const key_type& __k) const
1181  { return _M_h.at(__k); }
1182 
1183 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
1184  template <__heterogeneous_hash_key<unordered_map> _Kt>
1185  const mapped_type&
1186  at(const _Kt& __k) const
1187  { return _M_h._M_at_tr(__k); }
1188 #endif
1189  ///@}
1190 
1191  // bucket interface.
1192 
1193  /// Returns the number of buckets of the %unordered_map.
1194  size_type
1195  bucket_count() const noexcept
1196  { return _M_h.bucket_count(); }
1197 
1198  /// Returns the maximum number of buckets of the %unordered_map.
1199  size_type
1200  max_bucket_count() const noexcept
1201  { return _M_h.max_bucket_count(); }
1202 
1203  /*
1204  * @brief Returns the number of elements in a given bucket.
1205  * @param __n A bucket index.
1206  * @return The number of elements in the bucket.
1207  */
1208  size_type
1209  bucket_size(size_type __n) const
1210  { return _M_h.bucket_size(__n); }
1211 
1212  ///@{
1213  /*
1214  * @brief Returns the bucket index of a given element.
1215  * @param __key A key instance.
1216  * @return The key bucket index.
1217  */
1218  size_type
1219  bucket(const key_type& __key) const
1220  { return _M_h.bucket(__key); }
1221 
1222 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
1223  template <__heterogeneous_hash_key<unordered_map> _Kt>
1224  size_type
1225  bucket(const _Kt& __key) const
1226  { return _M_h._M_bucket_tr(__key); }
1227 #endif
1228  ///@}
1229 
1230  /**
1231  * @brief Returns a read/write iterator pointing to the first bucket
1232  * element.
1233  * @param __n The bucket index.
1234  * @return A read/write local iterator.
1235  */
1238  { return _M_h.begin(__n); }
1239 
1240  ///@{
1241  /**
1242  * @brief Returns a read-only (constant) iterator pointing to the first
1243  * bucket element.
1244  * @param __n The bucket index.
1245  * @return A read-only local iterator.
1246  */
1248  begin(size_type __n) const
1249  { return _M_h.begin(__n); }
1250 
1252  cbegin(size_type __n) const
1253  { return _M_h.cbegin(__n); }
1254  ///@}
1255 
1256  /**
1257  * @brief Returns a read/write iterator pointing to one past the last
1258  * bucket elements.
1259  * @param __n The bucket index.
1260  * @return A read/write local iterator.
1261  */
1264  { return _M_h.end(__n); }
1265 
1266  ///@{
1267  /**
1268  * @brief Returns a read-only (constant) iterator pointing to one past
1269  * the last bucket elements.
1270  * @param __n The bucket index.
1271  * @return A read-only local iterator.
1272  */
1274  end(size_type __n) const
1275  { return _M_h.end(__n); }
1276 
1278  cend(size_type __n) const
1279  { return _M_h.cend(__n); }
1280  ///@}
1281 
1282  // hash policy.
1283 
1284  /// Returns the average number of elements per bucket.
1285  float
1286  load_factor() const noexcept
1287  { return _M_h.load_factor(); }
1288 
1289  /// Returns a positive number that the %unordered_map tries to keep the
1290  /// load factor less than or equal to.
1291  float
1292  max_load_factor() const noexcept
1293  { return _M_h.max_load_factor(); }
1294 
1295  /**
1296  * @brief Change the %unordered_map maximum load factor.
1297  * @param __z The new maximum load factor.
1298  */
1299  void
1300  max_load_factor(float __z)
1301  { _M_h.max_load_factor(__z); }
1302 
1303  /**
1304  * @brief May rehash the %unordered_map.
1305  * @param __n The new number of buckets.
1306  *
1307  * Rehash will occur only if the new number of buckets respect the
1308  * %unordered_map maximum load factor.
1309  */
1310  void
1312  { _M_h.rehash(__n); }
1313 
1314  /**
1315  * @brief Prepare the %unordered_map for a specified number of
1316  * elements.
1317  * @param __n Number of elements required.
1318  *
1319  * Same as rehash(ceil(n / max_load_factor())).
1320  */
1321  void
1323  { _M_h.reserve(__n); }
1324 
1325  template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
1326  typename _Alloc1>
1327  friend bool
1330  };
1331 
1332 #if __cpp_deduction_guides >= 201606
1333 
1334  template<typename _InputIterator,
1335  typename _Hash = hash<__iter_key_t<_InputIterator>>,
1336  typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
1337  typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
1338  typename = _RequireInputIter<_InputIterator>,
1339  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1340  typename = _RequireNotAllocator<_Pred>,
1341  typename = _RequireAllocator<_Allocator>>
1342  unordered_map(_InputIterator, _InputIterator,
1343  typename unordered_map<int, int>::size_type = {},
1344  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1345  -> unordered_map<__iter_key_t<_InputIterator>,
1346  __iter_val_t<_InputIterator>,
1347  _Hash, _Pred, _Allocator>;
1348 
1349  template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
1350  typename _Pred = equal_to<_Key>,
1351  typename _Allocator = allocator<pair<const _Key, _Tp>>,
1352  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1353  typename = _RequireNotAllocator<_Pred>,
1354  typename = _RequireAllocator<_Allocator>>
1355  unordered_map(initializer_list<pair<_Key, _Tp>>,
1356  typename unordered_map<int, int>::size_type = {},
1357  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1358  -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
1359 
1360  template<typename _InputIterator, typename _Allocator,
1361  typename = _RequireInputIter<_InputIterator>,
1362  typename = _RequireAllocator<_Allocator>>
1363  unordered_map(_InputIterator, _InputIterator,
1364  typename unordered_map<int, int>::size_type, _Allocator)
1365  -> unordered_map<__iter_key_t<_InputIterator>,
1366  __iter_val_t<_InputIterator>,
1367  hash<__iter_key_t<_InputIterator>>,
1368  equal_to<__iter_key_t<_InputIterator>>,
1369  _Allocator>;
1370 
1371  template<typename _InputIterator, typename _Allocator,
1372  typename = _RequireInputIter<_InputIterator>,
1373  typename = _RequireAllocator<_Allocator>>
1374  unordered_map(_InputIterator, _InputIterator, _Allocator)
1375  -> unordered_map<__iter_key_t<_InputIterator>,
1376  __iter_val_t<_InputIterator>,
1377  hash<__iter_key_t<_InputIterator>>,
1378  equal_to<__iter_key_t<_InputIterator>>,
1379  _Allocator>;
1380 
1381  template<typename _InputIterator, typename _Hash, typename _Allocator,
1382  typename = _RequireInputIter<_InputIterator>,
1383  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1384  typename = _RequireAllocator<_Allocator>>
1385  unordered_map(_InputIterator, _InputIterator,
1387  _Hash, _Allocator)
1388  -> unordered_map<__iter_key_t<_InputIterator>,
1389  __iter_val_t<_InputIterator>, _Hash,
1390  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1391 
1392  template<typename _Key, typename _Tp, typename _Allocator,
1393  typename = _RequireAllocator<_Allocator>>
1394  unordered_map(initializer_list<pair<_Key, _Tp>>,
1396  _Allocator)
1397  -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1398 
1399  template<typename _Key, typename _Tp, typename _Allocator,
1400  typename = _RequireAllocator<_Allocator>>
1401  unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator)
1402  -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1403 
1404  template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
1405  typename = _RequireNotAllocatorOrIntegral<_Hash>,
1406  typename = _RequireAllocator<_Allocator>>
1407  unordered_map(initializer_list<pair<_Key, _Tp>>,
1409  _Hash, _Allocator)
1410  -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
1411 
1412 #if __glibcxx_containers_ranges // C++ >= 23
1413  template<ranges::input_range _Rg,
1414  __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
1415  __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
1416  __allocator_like _Allocator =
1417  allocator<__detail::__range_to_alloc_type<_Rg>>>
1418  unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type = {},
1419  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1420  -> unordered_map<__detail::__range_key_type<_Rg>,
1421  __detail::__range_mapped_type<_Rg>,
1422  _Hash, _Pred, _Allocator>;
1423 
1424  template<ranges::input_range _Rg,
1425  __allocator_like _Allocator>
1426  unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type,
1427  _Allocator)
1428  -> unordered_map<__detail::__range_key_type<_Rg>,
1429  __detail::__range_mapped_type<_Rg>,
1430  hash<__detail::__range_key_type<_Rg>>,
1431  equal_to<__detail::__range_key_type<_Rg>>,
1432  _Allocator>;
1433 
1434  template<ranges::input_range _Rg,
1435  __allocator_like _Allocator>
1436  unordered_map(from_range_t, _Rg&&, _Allocator)
1437  -> unordered_map<__detail::__range_key_type<_Rg>,
1438  __detail::__range_mapped_type<_Rg>,
1439  hash<__detail::__range_key_type<_Rg>>,
1440  equal_to<__detail::__range_key_type<_Rg>>,
1441  _Allocator>;
1442 
1443  template<ranges::input_range _Rg,
1444  __not_allocator_like _Hash,
1445  __allocator_like _Allocator>
1446  unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type,
1447  _Hash, _Allocator)
1448  -> unordered_map<__detail::__range_key_type<_Rg>,
1449  __detail::__range_mapped_type<_Rg>,
1450  _Hash, equal_to<__detail::__range_key_type<_Rg>>,
1451  _Allocator>;
1452 #endif
1453 #endif
1454 
1455  /**
1456  * @brief A standard container composed of equivalent keys
1457  * (possibly containing multiple of each key value) that associates
1458  * values of another type with the keys.
1459  *
1460  * @ingroup unordered_associative_containers
1461  * @headerfile unordered_map
1462  * @since C++11
1463  *
1464  * @tparam _Key Type of key objects.
1465  * @tparam _Tp Type of mapped objects.
1466  * @tparam _Hash Hashing function object type, defaults to hash<_Key>.
1467  * @tparam _Pred Predicate function object type, defaults
1468  * to equal_to<_Key>.
1469  * @tparam _Alloc Allocator type, defaults to
1470  * std::allocator<std::pair<const _Key, _Tp>>.
1471  *
1472  * Meets the requirements of a <a href="tables.html#65">container</a>, and
1473  * <a href="tables.html#xx">unordered associative container</a>
1474  *
1475  * The resulting value type of the container is std::pair<const _Key, _Tp>.
1476  *
1477  * Base is _Hashtable, dispatched at compile time via template
1478  * alias __ummap_hashtable.
1479  */
1480  template<typename _Key, typename _Tp,
1481  typename _Hash = hash<_Key>,
1482  typename _Pred = equal_to<_Key>,
1483  typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
1485  {
1486  typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
1487  _Hashtable _M_h;
1488 
1489  public:
1490  // typedefs:
1491  ///@{
1492  /// Public typedefs.
1493  typedef typename _Hashtable::key_type key_type;
1494  typedef typename _Hashtable::value_type value_type;
1495  typedef typename _Hashtable::mapped_type mapped_type;
1496  typedef typename _Hashtable::hasher hasher;
1497  typedef typename _Hashtable::key_equal key_equal;
1498  typedef typename _Hashtable::allocator_type allocator_type;
1499  ///@}
1500 
1501  ///@{
1502  /// Iterator-related typedefs.
1503  typedef typename _Hashtable::pointer pointer;
1504  typedef typename _Hashtable::const_pointer const_pointer;
1505  typedef typename _Hashtable::reference reference;
1506  typedef typename _Hashtable::const_reference const_reference;
1507  typedef typename _Hashtable::iterator iterator;
1508  typedef typename _Hashtable::const_iterator const_iterator;
1509  typedef typename _Hashtable::local_iterator local_iterator;
1510  typedef typename _Hashtable::const_local_iterator const_local_iterator;
1511  typedef typename _Hashtable::size_type size_type;
1512  typedef typename _Hashtable::difference_type difference_type;
1513  ///@}
1514 
1515 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1516  using node_type = typename _Hashtable::node_type;
1517 #endif
1518 
1519  //construct/destroy/copy
1520 
1521  /// Default constructor.
1522  unordered_multimap() = default;
1523 
1524  /**
1525  * @brief Default constructor creates no elements.
1526  * @param __n Mnimal initial number of buckets.
1527  * @param __hf A hash functor.
1528  * @param __eql A key equality functor.
1529  * @param __a An allocator object.
1530  */
1531  explicit
1533  const hasher& __hf = hasher(),
1534  const key_equal& __eql = key_equal(),
1535  const allocator_type& __a = allocator_type())
1536  : _M_h(__n, __hf, __eql, __a)
1537  { }
1538 
1539  /**
1540  * @brief Builds an %unordered_multimap from a range.
1541  * @param __first An input iterator.
1542  * @param __last An input iterator.
1543  * @param __n Minimal initial number of buckets.
1544  * @param __hf A hash functor.
1545  * @param __eql A key equality functor.
1546  * @param __a An allocator object.
1547  *
1548  * Create an %unordered_multimap consisting of copies of the elements
1549  * from [__first,__last). This is linear in N (where N is
1550  * distance(__first,__last)).
1551  */
1552  template<typename _InputIterator>
1553  unordered_multimap(_InputIterator __first, _InputIterator __last,
1554  size_type __n = 0,
1555  const hasher& __hf = hasher(),
1556  const key_equal& __eql = key_equal(),
1557  const allocator_type& __a = allocator_type())
1558  : _M_h(__first, __last, __n, __hf, __eql, __a)
1559  { }
1560 
1561  /// Copy constructor.
1563 
1564  /// Move constructor.
1566 
1567  /**
1568  * @brief Creates an %unordered_multimap with no elements.
1569  * @param __a An allocator object.
1570  */
1571  explicit
1573  : _M_h(__a)
1574  { }
1575 
1576  /*
1577  * @brief Copy constructor with allocator argument.
1578  * @param __uset Input %unordered_multimap to copy.
1579  * @param __a An allocator object.
1580  */
1581  unordered_multimap(const unordered_multimap& __ummap,
1582  const allocator_type& __a)
1583  : _M_h(__ummap._M_h, __a)
1584  { }
1585 
1586  /*
1587  * @brief Move constructor with allocator argument.
1588  * @param __uset Input %unordered_multimap to move.
1589  * @param __a An allocator object.
1590  */
1592  const allocator_type& __a)
1593  noexcept( noexcept(_Hashtable(std::move(__ummap._M_h), __a)) )
1594  : _M_h(std::move(__ummap._M_h), __a)
1595  { }
1596 
1597  /**
1598  * @brief Builds an %unordered_multimap from an initializer_list.
1599  * @param __l An initializer_list.
1600  * @param __n Minimal initial number of buckets.
1601  * @param __hf A hash functor.
1602  * @param __eql A key equality functor.
1603  * @param __a An allocator object.
1604  *
1605  * Create an %unordered_multimap consisting of copies of the elements in
1606  * the list. This is linear in N (where N is @a __l.size()).
1607  */
1609  size_type __n = 0,
1610  const hasher& __hf = hasher(),
1611  const key_equal& __eql = key_equal(),
1612  const allocator_type& __a = allocator_type())
1613  : _M_h(__l, __n, __hf, __eql, __a)
1614  { }
1615 
1617  : unordered_multimap(__n, hasher(), key_equal(), __a)
1618  { }
1619 
1620  unordered_multimap(size_type __n, const hasher& __hf,
1621  const allocator_type& __a)
1622  : unordered_multimap(__n, __hf, key_equal(), __a)
1623  { }
1624 
1625  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1626  // 2713. More missing allocator-extended constructors for unordered containers
1627  template<typename _InputIterator>
1628  unordered_multimap(_InputIterator __first, _InputIterator __last,
1629  const allocator_type& __a)
1630  : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a)
1631  { }
1632 
1633  template<typename _InputIterator>
1634  unordered_multimap(_InputIterator __first, _InputIterator __last,
1635  size_type __n,
1636  const allocator_type& __a)
1637  : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
1638  { }
1639 
1640  template<typename _InputIterator>
1641  unordered_multimap(_InputIterator __first, _InputIterator __last,
1642  size_type __n, const hasher& __hf,
1643  const allocator_type& __a)
1644  : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
1645  { }
1646 
1647  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1648  // 2713. More missing allocator-extended constructors for unordered containers
1649  unordered_multimap(initializer_list<value_type> __l,
1650  const allocator_type& __a)
1651  : unordered_multimap(__l, 0, hasher(), key_equal(), __a)
1652  { }
1653 
1654  unordered_multimap(initializer_list<value_type> __l,
1655  size_type __n,
1656  const allocator_type& __a)
1657  : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
1658  { }
1659 
1660  unordered_multimap(initializer_list<value_type> __l,
1661  size_type __n, const hasher& __hf,
1662  const allocator_type& __a)
1663  : unordered_multimap(__l, __n, __hf, key_equal(), __a)
1664  { }
1665 
1666 #if __glibcxx_containers_ranges // C++ >= 23
1667  /**
1668  * @brief Builds an %unordered_multimap from a range.
1669  * @since C++23
1670  * @param __rg An input range of elements that can be converted to
1671  * the maps's value type.
1672  * @param __n Minimal initial number of buckets.
1673  * @param __hf A hash functor.
1674  * @param __eql A key equality functor.
1675  * @param __a An allocator object.
1676  *
1677  * Create an %unordered_multimap consisting of copies of the elements in
1678  * the range. This is linear in N (where N is `std::ranges::size(__rg)`).
1679  */
1680  template<__detail::__container_compatible_range<value_type> _Rg>
1681  unordered_multimap(from_range_t, _Rg&& __rg,
1682  size_type __n = 0,
1683  const hasher& __hf = hasher(),
1684  const key_equal& __eql = key_equal(),
1685  const allocator_type& __a = allocator_type())
1686  : _M_h(__n, __hf, __eql, __a)
1687  { insert_range(std::forward<_Rg>(__rg)); }
1688 
1689  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1690  // 2713. More missing allocator-extended constructors for unordered containers
1691  template<__detail::__container_compatible_range<value_type> _Rg>
1692  unordered_multimap(from_range_t, _Rg&& __rg, const allocator_type& __a)
1693  : _M_h(0, hasher(), key_equal(), __a)
1694  { insert_range(std::forward<_Rg>(__rg)); }
1695 
1696  template<__detail::__container_compatible_range<value_type> _Rg>
1697  unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1698  const allocator_type& __a)
1699  : _M_h(__n, hasher(), key_equal(), __a)
1700  { insert_range(std::forward<_Rg>(__rg)); }
1701 
1702  template<__detail::__container_compatible_range<value_type> _Rg>
1703  unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1704  const hasher& __hf, const allocator_type& __a)
1705  : _M_h(__n, __hf, key_equal(), __a)
1706  { insert_range(std::forward<_Rg>(__rg)); }
1707 #endif
1708 
1709  /// Copy assignment operator.
1711  operator=(const unordered_multimap&) = default;
1712 
1713  /// Move assignment operator.
1716 
1717  /**
1718  * @brief %Unordered_multimap list assignment operator.
1719  * @param __l An initializer_list.
1720  *
1721  * This function fills an %unordered_multimap with copies of the
1722  * elements in the initializer list @a __l.
1723  *
1724  * Note that the assignment completely changes the %unordered_multimap
1725  * and that the resulting %unordered_multimap's size is the same as the
1726  * number of elements assigned.
1727  */
1730  {
1731  _M_h = __l;
1732  return *this;
1733  }
1734 
1735  /// Returns the allocator object used by the %unordered_multimap.
1737  get_allocator() const noexcept
1738  { return _M_h.get_allocator(); }
1739 
1740  // size and capacity:
1741 
1742  /// Returns true if the %unordered_multimap is empty.
1743  _GLIBCXX_NODISCARD bool
1744  empty() const noexcept
1745  { return _M_h.empty(); }
1746 
1747  /// Returns the size of the %unordered_multimap.
1748  size_type
1749  size() const noexcept
1750  { return _M_h.size(); }
1751 
1752  /// Returns the maximum size of the %unordered_multimap.
1753  size_type
1754  max_size() const noexcept
1755  { return _M_h.max_size(); }
1756 
1757  // iterators.
1758 
1759  /**
1760  * Returns a read/write iterator that points to the first element in the
1761  * %unordered_multimap.
1762  */
1763  iterator
1764  begin() noexcept
1765  { return _M_h.begin(); }
1766 
1767  ///@{
1768  /**
1769  * Returns a read-only (constant) iterator that points to the first
1770  * element in the %unordered_multimap.
1771  */
1773  begin() const noexcept
1774  { return _M_h.begin(); }
1775 
1777  cbegin() const noexcept
1778  { return _M_h.begin(); }
1779  ///@}
1780 
1781  /**
1782  * Returns a read/write iterator that points one past the last element in
1783  * the %unordered_multimap.
1784  */
1785  iterator
1786  end() noexcept
1787  { return _M_h.end(); }
1788 
1789  ///@{
1790  /**
1791  * Returns a read-only (constant) iterator that points one past the last
1792  * element in the %unordered_multimap.
1793  */
1795  end() const noexcept
1796  { return _M_h.end(); }
1797 
1799  cend() const noexcept
1800  { return _M_h.end(); }
1801  ///@}
1802 
1803  // modifiers.
1804 
1805  /**
1806  * @brief Attempts to build and insert a std::pair into the
1807  * %unordered_multimap.
1808  *
1809  * @param __args Arguments used to generate a new pair instance (see
1810  * std::piecewise_contruct for passing arguments to each
1811  * part of the pair constructor).
1812  *
1813  * @return An iterator that points to the inserted pair.
1814  *
1815  * This function attempts to build and insert a (key, value) %pair into
1816  * the %unordered_multimap.
1817  *
1818  * Insertion requires amortized constant time.
1819  */
1820  template<typename... _Args>
1821  iterator
1822  emplace(_Args&&... __args)
1823  { return _M_h.emplace(std::forward<_Args>(__args)...); }
1824 
1825  /**
1826  * @brief Attempts to build and insert a std::pair into the
1827  * %unordered_multimap.
1828  *
1829  * @param __pos An iterator that serves as a hint as to where the pair
1830  * should be inserted.
1831  * @param __args Arguments used to generate a new pair instance (see
1832  * std::piecewise_contruct for passing arguments to each
1833  * part of the pair constructor).
1834  * @return An iterator that points to the element with key of the
1835  * std::pair built from @a __args.
1836  *
1837  * Note that the first parameter is only a hint and can potentially
1838  * improve the performance of the insertion process. A bad hint would
1839  * cause no gains in efficiency.
1840  *
1841  * See
1842  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1843  * for more on @a hinting.
1844  *
1845  * Insertion requires amortized constant time.
1846  */
1847  template<typename... _Args>
1848  iterator
1849  emplace_hint(const_iterator __pos, _Args&&... __args)
1850  { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
1851 
1852  ///@{
1853  /**
1854  * @brief Inserts a std::pair into the %unordered_multimap.
1855  * @param __x Pair to be inserted (see std::make_pair for easy
1856  * creation of pairs).
1857  *
1858  * @return An iterator that points to the inserted pair.
1859  *
1860  * Insertion requires amortized constant time.
1861  */
1862  iterator
1863  insert(const value_type& __x)
1864  { return _M_h.insert(__x); }
1865 
1866  iterator
1868  { return _M_h.insert(std::move(__x)); }
1869 
1870  template<typename _Pair>
1871  __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
1872  insert(_Pair&& __x)
1873  { return _M_h.emplace(std::forward<_Pair>(__x)); }
1874  ///@}
1875 
1876  ///@{
1877  /**
1878  * @brief Inserts a std::pair into the %unordered_multimap.
1879  * @param __hint An iterator that serves as a hint as to where the
1880  * pair should be inserted.
1881  * @param __x Pair to be inserted (see std::make_pair for easy creation
1882  * of pairs).
1883  * @return An iterator that points to the element with key of
1884  * @a __x (may or may not be the %pair passed in).
1885  *
1886  * Note that the first parameter is only a hint and can potentially
1887  * improve the performance of the insertion process. A bad hint would
1888  * cause no gains in efficiency.
1889  *
1890  * See
1891  * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1892  * for more on @a hinting.
1893  *
1894  * Insertion requires amortized constant time.
1895  */
1896  iterator
1897  insert(const_iterator __hint, const value_type& __x)
1898  { return _M_h.insert(__hint, __x); }
1899 
1900  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1901  // 2354. Unnecessary copying when inserting into maps with braced-init
1902  iterator
1904  { return _M_h.insert(__hint, std::move(__x)); }
1905 
1906  template<typename _Pair>
1907  __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
1908  insert(const_iterator __hint, _Pair&& __x)
1909  { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); }
1910  ///@}
1911 
1912  /**
1913  * @brief A template function that attempts to insert a range of
1914  * elements.
1915  * @param __first Iterator pointing to the start of the range to be
1916  * inserted.
1917  * @param __last Iterator pointing to the end of the range.
1918  *
1919  * Complexity similar to that of the range constructor.
1920  */
1921  template<typename _InputIterator>
1922  void
1923  insert(_InputIterator __first, _InputIterator __last)
1924  { _M_h.insert(__first, __last); }
1925 
1926  /**
1927  * @brief Attempts to insert a list of elements into the
1928  * %unordered_multimap.
1929  * @param __l A std::initializer_list<value_type> of elements
1930  * to be inserted.
1931  *
1932  * Complexity similar to that of the range constructor.
1933  */
1934  void
1936  { _M_h.insert(__l); }
1937 
1938 #if __glibcxx_containers_ranges // C++ >= 23
1939  /**
1940  * @brief Inserts a range of elements.
1941  * @since C++23
1942  * @param __rg An input range of elements that can be converted to
1943  * the maps's value type.
1944  */
1945  template<__detail::__container_compatible_range<value_type> _Rg>
1946  void
1947  insert_range(_Rg&& __rg)
1948  {
1949  auto __first = ranges::begin(__rg);
1950  const auto __last = ranges::end(__rg);
1951  if (__first == __last)
1952  return;
1953 
1954  if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
1955  _M_h._M_rehash_insert(size_type(ranges::distance(__rg)));
1956  else
1957  _M_h._M_rehash_insert(1);
1958 
1959  for (; __first != __last; ++__first)
1960  _M_h.emplace(*__first);
1961  }
1962 #endif
1963 
1964 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1965  /// Extract a node.
1966  node_type
1968  {
1969  __glibcxx_assert(__pos != end());
1970  return _M_h.extract(__pos);
1971  }
1972 
1973  /// Extract a node.
1974  node_type
1975  extract(const key_type& __key)
1976  { return _M_h.extract(__key); }
1977 
1978 #ifdef __glibcxx_associative_heterogeneous_erasure // C++23
1979  template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1980  node_type
1981  extract(_Kt&& __key)
1982  { return _M_h._M_extract_tr(__key); }
1983 #endif
1984 
1985  /// Re-insert an extracted node.
1986  iterator
1987  insert(node_type&& __nh)
1988  { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
1989 
1990  /// Re-insert an extracted node.
1991  iterator
1992  insert(const_iterator __hint, node_type&& __nh)
1993  { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
1994 #endif // node_extract
1995 
1996  ///@{
1997  /**
1998  * @brief Erases an element from an %unordered_multimap.
1999  * @param __position An iterator pointing to the element to be erased.
2000  * @return An iterator pointing to the element immediately following
2001  * @a __position prior to the element being erased. If no such
2002  * element exists, end() is returned.
2003  *
2004  * This function erases an element, pointed to by the given iterator,
2005  * from an %unordered_multimap.
2006  * Note that this function only erases the element, and that if the
2007  * element is itself a pointer, the pointed-to memory is not touched in
2008  * any way. Managing the pointer is the user's responsibility.
2009  */
2010  iterator
2011  erase(const_iterator __position)
2012  { return _M_h.erase(__position); }
2013 
2014  // LWG 2059.
2015  iterator
2016  erase(iterator __position)
2017  { return _M_h.erase(__position); }
2018  ///@}
2019 
2020  ///@{
2021  /**
2022  * @brief Erases elements according to the provided key.
2023  * @param __x Key of elements to be erased.
2024  * @return The number of elements erased.
2025  *
2026  * This function erases all the elements located by the given key from
2027  * an %unordered_multimap.
2028  * Note that this function only erases the element, and that if the
2029  * element is itself a pointer, the pointed-to memory is not touched in
2030  * any way. Managing the pointer is the user's responsibility.
2031  */
2032  size_type
2033  erase(const key_type& __x)
2034  { return _M_h.erase(__x); }
2035 
2036 #ifdef __glibcxx_associative_heterogeneous_erasure // C++23
2037  template <__heterogeneous_hash_key<unordered_multimap> _Kt>
2038  size_type
2039  erase(_Kt&& __x)
2040  { return _M_h._M_erase_tr(__x); }
2041 #endif
2042  ///@}
2043 
2044 
2045  /**
2046  * @brief Erases a [__first,__last) range of elements from an
2047  * %unordered_multimap.
2048  * @param __first Iterator pointing to the start of the range to be
2049  * erased.
2050  * @param __last Iterator pointing to the end of the range to
2051  * be erased.
2052  * @return The iterator @a __last.
2053  *
2054  * This function erases a sequence of elements from an
2055  * %unordered_multimap.
2056  * Note that this function only erases the elements, and that if
2057  * the element is itself a pointer, the pointed-to memory is not touched
2058  * in any way. Managing the pointer is the user's responsibility.
2059  */
2060  iterator
2062  { return _M_h.erase(__first, __last); }
2063 
2064  /**
2065  * Erases all elements in an %unordered_multimap.
2066  * Note that this function only erases the elements, and that if the
2067  * elements themselves are pointers, the pointed-to memory is not touched
2068  * in any way. Managing the pointer is the user's responsibility.
2069  */
2070  void
2071  clear() noexcept
2072  { _M_h.clear(); }
2073 
2074  /**
2075  * @brief Swaps data with another %unordered_multimap.
2076  * @param __x An %unordered_multimap of the same element and allocator
2077  * types.
2078  *
2079  * This exchanges the elements between two %unordered_multimap in
2080  * constant time.
2081  * Note that the global std::swap() function is specialized such that
2082  * std::swap(m1,m2) will feed to this function.
2083  */
2084  void
2086  noexcept( noexcept(_M_h.swap(__x._M_h)) )
2087  { _M_h.swap(__x._M_h); }
2088 
2089 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
2090  template<typename, typename, typename>
2091  friend class std::_Hash_merge_helper;
2092 
2093  template<typename _H2, typename _P2>
2094  void
2096  {
2097  if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
2098  if (std::__addressof(__source) == this) [[__unlikely__]]
2099  return;
2100 
2101  using _Merge_helper
2102  = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
2103  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
2104  }
2105 
2106  template<typename _H2, typename _P2>
2107  void
2108  merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
2109  {
2110  using _Merge_helper
2111  = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
2112  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
2113  }
2114 
2115  template<typename _H2, typename _P2>
2116  void
2117  merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
2118  {
2119  using _Merge_helper
2120  = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
2121  _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
2122  }
2123 
2124  template<typename _H2, typename _P2>
2125  void
2126  merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
2127  { merge(__source); }
2128 #endif // node_extract
2129 
2130  // observers.
2131 
2132  /// Returns the hash functor object with which the %unordered_multimap
2133  /// was constructed.
2134  hasher
2136  { return _M_h.hash_function(); }
2137 
2138  /// Returns the key comparison object with which the %unordered_multimap
2139  /// was constructed.
2140  key_equal
2141  key_eq() const
2142  { return _M_h.key_eq(); }
2143 
2144  // lookup.
2145 
2146  ///@{
2147  /**
2148  * @brief Tries to locate an element in an %unordered_multimap.
2149  * @param __x Key to be located.
2150  * @return Iterator pointing to sought-after element, or end() if not
2151  * found.
2152  *
2153  * This function takes a key and tries to locate the element with which
2154  * the key matches. If successful the function returns an iterator
2155  * pointing to the sought after element. If unsuccessful it returns the
2156  * past-the-end ( @c end() ) iterator.
2157  */
2158  iterator
2159  find(const key_type& __x)
2160  { return _M_h.find(__x); }
2161 
2162 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2163  template<typename _Kt>
2164  auto
2165  find(const _Kt& __x) -> decltype(_M_h._M_find_tr(__x))
2166  { return _M_h._M_find_tr(__x); }
2167 #endif
2168 
2170  find(const key_type& __x) const
2171  { return _M_h.find(__x); }
2172 
2173 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2174  template<typename _Kt>
2175  auto
2176  find(const _Kt& __x) const -> decltype(_M_h._M_find_tr(__x))
2177  { return _M_h._M_find_tr(__x); }
2178 #endif
2179  ///@}
2180 
2181  ///@{
2182  /**
2183  * @brief Finds the number of elements.
2184  * @param __x Key to count.
2185  * @return Number of elements with specified key.
2186  */
2187  size_type
2188  count(const key_type& __x) const
2189  { return _M_h.count(__x); }
2190 
2191 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2192  template<typename _Kt>
2193  auto
2194  count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
2195  { return _M_h._M_count_tr(__x); }
2196 #endif
2197  ///@}
2198 
2199 #if __cplusplus > 201703L
2200  ///@{
2201  /**
2202  * @brief Finds whether an element with the given key exists.
2203  * @param __x Key of elements to be located.
2204  * @return True if there is any element with the specified key.
2205  */
2206  bool
2207  contains(const key_type& __x) const
2208  { return _M_h.find(__x) != _M_h.end(); }
2209 
2210  template<typename _Kt>
2211  auto
2212  contains(const _Kt& __x) const
2213  -> decltype(_M_h._M_find_tr(__x), void(), true)
2214  { return _M_h._M_find_tr(__x) != _M_h.end(); }
2215  ///@}
2216 #endif
2217 
2218  ///@{
2219  /**
2220  * @brief Finds a subsequence matching given key.
2221  * @param __x Key to be located.
2222  * @return Pair of iterators that possibly points to the subsequence
2223  * matching given key.
2224  */
2226  equal_range(const key_type& __x)
2227  { return _M_h.equal_range(__x); }
2228 
2229 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2230  template<typename _Kt>
2231  auto
2232  equal_range(const _Kt& __x)
2233  -> decltype(_M_h._M_equal_range_tr(__x))
2234  { return _M_h._M_equal_range_tr(__x); }
2235 #endif
2236 
2238  equal_range(const key_type& __x) const
2239  { return _M_h.equal_range(__x); }
2240 
2241 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2242  template<typename _Kt>
2243  auto
2244  equal_range(const _Kt& __x) const
2245  -> decltype(_M_h._M_equal_range_tr(__x))
2246  { return _M_h._M_equal_range_tr(__x); }
2247 #endif
2248  ///@}
2249 
2250  // bucket interface.
2251 
2252  /// Returns the number of buckets of the %unordered_multimap.
2253  size_type
2254  bucket_count() const noexcept
2255  { return _M_h.bucket_count(); }
2256 
2257  /// Returns the maximum number of buckets of the %unordered_multimap.
2258  size_type
2259  max_bucket_count() const noexcept
2260  { return _M_h.max_bucket_count(); }
2261 
2262  /*
2263  * @brief Returns the number of elements in a given bucket.
2264  * @param __n A bucket index.
2265  * @return The number of elements in the bucket.
2266  */
2267  size_type
2268  bucket_size(size_type __n) const
2269  { return _M_h.bucket_size(__n); }
2270 
2271  ///@{
2272  /*
2273  * @brief Returns the bucket index of a given element.
2274  * @param __key A key instance.
2275  * @return The key bucket index.
2276  */
2277  size_type
2278  bucket(const key_type& __key) const
2279  { return _M_h.bucket(__key); }
2280 
2281 #ifdef __glibcxx_associative_heterogeneous_insertion // C++26
2282  template <__heterogeneous_hash_key<unordered_multimap> _Kt>
2283  size_type
2284  bucket(const _Kt& __key) const
2285  { return _M_h._M_bucket_tr(__key); }
2286 #endif
2287  ///@}
2288 
2289  /**
2290  * @brief Returns a read/write iterator pointing to the first bucket
2291  * element.
2292  * @param __n The bucket index.
2293  * @return A read/write local iterator.
2294  */
2297  { return _M_h.begin(__n); }
2298 
2299  ///@{
2300  /**
2301  * @brief Returns a read-only (constant) iterator pointing to the first
2302  * bucket element.
2303  * @param __n The bucket index.
2304  * @return A read-only local iterator.
2305  */
2307  begin(size_type __n) const
2308  { return _M_h.begin(__n); }
2309 
2311  cbegin(size_type __n) const
2312  { return _M_h.cbegin(__n); }
2313  ///@}
2314 
2315  /**
2316  * @brief Returns a read/write iterator pointing to one past the last
2317  * bucket elements.
2318  * @param __n The bucket index.
2319  * @return A read/write local iterator.
2320  */
2323  { return _M_h.end(__n); }
2324 
2325  ///@{
2326  /**
2327  * @brief Returns a read-only (constant) iterator pointing to one past
2328  * the last bucket elements.
2329  * @param __n The bucket index.
2330  * @return A read-only local iterator.
2331  */
2333  end(size_type __n) const
2334  { return _M_h.end(__n); }
2335 
2337  cend(size_type __n) const
2338  { return _M_h.cend(__n); }
2339  ///@}
2340 
2341  // hash policy.
2342 
2343  /// Returns the average number of elements per bucket.
2344  float
2345  load_factor() const noexcept
2346  { return _M_h.load_factor(); }
2347 
2348  /// Returns a positive number that the %unordered_multimap tries to keep
2349  /// the load factor less than or equal to.
2350  float
2351  max_load_factor() const noexcept
2352  { return _M_h.max_load_factor(); }
2353 
2354  /**
2355  * @brief Change the %unordered_multimap maximum load factor.
2356  * @param __z The new maximum load factor.
2357  */
2358  void
2359  max_load_factor(float __z)
2360  { _M_h.max_load_factor(__z); }
2361 
2362  /**
2363  * @brief May rehash the %unordered_multimap.
2364  * @param __n The new number of buckets.
2365  *
2366  * Rehash will occur only if the new number of buckets respect the
2367  * %unordered_multimap maximum load factor.
2368  */
2369  void
2371  { _M_h.rehash(__n); }
2372 
2373  /**
2374  * @brief Prepare the %unordered_multimap for a specified number of
2375  * elements.
2376  * @param __n Number of elements required.
2377  *
2378  * Same as rehash(ceil(n / max_load_factor())).
2379  */
2380  void
2382  { _M_h.reserve(__n); }
2383 
2384  template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
2385  typename _Alloc1>
2386  friend bool
2387  operator==(const unordered_multimap<_Key1, _Tp1,
2388  _Hash1, _Pred1, _Alloc1>&,
2389  const unordered_multimap<_Key1, _Tp1,
2390  _Hash1, _Pred1, _Alloc1>&);
2391  };
2392 
2393 #if __cpp_deduction_guides >= 201606
2394 
2395  template<typename _InputIterator,
2396  typename _Hash = hash<__iter_key_t<_InputIterator>>,
2397  typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
2398  typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
2399  typename = _RequireInputIter<_InputIterator>,
2400  typename = _RequireNotAllocatorOrIntegral<_Hash>,
2401  typename = _RequireNotAllocator<_Pred>,
2402  typename = _RequireAllocator<_Allocator>>
2403  unordered_multimap(_InputIterator, _InputIterator,
2405  _Hash = _Hash(), _Pred = _Pred(),
2406  _Allocator = _Allocator())
2407  -> unordered_multimap<__iter_key_t<_InputIterator>,
2408  __iter_val_t<_InputIterator>, _Hash, _Pred,
2409  _Allocator>;
2410 
2411  template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
2412  typename _Pred = equal_to<_Key>,
2413  typename _Allocator = allocator<pair<const _Key, _Tp>>,
2414  typename = _RequireNotAllocatorOrIntegral<_Hash>,
2415  typename = _RequireNotAllocator<_Pred>,
2416  typename = _RequireAllocator<_Allocator>>
2417  unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2419  _Hash = _Hash(), _Pred = _Pred(),
2420  _Allocator = _Allocator())
2421  -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
2422 
2423  template<typename _InputIterator, typename _Allocator,
2424  typename = _RequireInputIter<_InputIterator>,
2425  typename = _RequireAllocator<_Allocator>>
2426  unordered_multimap(_InputIterator, _InputIterator,
2428  -> unordered_multimap<__iter_key_t<_InputIterator>,
2429  __iter_val_t<_InputIterator>,
2430  hash<__iter_key_t<_InputIterator>>,
2431  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
2432 
2433  template<typename _InputIterator, typename _Allocator,
2434  typename = _RequireInputIter<_InputIterator>,
2435  typename = _RequireAllocator<_Allocator>>
2436  unordered_multimap(_InputIterator, _InputIterator, _Allocator)
2437  -> unordered_multimap<__iter_key_t<_InputIterator>,
2438  __iter_val_t<_InputIterator>,
2439  hash<__iter_key_t<_InputIterator>>,
2440  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
2441 
2442  template<typename _InputIterator, typename _Hash, typename _Allocator,
2443  typename = _RequireInputIter<_InputIterator>,
2444  typename = _RequireNotAllocatorOrIntegral<_Hash>,
2445  typename = _RequireAllocator<_Allocator>>
2446  unordered_multimap(_InputIterator, _InputIterator,
2448  _Allocator)
2449  -> unordered_multimap<__iter_key_t<_InputIterator>,
2450  __iter_val_t<_InputIterator>, _Hash,
2451  equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
2452 
2453  template<typename _Key, typename _Tp, typename _Allocator,
2454  typename = _RequireAllocator<_Allocator>>
2455  unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2457  _Allocator)
2458  -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
2459 
2460  template<typename _Key, typename _Tp, typename _Allocator,
2461  typename = _RequireAllocator<_Allocator>>
2462  unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
2463  -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
2464 
2465  template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
2466  typename = _RequireNotAllocatorOrIntegral<_Hash>,
2467  typename = _RequireAllocator<_Allocator>>
2468  unordered_multimap(initializer_list<pair<_Key, _Tp>>,
2470  _Hash, _Allocator)
2471  -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
2472 
2473 #if __glibcxx_containers_ranges // C++ >= 23
2474  template<ranges::input_range _Rg,
2475  __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
2476  __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
2477  __allocator_like _Allocator =
2478  allocator<__detail::__range_to_alloc_type<_Rg>>>
2479  unordered_multimap(from_range_t, _Rg&&,
2481  _Hash = _Hash(), _Pred = _Pred(),
2482  _Allocator = _Allocator())
2483  -> unordered_multimap<__detail::__range_key_type<_Rg>,
2484  __detail::__range_mapped_type<_Rg>,
2485  _Hash, _Pred, _Allocator>;
2486 
2487  template<ranges::input_range _Rg,
2488  __allocator_like _Allocator>
2489  unordered_multimap(from_range_t, _Rg&&, unordered_multimap<int, int>::size_type,
2490  _Allocator)
2491  -> unordered_multimap<__detail::__range_key_type<_Rg>,
2492  __detail::__range_mapped_type<_Rg>,
2493  hash<__detail::__range_key_type<_Rg>>,
2494  equal_to<__detail::__range_key_type<_Rg>>,
2495  _Allocator>;
2496 
2497  template<ranges::input_range _Rg,
2498  __allocator_like _Allocator>
2499  unordered_multimap(from_range_t, _Rg&&, _Allocator)
2500  -> unordered_multimap<__detail::__range_key_type<_Rg>,
2501  __detail::__range_mapped_type<_Rg>,
2502  hash<__detail::__range_key_type<_Rg>>,
2503  equal_to<__detail::__range_key_type<_Rg>>,
2504  _Allocator>;
2505 
2506  template<ranges::input_range _Rg,
2507  __not_allocator_like _Hash,
2508  __allocator_like _Allocator>
2509  unordered_multimap(from_range_t, _Rg&&,
2511  _Hash, _Allocator)
2512  -> unordered_multimap<__detail::__range_key_type<_Rg>,
2513  __detail::__range_mapped_type<_Rg>,
2514  _Hash, equal_to<__detail::__range_key_type<_Rg>>,
2515  _Allocator>;
2516 #endif
2517 #endif
2518 
2519  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2520  inline void
2521  swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2522  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2523  noexcept(noexcept(__x.swap(__y)))
2524  { __x.swap(__y); }
2525 
2526  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2527  inline void
2528  swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2529  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2530  noexcept(noexcept(__x.swap(__y)))
2531  { __x.swap(__y); }
2532 
2533  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2534  inline bool
2535  operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2536  const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2537  { return __x._M_h._M_equal(__y._M_h); }
2538 
2539 #if __cpp_impl_three_way_comparison < 201907L
2540  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2541  inline bool
2542  operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2543  const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2544  { return !(__x == __y); }
2545 #endif
2546 
2547  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2548  inline bool
2549  operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2550  const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2551  { return __x._M_h._M_equal(__y._M_h); }
2552 
2553 #if __cpp_impl_three_way_comparison < 201907L
2554  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2555  inline bool
2556  operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
2557  const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
2558  { return !(__x == __y); }
2559 #endif
2560 
2561 _GLIBCXX_END_NAMESPACE_CONTAINER
2562 
2563 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
2564  // Allow std::unordered_map access to internals of compatible maps.
2565  template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
2566  typename _Alloc, typename _Hash2, typename _Eq2>
2567  struct _Hash_merge_helper<
2568  _GLIBCXX_STD_C::unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>,
2569  _Hash2, _Eq2>
2570  {
2571  private:
2572  template<typename... _Tp>
2573  using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
2574  template<typename... _Tp>
2575  using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
2576 
2577  friend unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>;
2578 
2579  static auto&
2580  _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2581  { return __map._M_h; }
2582 
2583  static auto&
2584  _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2585  { return __map._M_h; }
2586  };
2587 
2588  // Allow std::unordered_multimap access to internals of compatible maps.
2589  template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
2590  typename _Alloc, typename _Hash2, typename _Eq2>
2591  struct _Hash_merge_helper<
2592  _GLIBCXX_STD_C::unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>,
2593  _Hash2, _Eq2>
2594  {
2595  private:
2596  template<typename... _Tp>
2597  using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
2598  template<typename... _Tp>
2599  using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
2600 
2601  friend unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>;
2602 
2603  static auto&
2604  _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2605  { return __map._M_h; }
2606 
2607  static auto&
2608  _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2609  { return __map._M_h; }
2610  };
2611 #endif // node_extract
2612 
2613 _GLIBCXX_END_NAMESPACE_VERSION
2614 } // namespace std
2615 
2616 #endif /* _UNORDERED_MAP_H */
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:52
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
ISO C++ entities toplevel namespace is std.
__detail::_Hashtable_traits< _Cache, false, false > __ummap_traits
Base types for unordered_multimap.
Definition: unordered_map.h:65
__detail::_Hashtable_traits< _Cache, false, true > __umap_traits
Base types for unordered_map.
Definition: unordered_map.h:48
initializer_list
Primary class template hash.
The standard allocator, as per C++03 [20.4.1].
Definition: allocator.h:134
One of the comparison functors.
Definition: stl_function.h:374
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:304
Common iterator class.
A standard container composed of equivalent keys (possibly containing multiple of each key value) tha...
float load_factor() const noexcept
Returns the average number of elements per bucket.
unordered_multimap & operator=(const unordered_multimap &)=default
Copy assignment operator.
_Hashtable::reference reference
Iterator-related typedefs.
iterator erase(iterator __position)
Erases an element from an unordered_multimap.
const_iterator end() const noexcept
size_type erase(const key_type &__x)
Erases elements according to the provided key.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_multimap.
_Hashtable::iterator iterator
Iterator-related typedefs.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_multimap.
unordered_multimap & operator=(initializer_list< value_type > __l)
Unordered_multimap list assignment operator.
iterator begin() noexcept
const_iterator begin() const noexcept
hasher hash_function() const
Returns the hash functor object with which the unordered_multimap was constructed.
iterator insert(const_iterator __hint, node_type &&__nh)
Re-insert an extracted node.
key_equal key_eq() const
Returns the key comparison object with which the unordered_multimap was constructed.
size_type count(const key_type &__x) const
Finds the number of elements.
const_iterator find(const key_type &__x) const
Tries to locate an element in an unordered_multimap.
_Hashtable::mapped_type mapped_type
Public typedefs.
auto find(const _Kt &__x) -> decltype(_M_h._M_find_tr(__x))
Tries to locate an element in an unordered_multimap.
local_iterator end(size_type __n)
Returns a read/write iterator pointing to one past the last bucket elements.
void insert(_InputIterator __first, _InputIterator __last)
A template function that attempts to insert a range of elements.
unordered_multimap(size_type __n, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Default constructor creates no elements.
_Hashtable::value_type value_type
Public typedefs.
iterator emplace(_Args &&... __args)
Attempts to build and insert a std::pair into the unordered_multimap.
node_type extract(const key_type &__key)
Extract a node.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
_Hashtable::const_reference const_reference
Iterator-related typedefs.
iterator insert(node_type &&__nh)
Re-insert an extracted node.
iterator erase(const_iterator __position)
Erases an element from an unordered_multimap.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
iterator end() noexcept
local_iterator begin(size_type __n)
Returns a read/write iterator pointing to the first bucket element.
float max_load_factor() const noexcept
Returns a positive number that the unordered_multimap tries to keep the load factor less than or equa...
unordered_multimap()=default
Default constructor.
iterator insert(value_type &&__x)
Inserts a std::pair into the unordered_multimap.
iterator insert(const value_type &__x)
Inserts a std::pair into the unordered_multimap.
_Hashtable::hasher hasher
Public typedefs.
_Hashtable::local_iterator local_iterator
Iterator-related typedefs.
void reserve(size_type __n)
Prepare the unordered_multimap for a specified number of elements.
unordered_multimap(_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_multimap from a range.
iterator find(const key_type &__x)
Tries to locate an element in an unordered_multimap.
unordered_multimap(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_multimap from an initializer_list.
auto count(const _Kt &__x) const -> decltype(_M_h._M_count_tr(__x))
Finds the number of elements.
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_multimap.
const_local_iterator end(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
_Hashtable::pointer pointer
Iterator-related typedefs.
_Hashtable::allocator_type allocator_type
Public typedefs.
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
auto find(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x))
Tries to locate an element in an unordered_multimap.
_Hashtable::const_local_iterator const_local_iterator
Iterator-related typedefs.
unordered_multimap(unordered_multimap &&)=default
Move constructor.
unordered_multimap(const allocator_type &__a)
Creates an unordered_multimap with no elements.
_Hashtable::difference_type difference_type
Iterator-related typedefs.
_Hashtable::size_type size_type
Iterator-related typedefs.
_Hashtable::const_pointer const_pointer
Iterator-related typedefs.
auto contains(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x), void(), true)
Finds whether an element with the given key exists.
void swap(unordered_multimap &__x) noexcept(noexcept(_M_h.swap(__x._M_h)))
Swaps data with another unordered_multimap.
void rehash(size_type __n)
May rehash the unordered_multimap.
_Hashtable::const_iterator const_iterator
Iterator-related typedefs.
unordered_multimap & operator=(unordered_multimap &&)=default
Move assignment operator.
void insert(initializer_list< value_type > __l)
Attempts to insert a list of elements into the unordered_multimap.
const_iterator cend() const noexcept
size_type max_size() const noexcept
Returns the maximum size of the unordered_multimap.
const_local_iterator cbegin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
bool empty() const noexcept
Returns true if the unordered_multimap is empty.
__enable_if_t< is_constructible< value_type, _Pair && >::value, iterator > insert(_Pair &&__x)
Inserts a std::pair into the unordered_multimap.
const_iterator cbegin() const noexcept
_Hashtable::key_type key_type
Public typedefs.
node_type extract(const_iterator __pos)
Extract a node.
const_local_iterator cend(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
iterator insert(const_iterator __hint, const value_type &__x)
Inserts a std::pair into the unordered_multimap.
size_type size() const noexcept
Returns the size of the unordered_multimap.
unordered_multimap(const unordered_multimap &)=default
Copy constructor.
__enable_if_t< is_constructible< value_type, _Pair && >::value, iterator > insert(const_iterator __hint, _Pair &&__x)
Inserts a std::pair into the unordered_multimap.
iterator emplace_hint(const_iterator __pos, _Args &&... __args)
Attempts to build and insert a std::pair into the unordered_multimap.
iterator insert(const_iterator __hint, value_type &&__x)
Inserts a std::pair into the unordered_multimap.
auto equal_range(const _Kt &__x) -> decltype(_M_h._M_equal_range_tr(__x))
Finds a subsequence matching given key.
_Hashtable::key_equal key_equal
Public typedefs.
allocator_type get_allocator() const noexcept
Returns the allocator object used by the unordered_multimap.
void max_load_factor(float __z)
Change the unordered_multimap maximum load factor.
auto equal_range(const _Kt &__x) const -> decltype(_M_h._M_equal_range_tr(__x))
Finds a subsequence matching given key.
A standard container composed of unique keys (containing at most one of each key value) that associat...
iterator insert(const_iterator __hint, value_type &&__x)
Attempts to insert a std::pair into the unordered_map.
std::pair< iterator, bool > insert(const value_type &__x)
Attempts to insert a std::pair into the unordered_map.
_Hashtable::iterator iterator
Iterator-related typedefs.
void max_load_factor(float __z)
Change the unordered_map maximum load factor.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
node_type extract(const key_type &__key)
Extract a node.
void insert(_InputIterator __first, _InputIterator __last)
A template function that attempts to insert a range of elements.
allocator_type get_allocator() const noexcept
Returns the allocator object used by the unordered_map.
auto find(const _Kt &__x) -> decltype(_M_h._M_find_tr(__x))
Tries to locate an element in an unordered_map.
_Hashtable::const_pointer const_pointer
Iterator-related typedefs.
auto find(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x))
Tries to locate an element in an unordered_map.
pair< iterator, bool > insert_or_assign(const key_type &__k, _Obj &&__obj)
Attempts to insert a std::pair into the unordered_map.
void insert(initializer_list< value_type > __l)
Attempts to insert a list of elements into the unordered_map.
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_map.
const mapped_type & at(const key_type &__k) const
Access to unordered_map data.
mapped_type & operator[](key_type &&__k)
Subscript ( [] ) access to unordered_map data.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
iterator try_emplace(const_iterator __hint, const key_type &__k, _Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
node_type extract(const_iterator __pos)
Extract a node.
mapped_type & operator[](const key_type &__k)
Subscript ( [] ) access to unordered_map data.
void reserve(size_type __n)
Prepare the unordered_map for a specified number of elements.
std::pair< iterator, iterator > equal_range(const key_type &__x)
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.
pair< iterator, bool > insert_or_assign(key_type &&__k, _Obj &&__obj)
Attempts to insert a std::pair into the unordered_map.
iterator insert(const_iterator, node_type &&__nh)
Re-insert an extracted node.
_Hashtable::reference reference
Iterator-related typedefs.
iterator insert(const_iterator __hint, const value_type &__x)
Attempts to insert a std::pair into the unordered_map.
iterator end() noexcept
_Hashtable::allocator_type allocator_type
Public typedefs.
pair< iterator, bool > try_emplace(const key_type &__k, _Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
unordered_map & operator=(initializer_list< value_type > __l)
Unordered_map list assignment operator.
unordered_map(const unordered_map &)=default
Copy constructor.
size_type count(const key_type &__x) const
Finds the number of elements.
bool empty() const noexcept
Returns true if the unordered_map is empty.
size_type erase(const key_type &__x)
Erases elements according to the provided key.
iterator insert_or_assign(const_iterator __hint, key_type &&__k, _Obj &&__obj)
Attempts to insert a std::pair into the unordered_map.
const_iterator find(const key_type &__x) const
Tries to locate an element in an unordered_map.
unordered_map(unordered_map &&)=default
Move constructor.
const_local_iterator end(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
iterator try_emplace(const_iterator __hint, key_type &&__k, _Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
auto equal_range(const _Kt &__x) -> decltype(_M_h._M_equal_range_tr(__x))
Finds a subsequence matching given key.
auto contains(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x), void(), true)
Finds whether an element with the given key exists.
size_type max_size() const noexcept
Returns the maximum size of the unordered_map.
const_iterator end() const noexcept
unordered_map()=default
Default constructor.
_Hashtable::mapped_type mapped_type
Public typedefs.
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_map(size_type __n, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Default constructor creates no elements.
const_local_iterator cend(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
size_type size() const noexcept
Returns the size of the unordered_map.
unordered_map & operator=(unordered_map &&)=default
Move assignment operator.
mapped_type & at(const key_type &__k)
Access to unordered_map data.
_Hashtable::hasher hasher
Public typedefs.
unordered_map(_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_map from a range.
void clear() noexcept
const_iterator begin() const noexcept
std::pair< iterator, bool > emplace(_Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
key_equal key_eq() const
Returns the key comparison object with which the unordered_map was constructed.
_Hashtable::const_reference const_reference
Iterator-related typedefs.
_Hashtable::key_equal key_equal
Public typedefs.
_Hashtable::local_iterator local_iterator
Iterator-related typedefs.
__enable_if_t< is_constructible< value_type, _Pair && >::value, pair< iterator, bool > > insert(_Pair &&__x)
Attempts to insert a std::pair into the unordered_map.
iterator erase(iterator __position)
Erases an element from an unordered_map.
const_iterator cend() const noexcept
local_iterator end(size_type __n)
Returns a read/write iterator pointing to one past the last bucket elements.
_Hashtable::pointer pointer
Iterator-related typedefs.
iterator insert_or_assign(const_iterator __hint, const key_type &__k, _Obj &&__obj)
Attempts to insert a std::pair into the unordered_map.
unordered_map(const allocator_type &__a)
Creates an unordered_map with no elements.
_Hashtable::key_type key_type
Public typedefs.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_map.
iterator begin() noexcept
hasher hash_function() const
Returns the hash functor object with which the unordered_map was constructed.
unordered_map & operator=(const unordered_map &)=default
Copy assignment operator.
auto equal_range(const _Kt &__x) const -> decltype(_M_h._M_equal_range_tr(__x))
Finds a subsequence matching given key.
unordered_map(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_map from an initializer_list.
_Hashtable::const_iterator const_iterator
Iterator-related typedefs.
_Hashtable::size_type size_type
Iterator-related typedefs.
iterator find(const key_type &__x)
Tries to locate an element in an unordered_map.
std::pair< iterator, bool > insert(value_type &&__x)
Attempts to insert a std::pair into the unordered_map.
float load_factor() const noexcept
Returns the average number of elements per bucket.
iterator erase(const_iterator __position)
Erases an element from an unordered_map.
void swap(unordered_map &__x) noexcept(noexcept(_M_h.swap(__x._M_h)))
Swaps data with another unordered_map.
local_iterator begin(size_type __n)
Returns a read/write iterator pointing to the first bucket element.
float max_load_factor() const noexcept
Returns a positive number that the unordered_map tries to keep the load factor less than or equal to.
__enable_if_t< is_constructible< value_type, _Pair && >::value, iterator > insert(const_iterator __hint, _Pair &&__x)
Attempts to insert a std::pair into the unordered_map.
_Hashtable::difference_type difference_type
Iterator-related typedefs.
auto count(const _Kt &__x) const -> decltype(_M_h._M_count_tr(__x))
Finds the number of elements.
_Hashtable::const_local_iterator const_local_iterator
Iterator-related typedefs.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_map.
iterator emplace_hint(const_iterator __pos, _Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
pair< iterator, bool > try_emplace(key_type &&__k, _Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
insert_return_type insert(node_type &&__nh)
Re-insert an extracted node.
_Hashtable::value_type value_type
Public typedefs.
void rehash(size_type __n)
May rehash the unordered_map.
const_iterator cbegin() const noexcept