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
41namespace 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>
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.
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.
365 allocator_type
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.
378 size() const noexcept
379 { return _M_h.size(); }
380
381 /// Returns the maximum size of the %unordered_map.
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 */
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 */
401 const_iterator
402 begin() const noexcept
403 { return _M_h.begin(); }
404
405 const_iterator
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 */
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 */
423 const_iterator
424 end() const noexcept
425 { return _M_h.end(); }
426
427 const_iterator
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 * @brief Attempts to build and insert a std::pair into the
461 * %unordered_map.
462 *
463 * @param __pos An iterator that serves as a hint as to where the pair
464 * should be inserted.
465 * @param __args Arguments used to generate a new pair instance (see
466 * std::piecewise_contruct for passing arguments to each
467 * part of the pair constructor).
468 * @return An iterator that points to the element with key of the
469 * std::pair built from @a __args (may or may not be that
470 * std::pair).
471 *
472 * This function is not concerned about whether the insertion took place,
473 * and thus does not return a boolean like the single-argument emplace()
474 * does.
475 * Note that the first parameter is only a hint and can potentially
476 * improve the performance of the insertion process. A bad hint would
477 * cause no gains in efficiency.
478 *
479 * See
480 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
481 * for more on @a hinting.
482 *
483 * Insertion requires amortized constant time.
484 */
485 template<typename... _Args>
487 emplace_hint(const_iterator __pos, _Args&&... __args)
488 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
489
490#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
491 /// Extract a node.
492 node_type
493 extract(const_iterator __pos)
494 {
495 __glibcxx_assert(__pos != end());
496 return _M_h.extract(__pos);
497 }
498
499 /// Extract a node.
500 node_type
501 extract(const key_type& __key)
502 { return _M_h.extract(__key); }
503
504#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
505 template <__heterogeneous_hash_key<unordered_map> _Kt>
506 node_type
507 extract(_Kt&& __key)
508 { return _M_h._M_extract_tr(__key); }
509#endif
510
511 /// Re-insert an extracted node.
512 insert_return_type
513 insert(node_type&& __nh)
514 { return _M_h._M_reinsert_node(std::move(__nh)); }
515
516 /// Re-insert an extracted node.
518 insert(const_iterator, node_type&& __nh)
519 { return _M_h._M_reinsert_node(std::move(__nh)).position; }
520#endif // node_extract
521
522#ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED
523 /**
524 * @brief Attempts to build and insert a std::pair into the
525 * %unordered_map.
526 *
527 * @param __k Key to use for finding a possibly existing pair in
528 * the unordered_map.
529 * @param __args Arguments used to generate the .second for a
530 * new pair instance.
531 *
532 * @return A pair, of which the first element is an iterator that points
533 * to the possibly inserted pair, and the second is a bool that
534 * is true if the pair was actually inserted.
535 *
536 * This function attempts to build and insert a (key, value) %pair into
537 * the %unordered_map.
538 * An %unordered_map relies on unique keys and thus a %pair is only
539 * inserted if its first element (the key) is not already present in the
540 * %unordered_map.
541 * If a %pair is not inserted, this function has no effect.
542 *
543 * Insertion requires amortized constant time.
544 */
545 template <typename... _Args>
547 try_emplace(const key_type& __k, _Args&&... __args)
548 {
549 return _M_h.try_emplace(cend(), __k, std::forward<_Args>(__args)...);
550 }
551
552 // move-capable overload
553 template <typename... _Args>
555 try_emplace(key_type&& __k, _Args&&... __args)
556 {
557 return _M_h.try_emplace(cend(), std::move(__k),
558 std::forward<_Args>(__args)...);
559 }
560
561 /**
562 * @brief Attempts to build and insert a std::pair into the
563 * %unordered_map.
564 *
565 * @param __hint An iterator that serves as a hint as to where the pair
566 * should be inserted.
567 * @param __k Key to use for finding a possibly existing pair in
568 * the unordered_map.
569 * @param __args Arguments used to generate the .second for a
570 * new pair instance.
571 * @return An iterator that points to the element with key of the
572 * std::pair built from @a __args (may or may not be that
573 * std::pair).
574 *
575 * This function is not concerned about whether the insertion took place,
576 * and thus does not return a boolean like the single-argument emplace()
577 * does. However, if insertion did not take place,
578 * this function has no effect.
579 * Note that the first parameter is only a hint and can potentially
580 * improve the performance of the insertion process. A bad hint would
581 * cause no gains in efficiency.
582 *
583 * See
584 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
585 * for more on @a hinting.
586 *
587 * Insertion requires amortized constant time.
588 */
589 template <typename... _Args>
591 try_emplace(const_iterator __hint, const key_type& __k,
592 _Args&&... __args)
593 {
594 return _M_h.try_emplace(__hint, __k,
595 std::forward<_Args>(__args)...).first;
596 }
597
598 // move-capable overload
599 template <typename... _Args>
601 try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
602 {
603 return _M_h.try_emplace(__hint, std::move(__k),
604 std::forward<_Args>(__args)...).first;
605 }
606#endif // __glibcxx_unordered_map_try_emplace
607
608 ///@{
609 /**
610 * @brief Attempts to insert a std::pair into the %unordered_map.
611
612 * @param __x Pair to be inserted (see std::make_pair for easy
613 * creation of pairs).
614 *
615 * @return A pair, of which the first element is an iterator that
616 * points to the possibly inserted pair, and the second is
617 * a bool that is true if the pair was actually inserted.
618 *
619 * This function attempts to insert a (key, value) %pair into the
620 * %unordered_map. An %unordered_map relies on unique keys and thus a
621 * %pair is only inserted if its first element (the key) is not already
622 * present in the %unordered_map.
623 *
624 * Insertion requires amortized constant time.
625 */
627 insert(const value_type& __x)
628 { return _M_h.insert(__x); }
629
630 // _GLIBCXX_RESOLVE_LIB_DEFECTS
631 // 2354. Unnecessary copying when inserting into maps with braced-init
634 { return _M_h.insert(std::move(__x)); }
635
636 template<typename _Pair>
637 __enable_if_t<is_constructible<value_type, _Pair&&>::value,
639 insert(_Pair&& __x)
640 { return _M_h.emplace(std::forward<_Pair>(__x)); }
641 ///@}
642
643 ///@{
644 /**
645 * @brief Attempts to insert a std::pair into the %unordered_map.
646 * @param __hint An iterator that serves as a hint as to where the
647 * pair should be inserted.
648 * @param __x Pair to be inserted (see std::make_pair for easy creation
649 * of pairs).
650 * @return An iterator that points to the element with key of
651 * @a __x (may or may not be the %pair passed in).
652 *
653 * This function is not concerned about whether the insertion took place,
654 * and thus does not return a boolean like the single-argument insert()
655 * does. Note that the first parameter is only a hint and can
656 * potentially improve the performance of the insertion process. A bad
657 * hint would cause no gains in efficiency.
658 *
659 * See
660 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
661 * for more on @a hinting.
662 *
663 * Insertion requires amortized constant time.
664 */
666 insert(const_iterator __hint, const value_type& __x)
667 { return _M_h.insert(__hint, __x); }
668
669 // _GLIBCXX_RESOLVE_LIB_DEFECTS
670 // 2354. Unnecessary copying when inserting into maps with braced-init
673 { return _M_h.insert(__hint, std::move(__x)); }
674
675 template<typename _Pair>
676 __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
677 insert(const_iterator __hint, _Pair&& __x)
678 { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); }
679 ///@}
680
681 /**
682 * @brief A template function that attempts to insert a range of
683 * elements.
684 * @param __first Iterator pointing to the start of the range to be
685 * inserted.
686 * @param __last Iterator pointing to the end of the range.
687 *
688 * Complexity similar to that of the range constructor.
689 */
690 template<typename _InputIterator>
691 void
692 insert(_InputIterator __first, _InputIterator __last)
693 { _M_h.insert(__first, __last); }
694
695 /**
696 * @brief Attempts to insert a list of elements into the %unordered_map.
697 * @param __l A std::initializer_list<value_type> of elements
698 * to be inserted.
699 *
700 * Complexity similar to that of the range constructor.
701 */
702 void
704 { _M_h.insert(__l); }
705
706#if __glibcxx_containers_ranges // C++ >= 23
707 /**
708 * @brief Inserts a range of elements.
709 * @since C++23
710 * @param __rg An input range of elements that can be converted to
711 * the map's value type.
712 */
713 template<__detail::__container_compatible_range<value_type> _Rg>
714 void
715 insert_range(_Rg&& __rg)
716 {
717 auto __first = ranges::begin(__rg);
718 const auto __last = ranges::end(__rg);
719 for (; __first != __last; ++__first)
720 _M_h.emplace(*__first);
721 }
722#endif
723
724#ifdef __glibcxx_unordered_map_try_emplace // >= C++17 && HOSTED
725 /**
726 * @brief Attempts to insert a std::pair into the %unordered_map.
727 * @param __k Key to use for finding a possibly existing pair in
728 * the map.
729 * @param __obj Argument used to generate the .second for a pair
730 * instance.
731 *
732 * @return A pair, of which the first element is an iterator that
733 * points to the possibly inserted pair, and the second is
734 * a bool that is true if the pair was actually inserted.
735 *
736 * This function attempts to insert a (key, value) %pair into the
737 * %unordered_map. An %unordered_map relies on unique keys and thus a
738 * %pair is only inserted if its first element (the key) is not already
739 * present in the %unordered_map.
740 * If the %pair was already in the %unordered_map, the .second of
741 * the %pair is assigned from __obj.
742 *
743 * Insertion requires amortized constant time.
744 */
745 template <typename _Obj>
747 insert_or_assign(const key_type& __k, _Obj&& __obj)
748 {
749 auto __ret = _M_h.try_emplace(cend(), __k,
750 std::forward<_Obj>(__obj));
751 if (!__ret.second)
752 __ret.first->second = std::forward<_Obj>(__obj);
753 return __ret;
754 }
755
756 // move-capable overload
757 template <typename _Obj>
759 insert_or_assign(key_type&& __k, _Obj&& __obj)
760 {
761 auto __ret = _M_h.try_emplace(cend(), std::move(__k),
762 std::forward<_Obj>(__obj));
763 if (!__ret.second)
764 __ret.first->second = std::forward<_Obj>(__obj);
765 return __ret;
766 }
767
768 /**
769 * @brief Attempts to insert a std::pair into the %unordered_map.
770 * @param __hint An iterator that serves as a hint as to where the
771 * pair should be inserted.
772 * @param __k Key to use for finding a possibly existing pair in
773 * the unordered_map.
774 * @param __obj Argument used to generate the .second for a pair
775 * instance.
776 * @return An iterator that points to the element with key of
777 * @a __x (may or may not be the %pair passed in).
778 *
779 * This function is not concerned about whether the insertion took place,
780 * and thus does not return a boolean like the single-argument insert()
781 * does.
782 * If the %pair was already in the %unordered map, the .second of
783 * the %pair is assigned from __obj.
784 * Note that the first parameter is only a hint and can
785 * potentially improve the performance of the insertion process. A bad
786 * hint would cause no gains in efficiency.
787 *
788 * See
789 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
790 * for more on @a hinting.
791 *
792 * Insertion requires amortized constant time.
793 */
794 template <typename _Obj>
796 insert_or_assign(const_iterator __hint, const key_type& __k,
797 _Obj&& __obj)
798 {
799 auto __ret = _M_h.try_emplace(__hint, __k, std::forward<_Obj>(__obj));
800 if (!__ret.second)
801 __ret.first->second = std::forward<_Obj>(__obj);
802 return __ret.first;
803 }
804
805 // move-capable overload
806 template <typename _Obj>
808 insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
809 {
810 auto __ret = _M_h.try_emplace(__hint, std::move(__k),
811 std::forward<_Obj>(__obj));
812 if (!__ret.second)
813 __ret.first->second = std::forward<_Obj>(__obj);
814 return __ret.first;
815 }
816#endif // unordered_map_try_emplace
817
818 ///@{
819 /**
820 * @brief Erases an element from an %unordered_map.
821 * @param __position An iterator pointing to the element to be erased.
822 * @return An iterator pointing to the element immediately following
823 * @a __position prior to the element being erased. If no such
824 * element exists, end() is returned.
825 *
826 * This function erases an element, pointed to by the given iterator,
827 * from an %unordered_map.
828 * Note that this function only erases the element, and that if the
829 * element is itself a pointer, the pointed-to memory is not touched in
830 * any way. Managing the pointer is the user's responsibility.
831 */
834 { return _M_h.erase(__position); }
835
836 // LWG 2059.
838 erase(iterator __position)
839 { return _M_h.erase(__position); }
840 ///@}
841
842 /**
843 * @brief Erases elements according to the provided key.
844 * @param __x Key of element to be erased.
845 * @return The number of elements erased.
846 *
847 * This function erases all the elements located by the given key from
848 * an %unordered_map. For an %unordered_map the result of this function
849 * can only be 0 (not present) or 1 (present).
850 * Note that this function only erases the element, and that if the
851 * element is itself a pointer, the pointed-to memory is not touched in
852 * any way. Managing the pointer is the user's responsibility.
853 */
855 erase(const key_type& __x)
856 { return _M_h.erase(__x); }
857
858#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
859 template <__heterogeneous_hash_key<unordered_map> _Kt>
861 erase(_Kt&& __key)
862 { return _M_h._M_erase_tr(__key); }
863#endif
864
865 /**
866 * @brief Erases a [__first,__last) range of elements from an
867 * %unordered_map.
868 * @param __first Iterator pointing to the start of the range to be
869 * erased.
870 * @param __last Iterator pointing to the end of the range to
871 * be erased.
872 * @return The iterator @a __last.
873 *
874 * This function erases a sequence of elements from an %unordered_map.
875 * Note that this function only erases the elements, and that if
876 * the element is itself a pointer, the pointed-to memory is not touched
877 * in any way. Managing the pointer is the user's responsibility.
878 */
879 iterator
881 { return _M_h.erase(__first, __last); }
882
883 /**
884 * Erases all elements in an %unordered_map.
885 * Note that this function only erases the elements, and that if the
886 * elements themselves are pointers, the pointed-to memory is not touched
887 * in any way. Managing the pointer is the user's responsibility.
888 */
889 void
890 clear() noexcept
891 { _M_h.clear(); }
892
893 /**
894 * @brief Swaps data with another %unordered_map.
895 * @param __x An %unordered_map of the same element and allocator
896 * types.
897 *
898 * This exchanges the elements between two %unordered_map in constant
899 * time.
900 * Note that the global std::swap() function is specialized such that
901 * std::swap(m1,m2) will feed to this function.
902 */
903 void
905 noexcept( noexcept(_M_h.swap(__x._M_h)) )
906 { _M_h.swap(__x._M_h); }
907
908#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
909 template<typename, typename, typename>
910 friend class std::_Hash_merge_helper;
911
912 template<typename _H2, typename _P2>
913 void
915 {
916 if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
917 if (std::__addressof(__source) == this) [[__unlikely__]]
918 return;
919
920 using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
921 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
922 }
923
924 template<typename _H2, typename _P2>
925 void
926 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
927 {
928 using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
929 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
930 }
931
932 template<typename _H2, typename _P2>
933 void
934 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
935 {
936 using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>;
937 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
938 }
939
940 template<typename _H2, typename _P2>
941 void
942 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
943 { merge(__source); }
944#endif // node_extract
945
946 // observers.
947
948 /// Returns the hash functor object with which the %unordered_map was
949 /// constructed.
950 hasher
952 { return _M_h.hash_function(); }
953
954 /// Returns the key comparison object with which the %unordered_map was
955 /// constructed.
957 key_eq() const
958 { return _M_h.key_eq(); }
959
960 // lookup.
961
962 ///@{
963 /**
964 * @brief Tries to locate an element in an %unordered_map.
965 * @param __x Key to be located.
966 * @return Iterator pointing to sought-after element, or end() if not
967 * found.
968 *
969 * This function takes a key and tries to locate the element with which
970 * the key matches. If successful the function returns an iterator
971 * pointing to the sought after element. If unsuccessful it returns the
972 * past-the-end ( @c end() ) iterator.
973 */
975 find(const key_type& __x)
976 { return _M_h.find(__x); }
977
978#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
979 template<typename _Kt>
980 auto
981 find(const _Kt& __x) -> decltype(_M_h._M_find_tr(__x))
982 { return _M_h._M_find_tr(__x); }
983#endif
984
985 const_iterator
986 find(const key_type& __x) const
987 { return _M_h.find(__x); }
988
989#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
990 template<typename _Kt>
991 auto
992 find(const _Kt& __x) const -> decltype(_M_h._M_find_tr(__x))
993 { return _M_h._M_find_tr(__x); }
994#endif
995 ///@}
996
997 ///@{
998 /**
999 * @brief Finds the number of elements.
1000 * @param __x Key to count.
1001 * @return Number of elements with specified key.
1002 *
1003 * This function only makes sense for %unordered_multimap; for
1004 * %unordered_map the result will either be 0 (not present) or 1
1005 * (present).
1006 */
1007 size_type
1008 count(const key_type& __x) const
1009 { return _M_h.count(__x); }
1010
1011#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1012 template<typename _Kt>
1013 auto
1014 count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
1015 { return _M_h._M_count_tr(__x); }
1016#endif
1017 ///@}
1018
1019#if __cplusplus > 201703L
1020 ///@{
1021 /**
1022 * @brief Finds whether an element with the given key exists.
1023 * @param __x Key of elements to be located.
1024 * @return True if there is any element with the specified key.
1025 */
1026 bool
1027 contains(const key_type& __x) const
1028 { return _M_h.find(__x) != _M_h.end(); }
1029
1030 template<typename _Kt>
1031 auto
1032 contains(const _Kt& __x) const
1033 -> decltype(_M_h._M_find_tr(__x), void(), true)
1034 { return _M_h._M_find_tr(__x) != _M_h.end(); }
1035 ///@}
1036#endif
1037
1038 ///@{
1039 /**
1040 * @brief Finds a subsequence matching given key.
1041 * @param __x Key to be located.
1042 * @return Pair of iterators that possibly points to the subsequence
1043 * matching given key.
1044 *
1045 * This function probably only makes sense for %unordered_multimap.
1046 */
1049 { return _M_h.equal_range(__x); }
1050
1051#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1052 template<typename _Kt>
1053 auto
1054 equal_range(const _Kt& __x)
1055 -> decltype(_M_h._M_equal_range_tr(__x))
1056 { return _M_h._M_equal_range_tr(__x); }
1057#endif
1058
1060 equal_range(const key_type& __x) const
1061 { return _M_h.equal_range(__x); }
1062
1063#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1064 template<typename _Kt>
1065 auto
1066 equal_range(const _Kt& __x) const
1067 -> decltype(_M_h._M_equal_range_tr(__x))
1068 { return _M_h._M_equal_range_tr(__x); }
1069#endif
1070 ///@}
1071
1072 ///@{
1073 /**
1074 * @brief Subscript ( @c [] ) access to %unordered_map data.
1075 * @param __k The key for which data should be retrieved.
1076 * @return A reference to the data of the (key,data) %pair.
1077 *
1078 * Allows for easy lookup with the subscript ( @c [] )operator. Returns
1079 * data associated with the key specified in subscript. If the key does
1080 * not exist, a pair with that key is created using default values, which
1081 * is then returned.
1082 *
1083 * Lookup requires constant time.
1084 */
1087 { return _M_h[__k]; }
1088
1091 { return _M_h[std::move(__k)]; }
1092 ///@}
1093
1094 ///@{
1095 /**
1096 * @brief Access to %unordered_map data.
1097 * @param __k The key for which data should be retrieved.
1098 * @return A reference to the data whose key is equal to @a __k, if
1099 * such a data is present in the %unordered_map.
1100 * @throw std::out_of_range If no such data is present.
1101 */
1103 at(const key_type& __k)
1104 { return _M_h.at(__k); }
1105
1106 const mapped_type&
1107 at(const key_type& __k) const
1108 { return _M_h.at(__k); }
1109 ///@}
1110
1111 // bucket interface.
1112
1113 /// Returns the number of buckets of the %unordered_map.
1114 size_type
1115 bucket_count() const noexcept
1116 { return _M_h.bucket_count(); }
1117
1118 /// Returns the maximum number of buckets of the %unordered_map.
1119 size_type
1120 max_bucket_count() const noexcept
1121 { return _M_h.max_bucket_count(); }
1122
1123 /*
1124 * @brief Returns the number of elements in a given bucket.
1125 * @param __n A bucket index.
1126 * @return The number of elements in the bucket.
1127 */
1128 size_type
1129 bucket_size(size_type __n) const
1130 { return _M_h.bucket_size(__n); }
1131
1132 /*
1133 * @brief Returns the bucket index of a given element.
1134 * @param __key A key instance.
1135 * @return The key bucket index.
1136 */
1137 size_type
1138 bucket(const key_type& __key) const
1139 { return _M_h.bucket(__key); }
1140
1141 /**
1142 * @brief Returns a read/write iterator pointing to the first bucket
1143 * element.
1144 * @param __n The bucket index.
1145 * @return A read/write local iterator.
1146 */
1149 { return _M_h.begin(__n); }
1150
1151 ///@{
1152 /**
1153 * @brief Returns a read-only (constant) iterator pointing to the first
1154 * bucket element.
1155 * @param __n The bucket index.
1156 * @return A read-only local iterator.
1157 */
1159 begin(size_type __n) const
1160 { return _M_h.begin(__n); }
1161
1164 { return _M_h.cbegin(__n); }
1165 ///@}
1166
1167 /**
1168 * @brief Returns a read/write iterator pointing to one past the last
1169 * bucket elements.
1170 * @param __n The bucket index.
1171 * @return A read/write local iterator.
1172 */
1175 { return _M_h.end(__n); }
1176
1177 ///@{
1178 /**
1179 * @brief Returns a read-only (constant) iterator pointing to one past
1180 * the last bucket elements.
1181 * @param __n The bucket index.
1182 * @return A read-only local iterator.
1183 */
1185 end(size_type __n) const
1186 { return _M_h.end(__n); }
1187
1189 cend(size_type __n) const
1190 { return _M_h.cend(__n); }
1191 ///@}
1192
1193 // hash policy.
1194
1195 /// Returns the average number of elements per bucket.
1196 float
1197 load_factor() const noexcept
1198 { return _M_h.load_factor(); }
1199
1200 /// Returns a positive number that the %unordered_map tries to keep the
1201 /// load factor less than or equal to.
1202 float
1203 max_load_factor() const noexcept
1204 { return _M_h.max_load_factor(); }
1205
1206 /**
1207 * @brief Change the %unordered_map maximum load factor.
1208 * @param __z The new maximum load factor.
1209 */
1210 void
1212 { _M_h.max_load_factor(__z); }
1213
1214 /**
1215 * @brief May rehash the %unordered_map.
1216 * @param __n The new number of buckets.
1217 *
1218 * Rehash will occur only if the new number of buckets respect the
1219 * %unordered_map maximum load factor.
1220 */
1221 void
1223 { _M_h.rehash(__n); }
1224
1225 /**
1226 * @brief Prepare the %unordered_map for a specified number of
1227 * elements.
1228 * @param __n Number of elements required.
1229 *
1230 * Same as rehash(ceil(n / max_load_factor())).
1231 */
1232 void
1234 { _M_h.reserve(__n); }
1235
1236 template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
1237 typename _Alloc1>
1238 friend bool
1241 };
1242
1243#if __cpp_deduction_guides >= 201606
1244
1245 template<typename _InputIterator,
1246 typename _Hash = hash<__iter_key_t<_InputIterator>>,
1247 typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
1248 typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
1249 typename = _RequireInputIter<_InputIterator>,
1250 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1251 typename = _RequireNotAllocator<_Pred>,
1252 typename = _RequireAllocator<_Allocator>>
1253 unordered_map(_InputIterator, _InputIterator,
1254 typename unordered_map<int, int>::size_type = {},
1255 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1256 -> unordered_map<__iter_key_t<_InputIterator>,
1257 __iter_val_t<_InputIterator>,
1258 _Hash, _Pred, _Allocator>;
1259
1260 template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
1261 typename _Pred = equal_to<_Key>,
1262 typename _Allocator = allocator<pair<const _Key, _Tp>>,
1263 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1264 typename = _RequireNotAllocator<_Pred>,
1265 typename = _RequireAllocator<_Allocator>>
1268 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1270
1271 template<typename _InputIterator, typename _Allocator,
1272 typename = _RequireInputIter<_InputIterator>,
1273 typename = _RequireAllocator<_Allocator>>
1274 unordered_map(_InputIterator, _InputIterator,
1275 typename unordered_map<int, int>::size_type, _Allocator)
1277 __iter_val_t<_InputIterator>,
1280 _Allocator>;
1281
1282 template<typename _InputIterator, typename _Allocator,
1283 typename = _RequireInputIter<_InputIterator>,
1284 typename = _RequireAllocator<_Allocator>>
1285 unordered_map(_InputIterator, _InputIterator, _Allocator)
1287 __iter_val_t<_InputIterator>,
1290 _Allocator>;
1291
1292 template<typename _InputIterator, typename _Hash, typename _Allocator,
1293 typename = _RequireInputIter<_InputIterator>,
1294 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1295 typename = _RequireAllocator<_Allocator>>
1296 unordered_map(_InputIterator, _InputIterator,
1298 _Hash, _Allocator)
1300 __iter_val_t<_InputIterator>, _Hash,
1302
1303 template<typename _Key, typename _Tp, typename _Allocator,
1304 typename = _RequireAllocator<_Allocator>>
1307 _Allocator)
1309
1310 template<typename _Key, typename _Tp, typename _Allocator,
1311 typename = _RequireAllocator<_Allocator>>
1314
1315 template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
1316 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1317 typename = _RequireAllocator<_Allocator>>
1320 _Hash, _Allocator)
1322
1323#if __glibcxx_containers_ranges // C++ >= 23
1324 template<ranges::input_range _Rg,
1325 __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
1326 __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
1327 __allocator_like _Allocator =
1329 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type = {},
1330 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1331 -> unordered_map<__detail::__range_key_type<_Rg>,
1332 __detail::__range_mapped_type<_Rg>,
1333 _Hash, _Pred, _Allocator>;
1334
1335 template<ranges::input_range _Rg,
1336 __allocator_like _Allocator>
1338 _Allocator)
1340 __detail::__range_mapped_type<_Rg>,
1343 _Allocator>;
1344
1345 template<ranges::input_range _Rg,
1346 __allocator_like _Allocator>
1347 unordered_map(from_range_t, _Rg&&, _Allocator)
1349 __detail::__range_mapped_type<_Rg>,
1352 _Allocator>;
1353
1354 template<ranges::input_range _Rg,
1355 __not_allocator_like _Hash,
1356 __allocator_like _Allocator>
1358 _Hash, _Allocator)
1360 __detail::__range_mapped_type<_Rg>,
1362 _Allocator>;
1363#endif
1364#endif
1365
1366 /**
1367 * @brief A standard container composed of equivalent keys
1368 * (possibly containing multiple of each key value) that associates
1369 * values of another type with the keys.
1370 *
1371 * @ingroup unordered_associative_containers
1372 * @headerfile unordered_map
1373 * @since C++11
1374 *
1375 * @tparam _Key Type of key objects.
1376 * @tparam _Tp Type of mapped objects.
1377 * @tparam _Hash Hashing function object type, defaults to hash<_Key>.
1378 * @tparam _Pred Predicate function object type, defaults
1379 * to equal_to<_Key>.
1380 * @tparam _Alloc Allocator type, defaults to
1381 * std::allocator<std::pair<const _Key, _Tp>>.
1382 *
1383 * Meets the requirements of a <a href="tables.html#65">container</a>, and
1384 * <a href="tables.html#xx">unordered associative container</a>
1385 *
1386 * The resulting value type of the container is std::pair<const _Key, _Tp>.
1387 *
1388 * Base is _Hashtable, dispatched at compile time via template
1389 * alias __ummap_hashtable.
1390 */
1391 template<typename _Key, typename _Tp,
1392 typename _Hash = hash<_Key>,
1393 typename _Pred = equal_to<_Key>,
1394 typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
1396 {
1397 typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
1398 _Hashtable _M_h;
1399
1400 public:
1401 // typedefs:
1402 ///@{
1403 /// Public typedefs.
1404 typedef typename _Hashtable::key_type key_type;
1405 typedef typename _Hashtable::value_type value_type;
1406 typedef typename _Hashtable::mapped_type mapped_type;
1407 typedef typename _Hashtable::hasher hasher;
1408 typedef typename _Hashtable::key_equal key_equal;
1409 typedef typename _Hashtable::allocator_type allocator_type;
1410 ///@}
1411
1412 ///@{
1413 /// Iterator-related typedefs.
1414 typedef typename _Hashtable::pointer pointer;
1415 typedef typename _Hashtable::const_pointer const_pointer;
1416 typedef typename _Hashtable::reference reference;
1417 typedef typename _Hashtable::const_reference const_reference;
1418 typedef typename _Hashtable::iterator iterator;
1419 typedef typename _Hashtable::const_iterator const_iterator;
1420 typedef typename _Hashtable::local_iterator local_iterator;
1421 typedef typename _Hashtable::const_local_iterator const_local_iterator;
1422 typedef typename _Hashtable::size_type size_type;
1423 typedef typename _Hashtable::difference_type difference_type;
1424 ///@}
1425
1426#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1427 using node_type = typename _Hashtable::node_type;
1428#endif
1429
1430 //construct/destroy/copy
1431
1432 /// Default constructor.
1434
1435 /**
1436 * @brief Default constructor creates no elements.
1437 * @param __n Mnimal initial number of buckets.
1438 * @param __hf A hash functor.
1439 * @param __eql A key equality functor.
1440 * @param __a An allocator object.
1441 */
1442 explicit
1444 const hasher& __hf = hasher(),
1445 const key_equal& __eql = key_equal(),
1446 const allocator_type& __a = allocator_type())
1447 : _M_h(__n, __hf, __eql, __a)
1448 { }
1449
1450 /**
1451 * @brief Builds an %unordered_multimap from a range.
1452 * @param __first An input iterator.
1453 * @param __last An input iterator.
1454 * @param __n Minimal initial number of buckets.
1455 * @param __hf A hash functor.
1456 * @param __eql A key equality functor.
1457 * @param __a An allocator object.
1458 *
1459 * Create an %unordered_multimap consisting of copies of the elements
1460 * from [__first,__last). This is linear in N (where N is
1461 * distance(__first,__last)).
1462 */
1463 template<typename _InputIterator>
1464 unordered_multimap(_InputIterator __first, _InputIterator __last,
1465 size_type __n = 0,
1466 const hasher& __hf = hasher(),
1467 const key_equal& __eql = key_equal(),
1468 const allocator_type& __a = allocator_type())
1469 : _M_h(__first, __last, __n, __hf, __eql, __a)
1470 { }
1471
1472 /// Copy constructor.
1474
1475 /// Move constructor.
1477
1478 /**
1479 * @brief Creates an %unordered_multimap with no elements.
1480 * @param __a An allocator object.
1481 */
1482 explicit
1484 : _M_h(__a)
1485 { }
1486
1487 /*
1488 * @brief Copy constructor with allocator argument.
1489 * @param __uset Input %unordered_multimap to copy.
1490 * @param __a An allocator object.
1491 */
1493 const allocator_type& __a)
1494 : _M_h(__ummap._M_h, __a)
1495 { }
1496
1497 /*
1498 * @brief Move constructor with allocator argument.
1499 * @param __uset Input %unordered_multimap to move.
1500 * @param __a An allocator object.
1501 */
1502 unordered_multimap(unordered_multimap&& __ummap,
1503 const allocator_type& __a)
1504 noexcept( noexcept(_Hashtable(std::move(__ummap._M_h), __a)) )
1505 : _M_h(std::move(__ummap._M_h), __a)
1506 { }
1507
1508 /**
1509 * @brief Builds an %unordered_multimap from an initializer_list.
1510 * @param __l An initializer_list.
1511 * @param __n Minimal initial number of buckets.
1512 * @param __hf A hash functor.
1513 * @param __eql A key equality functor.
1514 * @param __a An allocator object.
1515 *
1516 * Create an %unordered_multimap consisting of copies of the elements in
1517 * the list. This is linear in N (where N is @a __l.size()).
1518 */
1520 size_type __n = 0,
1521 const hasher& __hf = hasher(),
1522 const key_equal& __eql = key_equal(),
1523 const allocator_type& __a = allocator_type())
1524 : _M_h(__l, __n, __hf, __eql, __a)
1525 { }
1526
1527 unordered_multimap(size_type __n, const allocator_type& __a)
1528 : unordered_multimap(__n, hasher(), key_equal(), __a)
1529 { }
1530
1531 unordered_multimap(size_type __n, const hasher& __hf,
1532 const allocator_type& __a)
1533 : unordered_multimap(__n, __hf, key_equal(), __a)
1534 { }
1535
1536 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1537 // 2713. More missing allocator-extended constructors for unordered containers
1538 template<typename _InputIterator>
1539 unordered_multimap(_InputIterator __first, _InputIterator __last,
1540 const allocator_type& __a)
1541 : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a)
1542 { }
1543
1544 template<typename _InputIterator>
1545 unordered_multimap(_InputIterator __first, _InputIterator __last,
1546 size_type __n,
1547 const allocator_type& __a)
1548 : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
1549 { }
1550
1551 template<typename _InputIterator>
1552 unordered_multimap(_InputIterator __first, _InputIterator __last,
1553 size_type __n, const hasher& __hf,
1554 const allocator_type& __a)
1555 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
1556 { }
1557
1558 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1559 // 2713. More missing allocator-extended constructors for unordered containers
1560 unordered_multimap(initializer_list<value_type> __l,
1561 const allocator_type& __a)
1562 : unordered_multimap(__l, 0, hasher(), key_equal(), __a)
1563 { }
1564
1565 unordered_multimap(initializer_list<value_type> __l,
1566 size_type __n,
1567 const allocator_type& __a)
1568 : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
1569 { }
1570
1571 unordered_multimap(initializer_list<value_type> __l,
1572 size_type __n, const hasher& __hf,
1573 const allocator_type& __a)
1574 : unordered_multimap(__l, __n, __hf, key_equal(), __a)
1575 { }
1576
1577#if __glibcxx_containers_ranges // C++ >= 23
1578 /**
1579 * @brief Builds an %unordered_multimap from a range.
1580 * @since C++23
1581 * @param __rg An input range of elements that can be converted to
1582 * the maps's value type.
1583 * @param __n Minimal initial number of buckets.
1584 * @param __hf A hash functor.
1585 * @param __eql A key equality functor.
1586 * @param __a An allocator object.
1587 *
1588 * Create an %unordered_multimap consisting of copies of the elements in
1589 * the range. This is linear in N (where N is `std::ranges::size(__rg)`).
1590 */
1591 template<__detail::__container_compatible_range<value_type> _Rg>
1592 unordered_multimap(from_range_t, _Rg&& __rg,
1593 size_type __n = 0,
1594 const hasher& __hf = hasher(),
1595 const key_equal& __eql = key_equal(),
1596 const allocator_type& __a = allocator_type())
1597 : _M_h(__n, __hf, __eql, __a)
1598 { insert_range(std::forward<_Rg>(__rg)); }
1599
1600 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1601 // 2713. More missing allocator-extended constructors for unordered containers
1602 template<__detail::__container_compatible_range<value_type> _Rg>
1603 unordered_multimap(from_range_t, _Rg&& __rg, const allocator_type& __a)
1604 : _M_h(0, hasher(), key_equal(), __a)
1605 { insert_range(std::forward<_Rg>(__rg)); }
1606
1607 template<__detail::__container_compatible_range<value_type> _Rg>
1608 unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1609 const allocator_type& __a)
1610 : _M_h(__n, hasher(), key_equal(), __a)
1611 { insert_range(std::forward<_Rg>(__rg)); }
1612
1613 template<__detail::__container_compatible_range<value_type> _Rg>
1614 unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1615 const hasher& __hf, const allocator_type& __a)
1616 : _M_h(__n, __hf, key_equal(), __a)
1617 { insert_range(std::forward<_Rg>(__rg)); }
1618#endif
1619
1620 /// Copy assignment operator.
1623
1624 /// Move assignment operator.
1627
1628 /**
1629 * @brief %Unordered_multimap list assignment operator.
1630 * @param __l An initializer_list.
1631 *
1632 * This function fills an %unordered_multimap with copies of the
1633 * elements in the initializer list @a __l.
1634 *
1635 * Note that the assignment completely changes the %unordered_multimap
1636 * and that the resulting %unordered_multimap's size is the same as the
1637 * number of elements assigned.
1638 */
1641 {
1642 _M_h = __l;
1643 return *this;
1644 }
1645
1646 /// Returns the allocator object used by the %unordered_multimap.
1647 allocator_type
1648 get_allocator() const noexcept
1649 { return _M_h.get_allocator(); }
1650
1651 // size and capacity:
1652
1653 /// Returns true if the %unordered_multimap is empty.
1654 _GLIBCXX_NODISCARD bool
1655 empty() const noexcept
1656 { return _M_h.empty(); }
1657
1658 /// Returns the size of the %unordered_multimap.
1659 size_type
1660 size() const noexcept
1661 { return _M_h.size(); }
1662
1663 /// Returns the maximum size of the %unordered_multimap.
1664 size_type
1665 max_size() const noexcept
1666 { return _M_h.max_size(); }
1667
1668 // iterators.
1669
1670 /**
1671 * Returns a read/write iterator that points to the first element in the
1672 * %unordered_multimap.
1673 */
1674 iterator
1675 begin() noexcept
1676 { return _M_h.begin(); }
1677
1678 ///@{
1679 /**
1680 * Returns a read-only (constant) iterator that points to the first
1681 * element in the %unordered_multimap.
1682 */
1683 const_iterator
1684 begin() const noexcept
1685 { return _M_h.begin(); }
1686
1687 const_iterator
1688 cbegin() const noexcept
1689 { return _M_h.begin(); }
1690 ///@}
1691
1692 /**
1693 * Returns a read/write iterator that points one past the last element in
1694 * the %unordered_multimap.
1695 */
1696 iterator
1697 end() noexcept
1698 { return _M_h.end(); }
1699
1700 ///@{
1701 /**
1702 * Returns a read-only (constant) iterator that points one past the last
1703 * element in the %unordered_multimap.
1704 */
1705 const_iterator
1706 end() const noexcept
1707 { return _M_h.end(); }
1708
1709 const_iterator
1710 cend() const noexcept
1711 { return _M_h.end(); }
1712 ///@}
1713
1714 // modifiers.
1715
1716 /**
1717 * @brief Attempts to build and insert a std::pair into the
1718 * %unordered_multimap.
1719 *
1720 * @param __args Arguments used to generate a new pair instance (see
1721 * std::piecewise_contruct for passing arguments to each
1722 * part of the pair constructor).
1723 *
1724 * @return An iterator that points to the inserted pair.
1725 *
1726 * This function attempts to build and insert a (key, value) %pair into
1727 * the %unordered_multimap.
1728 *
1729 * Insertion requires amortized constant time.
1730 */
1731 template<typename... _Args>
1732 iterator
1733 emplace(_Args&&... __args)
1734 { return _M_h.emplace(std::forward<_Args>(__args)...); }
1735
1736 /**
1737 * @brief Attempts to build and insert a std::pair into the
1738 * %unordered_multimap.
1739 *
1740 * @param __pos An iterator that serves as a hint as to where the pair
1741 * should be inserted.
1742 * @param __args Arguments used to generate a new pair instance (see
1743 * std::piecewise_contruct for passing arguments to each
1744 * part of the pair constructor).
1745 * @return An iterator that points to the element with key of the
1746 * std::pair built from @a __args.
1747 *
1748 * Note that the first parameter is only a hint and can potentially
1749 * improve the performance of the insertion process. A bad hint would
1750 * cause no gains in efficiency.
1751 *
1752 * See
1753 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1754 * for more on @a hinting.
1755 *
1756 * Insertion requires amortized constant time.
1757 */
1758 template<typename... _Args>
1759 iterator
1760 emplace_hint(const_iterator __pos, _Args&&... __args)
1761 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
1762
1763 ///@{
1764 /**
1765 * @brief Inserts a std::pair into the %unordered_multimap.
1766 * @param __x Pair to be inserted (see std::make_pair for easy
1767 * creation of pairs).
1768 *
1769 * @return An iterator that points to the inserted pair.
1770 *
1771 * Insertion requires amortized constant time.
1772 */
1773 iterator
1774 insert(const value_type& __x)
1775 { return _M_h.insert(__x); }
1776
1777 iterator
1779 { return _M_h.insert(std::move(__x)); }
1780
1781 template<typename _Pair>
1782 __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
1783 insert(_Pair&& __x)
1784 { return _M_h.emplace(std::forward<_Pair>(__x)); }
1785 ///@}
1786
1787 ///@{
1788 /**
1789 * @brief Inserts a std::pair into the %unordered_multimap.
1790 * @param __hint An iterator that serves as a hint as to where the
1791 * pair should be inserted.
1792 * @param __x Pair to be inserted (see std::make_pair for easy creation
1793 * of pairs).
1794 * @return An iterator that points to the element with key of
1795 * @a __x (may or may not be the %pair passed in).
1796 *
1797 * Note that the first parameter is only a hint and can potentially
1798 * improve the performance of the insertion process. A bad hint would
1799 * cause no gains in efficiency.
1800 *
1801 * See
1802 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1803 * for more on @a hinting.
1804 *
1805 * Insertion requires amortized constant time.
1806 */
1807 iterator
1809 { return _M_h.insert(__hint, __x); }
1810
1811 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1812 // 2354. Unnecessary copying when inserting into maps with braced-init
1813 iterator
1815 { return _M_h.insert(__hint, std::move(__x)); }
1816
1817 template<typename _Pair>
1818 __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator>
1819 insert(const_iterator __hint, _Pair&& __x)
1820 { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); }
1821 ///@}
1822
1823 /**
1824 * @brief A template function that attempts to insert a range of
1825 * elements.
1826 * @param __first Iterator pointing to the start of the range to be
1827 * inserted.
1828 * @param __last Iterator pointing to the end of the range.
1829 *
1830 * Complexity similar to that of the range constructor.
1831 */
1832 template<typename _InputIterator>
1833 void
1834 insert(_InputIterator __first, _InputIterator __last)
1835 { _M_h.insert(__first, __last); }
1836
1837 /**
1838 * @brief Attempts to insert a list of elements into the
1839 * %unordered_multimap.
1840 * @param __l A std::initializer_list<value_type> of elements
1841 * to be inserted.
1842 *
1843 * Complexity similar to that of the range constructor.
1844 */
1845 void
1847 { _M_h.insert(__l); }
1848
1849#if __glibcxx_containers_ranges // C++ >= 23
1850 /**
1851 * @brief Inserts a range of elements.
1852 * @since C++23
1853 * @param __rg An input range of elements that can be converted to
1854 * the maps's value type.
1855 */
1856 template<__detail::__container_compatible_range<value_type> _Rg>
1857 void
1858 insert_range(_Rg&& __rg)
1859 {
1860 auto __first = ranges::begin(__rg);
1861 const auto __last = ranges::end(__rg);
1862 if (__first == __last)
1863 return;
1864
1866 _M_h._M_rehash_insert(size_type(ranges::distance(__rg)));
1867 else
1868 _M_h._M_rehash_insert(1);
1869
1870 for (; __first != __last; ++__first)
1871 _M_h.emplace(*__first);
1872 }
1873#endif
1874
1875#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1876 /// Extract a node.
1877 node_type
1878 extract(const_iterator __pos)
1879 {
1880 __glibcxx_assert(__pos != end());
1881 return _M_h.extract(__pos);
1882 }
1883
1884 /// Extract a node.
1885 node_type
1886 extract(const key_type& __key)
1887 { return _M_h.extract(__key); }
1888
1889#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
1890 template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1891 node_type
1892 extract(_Kt&& __key)
1893 { return _M_h._M_extract_tr(__key); }
1894#endif
1895
1896 /// Re-insert an extracted node.
1897 iterator
1898 insert(node_type&& __nh)
1899 { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
1900
1901 /// Re-insert an extracted node.
1902 iterator
1903 insert(const_iterator __hint, node_type&& __nh)
1904 { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
1905#endif // node_extract
1906
1907 ///@{
1908 /**
1909 * @brief Erases an element from an %unordered_multimap.
1910 * @param __position An iterator pointing to the element to be erased.
1911 * @return An iterator pointing to the element immediately following
1912 * @a __position prior to the element being erased. If no such
1913 * element exists, end() is returned.
1914 *
1915 * This function erases an element, pointed to by the given iterator,
1916 * from an %unordered_multimap.
1917 * Note that this function only erases the element, and that if the
1918 * element is itself a pointer, the pointed-to memory is not touched in
1919 * any way. Managing the pointer is the user's responsibility.
1920 */
1921 iterator
1923 { return _M_h.erase(__position); }
1924
1925 // LWG 2059.
1926 iterator
1927 erase(iterator __position)
1928 { return _M_h.erase(__position); }
1929 ///@}
1930
1931 /**
1932 * @brief Erases elements according to the provided key.
1933 * @param __x Key of elements to be erased.
1934 * @return The number of elements erased.
1935 *
1936 * This function erases all the elements located by the given key from
1937 * an %unordered_multimap.
1938 * Note that this function only erases the element, and that if the
1939 * element is itself a pointer, the pointed-to memory is not touched in
1940 * any way. Managing the pointer is the user's responsibility.
1941 */
1942 size_type
1943 erase(const key_type& __x)
1944 { return _M_h.erase(__x); }
1945
1946#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
1947 template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1948 size_type
1949 erase(_Kt&& __key)
1950 { return _M_h._M_erase_tr(__key); }
1951#endif
1952
1953 /**
1954 * @brief Erases a [__first,__last) range of elements from an
1955 * %unordered_multimap.
1956 * @param __first Iterator pointing to the start of the range to be
1957 * erased.
1958 * @param __last Iterator pointing to the end of the range to
1959 * be erased.
1960 * @return The iterator @a __last.
1961 *
1962 * This function erases a sequence of elements from an
1963 * %unordered_multimap.
1964 * Note that this function only erases the elements, and that if
1965 * the element is itself a pointer, the pointed-to memory is not touched
1966 * in any way. Managing the pointer is the user's responsibility.
1967 */
1968 iterator
1970 { return _M_h.erase(__first, __last); }
1971
1972 /**
1973 * Erases all elements in an %unordered_multimap.
1974 * Note that this function only erases the elements, and that if the
1975 * elements themselves are pointers, the pointed-to memory is not touched
1976 * in any way. Managing the pointer is the user's responsibility.
1977 */
1978 void
1979 clear() noexcept
1980 { _M_h.clear(); }
1981
1982 /**
1983 * @brief Swaps data with another %unordered_multimap.
1984 * @param __x An %unordered_multimap of the same element and allocator
1985 * types.
1986 *
1987 * This exchanges the elements between two %unordered_multimap in
1988 * constant time.
1989 * Note that the global std::swap() function is specialized such that
1990 * std::swap(m1,m2) will feed to this function.
1991 */
1992 void
1994 noexcept( noexcept(_M_h.swap(__x._M_h)) )
1995 { _M_h.swap(__x._M_h); }
1996
1997#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1998 template<typename, typename, typename>
1999 friend class std::_Hash_merge_helper;
2000
2001 template<typename _H2, typename _P2>
2002 void
2004 {
2005 if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
2006 if (std::__addressof(__source) == this) [[__unlikely__]]
2007 return;
2008
2009 using _Merge_helper
2010 = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
2011 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
2012 }
2013
2014 template<typename _H2, typename _P2>
2015 void
2016 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
2017 {
2018 using _Merge_helper
2019 = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
2020 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
2021 }
2022
2023 template<typename _H2, typename _P2>
2024 void
2025 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
2026 {
2027 using _Merge_helper
2028 = _Hash_merge_helper<unordered_multimap, _H2, _P2>;
2029 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
2030 }
2031
2032 template<typename _H2, typename _P2>
2033 void
2034 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
2035 { merge(__source); }
2036#endif // node_extract
2037
2038 // observers.
2039
2040 /// Returns the hash functor object with which the %unordered_multimap
2041 /// was constructed.
2042 hasher
2044 { return _M_h.hash_function(); }
2045
2046 /// Returns the key comparison object with which the %unordered_multimap
2047 /// was constructed.
2048 key_equal
2049 key_eq() const
2050 { return _M_h.key_eq(); }
2051
2052 // lookup.
2053
2054 ///@{
2055 /**
2056 * @brief Tries to locate an element in an %unordered_multimap.
2057 * @param __x Key to be located.
2058 * @return Iterator pointing to sought-after element, or end() if not
2059 * found.
2060 *
2061 * This function takes a key and tries to locate the element with which
2062 * the key matches. If successful the function returns an iterator
2063 * pointing to the sought after element. If unsuccessful it returns the
2064 * past-the-end ( @c end() ) iterator.
2065 */
2066 iterator
2067 find(const key_type& __x)
2068 { return _M_h.find(__x); }
2069
2070#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2071 template<typename _Kt>
2072 auto
2073 find(const _Kt& __x) -> decltype(_M_h._M_find_tr(__x))
2074 { return _M_h._M_find_tr(__x); }
2075#endif
2076
2077 const_iterator
2078 find(const key_type& __x) const
2079 { return _M_h.find(__x); }
2080
2081#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2082 template<typename _Kt>
2083 auto
2084 find(const _Kt& __x) const -> decltype(_M_h._M_find_tr(__x))
2085 { return _M_h._M_find_tr(__x); }
2086#endif
2087 ///@}
2088
2089 ///@{
2090 /**
2091 * @brief Finds the number of elements.
2092 * @param __x Key to count.
2093 * @return Number of elements with specified key.
2094 */
2095 size_type
2096 count(const key_type& __x) const
2097 { return _M_h.count(__x); }
2098
2099#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2100 template<typename _Kt>
2101 auto
2102 count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
2103 { return _M_h._M_count_tr(__x); }
2104#endif
2105 ///@}
2106
2107#if __cplusplus > 201703L
2108 ///@{
2109 /**
2110 * @brief Finds whether an element with the given key exists.
2111 * @param __x Key of elements to be located.
2112 * @return True if there is any element with the specified key.
2113 */
2114 bool
2115 contains(const key_type& __x) const
2116 { return _M_h.find(__x) != _M_h.end(); }
2117
2118 template<typename _Kt>
2119 auto
2120 contains(const _Kt& __x) const
2121 -> decltype(_M_h._M_find_tr(__x), void(), true)
2122 { return _M_h._M_find_tr(__x) != _M_h.end(); }
2123 ///@}
2124#endif
2125
2126 ///@{
2127 /**
2128 * @brief Finds a subsequence matching given key.
2129 * @param __x Key to be located.
2130 * @return Pair of iterators that possibly points to the subsequence
2131 * matching given key.
2132 */
2135 { return _M_h.equal_range(__x); }
2136
2137#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2138 template<typename _Kt>
2139 auto
2140 equal_range(const _Kt& __x)
2141 -> decltype(_M_h._M_equal_range_tr(__x))
2142 { return _M_h._M_equal_range_tr(__x); }
2143#endif
2144
2146 equal_range(const key_type& __x) const
2147 { return _M_h.equal_range(__x); }
2148
2149#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
2150 template<typename _Kt>
2151 auto
2152 equal_range(const _Kt& __x) const
2153 -> decltype(_M_h._M_equal_range_tr(__x))
2154 { return _M_h._M_equal_range_tr(__x); }
2155#endif
2156 ///@}
2157
2158 // bucket interface.
2159
2160 /// Returns the number of buckets of the %unordered_multimap.
2161 size_type
2162 bucket_count() const noexcept
2163 { return _M_h.bucket_count(); }
2164
2165 /// Returns the maximum number of buckets of the %unordered_multimap.
2166 size_type
2167 max_bucket_count() const noexcept
2168 { return _M_h.max_bucket_count(); }
2169
2170 /*
2171 * @brief Returns the number of elements in a given bucket.
2172 * @param __n A bucket index.
2173 * @return The number of elements in the bucket.
2174 */
2175 size_type
2176 bucket_size(size_type __n) const
2177 { return _M_h.bucket_size(__n); }
2178
2179 /*
2180 * @brief Returns the bucket index of a given element.
2181 * @param __key A key instance.
2182 * @return The key bucket index.
2183 */
2184 size_type
2185 bucket(const key_type& __key) const
2186 { return _M_h.bucket(__key); }
2187
2188 /**
2189 * @brief Returns a read/write iterator pointing to the first bucket
2190 * element.
2191 * @param __n The bucket index.
2192 * @return A read/write local iterator.
2193 */
2196 { return _M_h.begin(__n); }
2197
2198 ///@{
2199 /**
2200 * @brief Returns a read-only (constant) iterator pointing to the first
2201 * bucket element.
2202 * @param __n The bucket index.
2203 * @return A read-only local iterator.
2204 */
2206 begin(size_type __n) const
2207 { return _M_h.begin(__n); }
2208
2211 { return _M_h.cbegin(__n); }
2212 ///@}
2213
2214 /**
2215 * @brief Returns a read/write iterator pointing to one past the last
2216 * bucket elements.
2217 * @param __n The bucket index.
2218 * @return A read/write local iterator.
2219 */
2222 { return _M_h.end(__n); }
2223
2224 ///@{
2225 /**
2226 * @brief Returns a read-only (constant) iterator pointing to one past
2227 * the last bucket elements.
2228 * @param __n The bucket index.
2229 * @return A read-only local iterator.
2230 */
2232 end(size_type __n) const
2233 { return _M_h.end(__n); }
2234
2236 cend(size_type __n) const
2237 { return _M_h.cend(__n); }
2238 ///@}
2239
2240 // hash policy.
2241
2242 /// Returns the average number of elements per bucket.
2243 float
2244 load_factor() const noexcept
2245 { return _M_h.load_factor(); }
2246
2247 /// Returns a positive number that the %unordered_multimap tries to keep
2248 /// the load factor less than or equal to.
2249 float
2250 max_load_factor() const noexcept
2251 { return _M_h.max_load_factor(); }
2252
2253 /**
2254 * @brief Change the %unordered_multimap maximum load factor.
2255 * @param __z The new maximum load factor.
2256 */
2257 void
2259 { _M_h.max_load_factor(__z); }
2260
2261 /**
2262 * @brief May rehash the %unordered_multimap.
2263 * @param __n The new number of buckets.
2264 *
2265 * Rehash will occur only if the new number of buckets respect the
2266 * %unordered_multimap maximum load factor.
2267 */
2268 void
2270 { _M_h.rehash(__n); }
2271
2272 /**
2273 * @brief Prepare the %unordered_multimap for a specified number of
2274 * elements.
2275 * @param __n Number of elements required.
2276 *
2277 * Same as rehash(ceil(n / max_load_factor())).
2278 */
2279 void
2281 { _M_h.reserve(__n); }
2282
2283 template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1,
2284 typename _Alloc1>
2285 friend bool
2286 operator==(const unordered_multimap<_Key1, _Tp1,
2287 _Hash1, _Pred1, _Alloc1>&,
2288 const unordered_multimap<_Key1, _Tp1,
2289 _Hash1, _Pred1, _Alloc1>&);
2290 };
2291
2292#if __cpp_deduction_guides >= 201606
2293
2294 template<typename _InputIterator,
2295 typename _Hash = hash<__iter_key_t<_InputIterator>>,
2296 typename _Pred = equal_to<__iter_key_t<_InputIterator>>,
2297 typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
2298 typename = _RequireInputIter<_InputIterator>,
2299 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2300 typename = _RequireNotAllocator<_Pred>,
2301 typename = _RequireAllocator<_Allocator>>
2302 unordered_multimap(_InputIterator, _InputIterator,
2303 unordered_multimap<int, int>::size_type = {},
2304 _Hash = _Hash(), _Pred = _Pred(),
2305 _Allocator = _Allocator())
2306 -> unordered_multimap<__iter_key_t<_InputIterator>,
2307 __iter_val_t<_InputIterator>, _Hash, _Pred,
2308 _Allocator>;
2309
2310 template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
2311 typename _Pred = equal_to<_Key>,
2312 typename _Allocator = allocator<pair<const _Key, _Tp>>,
2313 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2314 typename = _RequireNotAllocator<_Pred>,
2315 typename = _RequireAllocator<_Allocator>>
2318 _Hash = _Hash(), _Pred = _Pred(),
2319 _Allocator = _Allocator())
2321
2322 template<typename _InputIterator, typename _Allocator,
2323 typename = _RequireInputIter<_InputIterator>,
2324 typename = _RequireAllocator<_Allocator>>
2325 unordered_multimap(_InputIterator, _InputIterator,
2328 __iter_val_t<_InputIterator>,
2331
2332 template<typename _InputIterator, typename _Allocator,
2333 typename = _RequireInputIter<_InputIterator>,
2334 typename = _RequireAllocator<_Allocator>>
2335 unordered_multimap(_InputIterator, _InputIterator, _Allocator)
2337 __iter_val_t<_InputIterator>,
2340
2341 template<typename _InputIterator, typename _Hash, typename _Allocator,
2342 typename = _RequireInputIter<_InputIterator>,
2343 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2344 typename = _RequireAllocator<_Allocator>>
2345 unordered_multimap(_InputIterator, _InputIterator,
2347 _Allocator)
2349 __iter_val_t<_InputIterator>, _Hash,
2351
2352 template<typename _Key, typename _Tp, typename _Allocator,
2353 typename = _RequireAllocator<_Allocator>>
2356 _Allocator)
2358
2359 template<typename _Key, typename _Tp, typename _Allocator,
2360 typename = _RequireAllocator<_Allocator>>
2363
2364 template<typename _Key, typename _Tp, typename _Hash, typename _Allocator,
2365 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2366 typename = _RequireAllocator<_Allocator>>
2369 _Hash, _Allocator)
2371
2372#if __glibcxx_containers_ranges // C++ >= 23
2373 template<ranges::input_range _Rg,
2374 __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
2375 __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
2376 __allocator_like _Allocator =
2378 unordered_multimap(from_range_t, _Rg&&,
2380 _Hash = _Hash(), _Pred = _Pred(),
2381 _Allocator = _Allocator())
2382 -> unordered_multimap<__detail::__range_key_type<_Rg>,
2383 __detail::__range_mapped_type<_Rg>,
2384 _Hash, _Pred, _Allocator>;
2385
2386 template<ranges::input_range _Rg,
2387 __allocator_like _Allocator>
2389 _Allocator)
2391 __detail::__range_mapped_type<_Rg>,
2394 _Allocator>;
2395
2396 template<ranges::input_range _Rg,
2397 __allocator_like _Allocator>
2398 unordered_multimap(from_range_t, _Rg&&, _Allocator)
2400 __detail::__range_mapped_type<_Rg>,
2403 _Allocator>;
2404
2405 template<ranges::input_range _Rg,
2406 __not_allocator_like _Hash,
2407 __allocator_like _Allocator>
2408 unordered_multimap(from_range_t, _Rg&&,
2410 _Hash, _Allocator)
2412 __detail::__range_mapped_type<_Rg>,
2414 _Allocator>;
2415#endif
2416#endif
2417
2418 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2419 inline void
2422 noexcept(noexcept(__x.swap(__y)))
2423 { __x.swap(__y); }
2424
2425 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2426 inline void
2429 noexcept(noexcept(__x.swap(__y)))
2430 { __x.swap(__y); }
2431
2432 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2433 inline bool
2436 { return __x._M_h._M_equal(__y._M_h); }
2437
2438#if __cpp_impl_three_way_comparison < 201907L
2439 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2440 inline bool
2443 { return !(__x == __y); }
2444#endif
2445
2446 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2447 inline bool
2450 { return __x._M_h._M_equal(__y._M_h); }
2451
2452#if __cpp_impl_three_way_comparison < 201907L
2453 template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
2454 inline bool
2457 { return !(__x == __y); }
2458#endif
2459
2460_GLIBCXX_END_NAMESPACE_CONTAINER
2461
2462#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
2463 // Allow std::unordered_map access to internals of compatible maps.
2464 template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
2465 typename _Alloc, typename _Hash2, typename _Eq2>
2466 struct _Hash_merge_helper<
2467 _GLIBCXX_STD_C::unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>,
2468 _Hash2, _Eq2>
2469 {
2470 private:
2471 template<typename... _Tp>
2472 using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
2473 template<typename... _Tp>
2474 using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
2475
2476 friend unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>;
2477
2478 static auto&
2479 _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2480 { return __map._M_h; }
2481
2482 static auto&
2483 _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2484 { return __map._M_h; }
2485 };
2486
2487 // Allow std::unordered_multimap access to internals of compatible maps.
2488 template<typename _Key, typename _Val, typename _Hash1, typename _Eq1,
2489 typename _Alloc, typename _Hash2, typename _Eq2>
2490 struct _Hash_merge_helper<
2491 _GLIBCXX_STD_C::unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>,
2492 _Hash2, _Eq2>
2493 {
2494 private:
2495 template<typename... _Tp>
2496 using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>;
2497 template<typename... _Tp>
2498 using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>;
2499
2500 friend unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>;
2501
2502 static auto&
2503 _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2504 { return __map._M_h; }
2505
2506 static auto&
2507 _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map)
2508 { return __map._M_h; }
2509 };
2510#endif // node_extract
2511
2512_GLIBCXX_END_NAMESPACE_VERSION
2513} // namespace std
2514
2515#endif /* _UNORDERED_MAP_H */
pair(_T1, _T2) -> pair< _T1, _T2 >
Two pairs are equal iff their members are equal.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
ISO C++ entities toplevel namespace is std.
__detail::_Hashtable_traits< _Cache, false, false > __ummap_traits
Base types for unordered_multimap.
__detail::_Hashtable_traits< _Cache, false, true > __umap_traits
Base types for unordered_map.
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.
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.
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.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_multimap.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_multimap.
iterator begin() noexcept
const_iterator begin() const noexcept
hasher hash_function() const
Returns the hash functor object with which the unordered_multimap was constructed.
__enable_if_t< is_constructible< value_type, _Pair && >::value, iterator > insert(const_iterator __hint, _Pair &&__x)
Inserts a std::pair into the unordered_multimap.
unordered_multimap & operator=(const unordered_multimap &)=default
Copy assignment operator.
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.
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 & operator=(initializer_list< value_type > __l)
Unordered_multimap list assignment operator.
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.
iterator emplace(_Args &&... __args)
Attempts to build and insert a std::pair into the unordered_multimap.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
iterator erase(const_iterator __position)
Erases an element from an unordered_multimap.
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.
unordered_multimap & operator=(unordered_multimap &&)=default
Move assignment operator.
void reserve(size_type __n)
Prepare the unordered_multimap for a specified number of elements.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
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.
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.
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_multimap(unordered_multimap &&)=default
Move constructor.
unordered_multimap(const allocator_type &__a)
Creates an unordered_multimap with no elements.
__enable_if_t< is_constructible< value_type, _Pair && >::value, iterator > insert(_Pair &&__x)
Inserts a std::pair into the unordered_multimap.
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.
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.
const_iterator cbegin() const noexcept
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.
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.
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.
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.
void max_load_factor(float __z)
Change the unordered_map maximum load factor.
const mapped_type & at(const key_type &__k) const
Access to unordered_map data.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
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.
unordered_map & operator=(initializer_list< value_type > __l)
Unordered_map list assignment operator.
void insert(initializer_list< value_type > __l)
Attempts to insert a list of elements into the unordered_map.
__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.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
mapped_type & at(const key_type &__k)
Access to unordered_map data.
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_map.
std::pair< iterator, bool > insert(const value_type &__x)
Attempts to insert a std::pair into the unordered_map.
void reserve(size_type __n)
Prepare the unordered_map for a specified number of elements.
const_local_iterator cbegin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
iterator insert(const_iterator __hint, const value_type &__x)
Attempts to insert a std::pair into the unordered_map.
iterator end() noexcept
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.
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.
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.
unordered_map & operator=(unordered_map &&)=default
Move assignment operator.
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.
std::pair< iterator, bool > emplace(_Args &&... __args)
Attempts to build and insert a std::pair into the unordered_map.
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.
__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.
mapped_type & operator[](key_type &&__k)
Subscript ( [] ) access to unordered_map data.
std::pair< iterator, bool > insert(value_type &&__x)
Attempts to insert a std::pair into the unordered_map.
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
mapped_type & operator[](const key_type &__k)
Subscript ( [] ) access to unordered_map data.
const_iterator begin() const noexcept
key_equal key_eq() const
Returns the key comparison object with which the unordered_map was constructed.
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.
unordered_map(const allocator_type &__a)
Creates an unordered_map with no elements.
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(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.
iterator find(const key_type &__x)
Tries to locate an element in an 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.
unordered_map & operator=(const unordered_map &)=default
Copy assignment operator.
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.
void rehash(size_type __n)
May rehash the unordered_map.
const_iterator cbegin() const noexcept
[range.sized] The sized_range concept.
A range for which ranges::begin returns an input iterator.
A range for which ranges::begin returns a forward iterator.