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