29#ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
30#define _GLIBCXX_DEBUG_UNORDERED_MAP 1
33#pragma GCC system_header
36#if __cplusplus < 201103L
40namespace std _GLIBCXX_VISIBILITY(default) {
namespace __debug {
41 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _Pred,
44 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _Pred,
56namespace std _GLIBCXX_VISIBILITY(default)
61 template<
typename _Key,
typename _Tp,
62 typename _Hash = std::hash<_Key>,
63 typename _Pred = std::equal_to<_Key>,
64 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
67 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
68 __gnu_debug::_Safe_unordered_container>,
69 public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
71 typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
75 typedef typename _Base::const_iterator _Base_const_iterator;
76 typedef typename _Base::iterator _Base_iterator;
77 typedef typename _Base::const_local_iterator
78 _Base_const_local_iterator;
79 typedef typename _Base::local_iterator _Base_local_iterator;
81 template<
typename _ItT,
typename _SeqT,
typename _CatT>
82 friend class ::__gnu_debug::_Safe_iterator;
83 template<
typename _ItT,
typename _SeqT>
84 friend class ::__gnu_debug::_Safe_local_iterator;
89 _Base_ref(
const _Base& __r) : _M_ref(__r) { }
95 typedef typename _Base::size_type size_type;
96 typedef typename _Base::hasher hasher;
97 typedef typename _Base::key_equal key_equal;
98 typedef typename _Base::allocator_type allocator_type;
100 typedef typename _Base::key_type key_type;
101 typedef typename _Base::value_type value_type;
102 typedef typename _Base::mapped_type mapped_type;
104 typedef typename _Base::pointer pointer;
105 typedef typename _Base::const_pointer const_pointer;
106 typedef typename _Base::reference reference;
107 typedef typename _Base::const_reference const_reference;
109 _Base_iterator, unordered_map> iterator;
111 _Base_const_iterator, unordered_map> const_iterator;
113 _Base_local_iterator, unordered_map> local_iterator;
115 _Base_const_local_iterator, unordered_map> const_local_iterator;
116 typedef typename _Base::difference_type difference_type;
118 unordered_map() =
default;
121 unordered_map(size_type __n,
122 const hasher& __hf = hasher(),
123 const key_equal& __eql = key_equal(),
124 const allocator_type& __a = allocator_type())
125 : _Base(__n, __hf, __eql, __a) { }
127 template<
typename _InputIterator>
128 unordered_map(_InputIterator __first, _InputIterator __last,
130 const hasher& __hf = hasher(),
131 const key_equal& __eql = key_equal(),
132 const allocator_type& __a = allocator_type())
134 __glibcxx_check_valid_constructor_range(__first, __last)),
136 __hf, __eql, __a) { }
138 unordered_map(
const unordered_map&) =
default;
140 unordered_map(_Base_ref __x)
141 : _Base(__x._M_ref) { }
143 unordered_map(unordered_map&&) =
default;
146 unordered_map(
const allocator_type& __a)
149 unordered_map(
const unordered_map& __umap,
150 const allocator_type& __a)
151 : _Base(__umap, __a) { }
153 unordered_map(unordered_map&& __umap,
154 const allocator_type& __a)
155 noexcept(
noexcept(_Base(
std::move(__umap), __a)) )
161 const hasher& __hf = hasher(),
162 const key_equal& __eql = key_equal(),
163 const allocator_type& __a = allocator_type())
164 : _Base(__l, __n, __hf, __eql, __a) { }
166 unordered_map(size_type __n,
const allocator_type& __a)
167 : unordered_map(__n, hasher(), key_equal(), __a)
170 unordered_map(size_type __n,
172 const allocator_type& __a)
173 : unordered_map(__n, __hf, key_equal(), __a)
176 template<
typename _InputIterator>
177 unordered_map(_InputIterator __first, _InputIterator __last,
178 const allocator_type& __a)
179 : unordered_map(__first, __last, 0, hasher(), key_equal(), __a)
182 template<
typename _InputIterator>
183 unordered_map(_InputIterator __first, _InputIterator __last,
185 const allocator_type& __a)
186 : unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
189 template<
typename _InputIterator>
190 unordered_map(_InputIterator __first, _InputIterator __last,
193 const allocator_type& __a)
194 : unordered_map(__first, __last, __n, __hf, key_equal(), __a)
198 const allocator_type& __a)
199 : unordered_map(__l, 0, hasher(), key_equal(), __a)
204 const allocator_type& __a)
205 : unordered_map(__l, __n, hasher(), key_equal(), __a)
211 const allocator_type& __a)
212 : unordered_map(__l, __n, __hf, key_equal(), __a)
215#if __glibcxx_containers_ranges
216 template<__detail::__container_compatible_range<value_type> _Rg>
217 unordered_map(from_range_t, _Rg&& __rg,
219 const hasher& __hf = hasher(),
220 const key_equal& __eql = key_equal(),
221 const allocator_type& __a = allocator_type())
225 template<__detail::__container_compatible_range<value_type> _Rg>
226 unordered_map(from_range_t, _Rg&& __rg,
const allocator_type& __a)
230 template<__detail::__container_compatible_range<value_type> _Rg>
231 unordered_map(from_range_t, _Rg&& __rg, size_type __n,
232 const allocator_type& __a)
236 template<__detail::__container_compatible_range<value_type> _Rg>
237 unordered_map(from_range_t, _Rg&& __rg, size_type __n,
238 const hasher& __hf,
const allocator_type& __a)
243 ~unordered_map() =
default;
246 operator=(
const unordered_map&) =
default;
249 operator=(unordered_map&&) =
default;
254 _Base::operator=(__l);
255 this->_M_invalidate_all();
259 using _Base::get_allocator;
262 using _Base::max_size;
265 swap(unordered_map& __x)
276 this->_M_invalidate_all();
281 {
return { _Base::begin(),
this }; }
284 begin()
const noexcept
285 {
return { _Base::begin(),
this }; }
289 {
return { _Base::end(),
this }; }
293 {
return { _Base::end(),
this }; }
296 cbegin()
const noexcept
297 {
return { _Base::cbegin(),
this }; }
300 cend()
const noexcept
301 {
return { _Base::cend(),
this }; }
307 __glibcxx_check_bucket_index(__b);
308 return { _Base::begin(__b),
this };
314 __glibcxx_check_bucket_index(__b);
315 return { _Base::end(__b),
this };
319 begin(size_type __b)
const
321 __glibcxx_check_bucket_index(__b);
322 return { _Base::begin(__b),
this };
326 end(size_type __b)
const
328 __glibcxx_check_bucket_index(__b);
329 return { _Base::end(__b),
this };
333 cbegin(size_type __b)
const
335 __glibcxx_check_bucket_index(__b);
336 return { _Base::cbegin(__b),
this };
340 cend(size_type __b)
const
342 __glibcxx_check_bucket_index(__b);
343 return { _Base::cend(__b),
this };
346 using _Base::bucket_count;
347 using _Base::max_bucket_count;
351 bucket_size(size_type __b)
const
353 __glibcxx_check_bucket_index(__b);
354 return _Base::bucket_size(__b);
357 using _Base::load_factor;
360 max_load_factor()
const noexcept
361 {
return _Base::max_load_factor(); }
364 max_load_factor(
float __f)
366 __glibcxx_check_max_load_factor(__f);
367 _Base::max_load_factor(__f);
370 template<
typename... _Args>
372 emplace(_Args&&... __args)
374 size_type __bucket_count = this->bucket_count();
376 _M_check_rehashed(__bucket_count);
377 return { { __res.first,
this }, __res.second };
380 template<
typename... _Args>
382 emplace_hint(const_iterator __hint, _Args&&... __args)
385 size_type __bucket_count = this->bucket_count();
386 auto __it = _Base::emplace_hint(__hint.
base(),
388 _M_check_rehashed(__bucket_count);
389 return { __it,
this };
393 insert(
const value_type& __obj)
395 size_type __bucket_count = this->bucket_count();
396 auto __res = _Base::insert(__obj);
397 _M_check_rehashed(__bucket_count);
398 return { { __res.first,
this }, __res.second };
404 insert(value_type&& __x)
406 size_type __bucket_count = this->bucket_count();
407 auto __res = _Base::insert(
std::move(__x));
408 _M_check_rehashed(__bucket_count);
409 return { { __res.first,
this }, __res.second };
412 template<
typename _Pair,
typename =
typename
416 insert(_Pair&& __obj)
418 size_type __bucket_count = this->bucket_count();
420 _M_check_rehashed(__bucket_count);
421 return { { __res.first,
this }, __res.second };
425 insert(const_iterator __hint,
const value_type& __obj)
428 size_type __bucket_count = this->bucket_count();
429 auto __it = _Base::insert(__hint.
base(), __obj);
430 _M_check_rehashed(__bucket_count);
431 return { __it,
this };
437 insert(const_iterator __hint, value_type&& __x)
440 size_type __bucket_count = this->bucket_count();
442 _M_check_rehashed(__bucket_count);
443 return { __it,
this };
446 template<
typename _Pair,
typename =
typename
450 insert(const_iterator __hint, _Pair&& __obj)
453 size_type __bucket_count = this->bucket_count();
455 _M_check_rehashed(__bucket_count);
456 return { __it,
this };
462 size_type __bucket_count = this->bucket_count();
464 _M_check_rehashed(__bucket_count);
467 template<
typename _InputIterator>
469 insert(_InputIterator __first, _InputIterator __last)
471 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
472 __glibcxx_check_valid_range2(__first, __last, __dist);
473 size_type __bucket_count = this->bucket_count();
475 if (__dist.second >= __gnu_debug::__dp_sign)
476 _Base::insert(__gnu_debug::__unsafe(__first),
477 __gnu_debug::__unsafe(__last));
479 _Base::insert(__first, __last);
481 _M_check_rehashed(__bucket_count);
484#ifdef __glibcxx_unordered_map_try_emplace
485 template <
typename... _Args>
487 try_emplace(
const key_type& __k, _Args&&... __args)
489 auto __res = _Base::try_emplace(__k,
491 return { { __res.first,
this }, __res.second };
494 template <
typename... _Args>
496 try_emplace(key_type&& __k, _Args&&... __args)
498 auto __res = _Base::try_emplace(
std::move(__k),
500 return { { __res.first,
this }, __res.second };
503# ifdef __glibcxx_associative_heterogeneous_insertion
504 template <__heterogeneous_hash_key<unordered_map> _Kt,
typename... _Args>
506 try_emplace(_Kt&& __k, _Args&&... __args)
510 return { { __res.first,
this }, __res.second };
514 template <
typename... _Args>
516 try_emplace(const_iterator __hint,
const key_type& __k,
520 return { _Base::try_emplace(__hint.
base(), __k,
525 template <
typename... _Args>
527 try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
530 auto __it = _Base::try_emplace(__hint.
base(),
std::move(__k),
532 return { __it,
this };
534# ifdef __glibcxx_associative_heterogeneous_insertion
535 template <__heterogeneous_hash_key<unordered_map> _Kt,
typename... _Args>
537 try_emplace(const_iterator __hint, _Kt&& __k, _Args&&... __args)
540 auto __it = _Base::try_emplace(__hint.
base(),
542 return { __it,
this };
546 template <
typename _Obj>
548 insert_or_assign(
const key_type& __k, _Obj&& __obj)
550 auto __res = _Base::insert_or_assign(__k,
552 return { { __res.first,
this }, __res.second };
555 template <
typename _Obj>
557 insert_or_assign(key_type&& __k, _Obj&& __obj)
559 auto __res = _Base::insert_or_assign(
std::move(__k),
561 return { { __res.first,
this }, __res.second };
564# ifdef __glibcxx_associative_heterogeneous_insertion
565 template <__heterogeneous_hash_key<unordered_map> _Kt,
typename _Obj>
567 insert_or_assign(_Kt&& __k, _Obj&& __obj)
569 auto __res = _Base::insert_or_assign(
571 return { { __res.first,
this }, __res.second };
575 template <
typename _Obj>
577 insert_or_assign(const_iterator __hint,
const key_type& __k,
581 auto __it = _Base::insert_or_assign(__hint.
base(), __k,
583 return { __it,
this };
586 template <
typename _Obj>
588 insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
591 auto __it = _Base::insert_or_assign(__hint.
base(),
std::move(__k),
593 return { __it,
this };
596# ifdef __glibcxx_associative_heterogeneous_insertion
597 template <__heterogeneous_hash_key<unordered_map> _Kt,
typename _Obj>
599 insert_or_assign(const_iterator __hint, _Kt&& __k, _Obj&& __obj)
602 auto __it = _Base::insert_or_assign(__hint.
base(),
604 return { __it,
this };
610#ifdef __glibcxx_node_extract
611 using node_type =
typename _Base::node_type;
612 using insert_return_type = _Node_insert_return<iterator, node_type>;
615 extract(const_iterator __position)
618 return _M_extract(__position.
base());
622 extract(
const key_type& __key)
624 const auto __position = _Base::find(__key);
625 if (__position != _Base::end())
626 return _M_extract(__position);
630# ifdef __glibcxx_associative_heterogeneous_erasure
631 template <__heterogeneous_hash_key<unordered_map> _Kt>
635 const auto __position = _Base::find(__key);
636 if (__position != _Base::end())
637 return _M_extract(__position);
643 insert(node_type&& __nh)
645 auto __ret = _Base::insert(
std::move(__nh));
647 { { __ret.position,
this }, __ret.inserted,
std::move(__ret.node) };
651 insert(const_iterator __hint, node_type&& __nh)
654 return { _Base::insert(__hint.
base(),
std::move(__nh)),
this };
657 template<
typename _H2,
typename _P2>
659 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
662 = _Safe::_S_uc_guard(std::__detail::_Select1st{}, __source);
663 _Base::merge(__source);
666 template<
typename _H2,
typename _P2>
668 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
671 template<
typename _H2,
typename _P2>
676 = _Safe::_S_umc_guard(std::__detail::_Select1st{}, __source);
677 _Base::merge(__source);
680 template<
typename _H2,
typename _P2>
686 using _Base::hash_function;
690 find(
const key_type& __key)
691 {
return { _Base::find(__key),
this }; }
693#ifdef __glibcxx_generic_unordered_lookup
694 template<
typename _Kt,
695 typename = std::__has_is_transparent_t<_Hash, _Kt>,
696 typename = std::__has_is_transparent_t<_Pred, _Kt>>
699 {
return { _Base::find(__k),
this }; }
703 find(
const key_type& __key)
const
704 {
return { _Base::find(__key),
this }; }
706#ifdef __glibcxx_generic_unordered_lookup
707 template<
typename _Kt,
708 typename = std::__has_is_transparent_t<_Hash, _Kt>,
709 typename = std::__has_is_transparent_t<_Pred, _Kt>>
711 find(
const _Kt& __k)
const
712 {
return { _Base::find(__k),
this }; }
716#if __cplusplus > 201703L
717 using _Base::contains;
721 equal_range(
const key_type& __key)
723 auto __res = _Base::equal_range(__key);
724 return { { __res.first,
this }, { __res.second,
this } };
727#ifdef __glibcxx_generic_unordered_lookup
728 template<
typename _Kt,
729 typename = std::__has_is_transparent_t<_Hash, _Kt>,
730 typename = std::__has_is_transparent_t<_Pred, _Kt>>
732 equal_range(
const _Kt& __k)
734 auto __res = _Base::equal_range(__k);
735 return { { __res.first,
this }, { __res.second,
this } };
740 equal_range(
const key_type& __key)
const
742 auto __res = _Base::equal_range(__key);
743 return { { __res.first,
this }, { __res.second,
this } };
746#ifdef __glibcxx_generic_unordered_lookup
747 template<
typename _Kt,
748 typename = std::__has_is_transparent_t<_Hash, _Kt>,
749 typename = std::__has_is_transparent_t<_Pred, _Kt>>
751 equal_range(
const _Kt& __k)
const
753 auto __res = _Base::equal_range(__k);
754 return { { __res.first,
this }, { __res.second,
this } };
758 using _Base::operator[];
762 erase(
const key_type& __key)
765 auto __victim = _Base::find(__key);
766 if (__victim != _Base::end())
774# ifdef __glibcxx_associative_heterogeneous_erasure
775 template <__heterogeneous_hash_key<unordered_map> _Kt>
779 auto __victim = _Base::find(__key);
780 if (__victim != _Base::end())
781 return _M_erase(__victim), 1;
787 erase(const_iterator __it)
790 return { _M_erase(__it.
base()),
this };
794 erase(_Base_const_iterator __it)
796 __glibcxx_check_erase2(__it);
797 return _M_erase(__it);
804 return { _M_erase(__it.
base()),
this };
808 erase(const_iterator __first, const_iterator __last)
813 for (
auto __tmp = __first.base(); __tmp != __last.
base(); ++__tmp)
815 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
816 _M_message(__gnu_debug::__msg_valid_range)
817 ._M_iterator(__first,
"first")
818 ._M_iterator(__last,
"last"));
819 this->_M_invalidate(__tmp, sentry);
823 auto __next = _Base::erase(__first.base(), __last.
base());
824 return { __next,
this };
828 using _Base::reserve;
831 _M_base()
noexcept {
return *
this; }
834 _M_base()
const noexcept {
return *
this; }
838 _M_self()
const noexcept
842 _M_check_rehashed(size_type __prev_count)
844 if (__prev_count != this->bucket_count())
845 this->_M_invalidate_all();
849 _M_erase(_Base_const_iterator __victim)
851 this->_M_invalidate(__victim);
852 return _Base::erase(__victim);
855#ifdef __glibcxx_node_extract
857 _M_extract(_Base_const_iterator __victim)
859 this->_M_invalidate(__victim);
860 return _Base::extract(__victim);
865#if __cpp_deduction_guides >= 201606
867 template<
typename _InputIterator,
871 typename = _RequireInputIter<_InputIterator>,
872 typename = _RequireNotAllocatorOrIntegral<_Hash>,
873 typename = _RequireNotAllocator<_Pred>,
874 typename = _RequireAllocator<_Allocator>>
876 typename unordered_map<int, int>::size_type = {},
877 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
879 __iter_val_t<_InputIterator>,
880 _Hash, _Pred, _Allocator>;
882 template<
typename _Key,
typename _Tp,
typename _Hash = hash<_Key>,
883 typename _Pred = equal_to<_Key>,
884 typename _Allocator = allocator<pair<const _Key, _Tp>>,
885 typename = _RequireNotAllocatorOrIntegral<_Hash>,
886 typename = _RequireNotAllocator<_Pred>,
887 typename = _RequireAllocator<_Allocator>>
890 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
891 -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
893 template<
typename _InputIterator,
typename _Allocator,
894 typename = _RequireInputIter<_InputIterator>,
895 typename = _RequireAllocator<_Allocator>>
896 unordered_map(_InputIterator, _InputIterator,
897 typename unordered_map<int, int>::size_type, _Allocator)
898 -> unordered_map<__iter_key_t<_InputIterator>,
899 __iter_val_t<_InputIterator>,
900 hash<__iter_key_t<_InputIterator>>,
901 equal_to<__iter_key_t<_InputIterator>>,
904 template<
typename _InputIterator,
typename _Allocator,
905 typename = _RequireInputIter<_InputIterator>,
906 typename = _RequireAllocator<_Allocator>>
907 unordered_map(_InputIterator, _InputIterator, _Allocator)
908 -> unordered_map<__iter_key_t<_InputIterator>,
909 __iter_val_t<_InputIterator>,
910 hash<__iter_key_t<_InputIterator>>,
911 equal_to<__iter_key_t<_InputIterator>>,
914 template<
typename _InputIterator,
typename _Hash,
typename _Allocator,
915 typename = _RequireInputIter<_InputIterator>,
916 typename = _RequireNotAllocatorOrIntegral<_Hash>,
917 typename = _RequireAllocator<_Allocator>>
918 unordered_map(_InputIterator, _InputIterator,
919 typename unordered_map<int, int>::size_type,
921 -> unordered_map<__iter_key_t<_InputIterator>,
922 __iter_val_t<_InputIterator>, _Hash,
923 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
925 template<
typename _Key,
typename _Tp,
typename _Allocator,
926 typename = _RequireAllocator<_Allocator>>
928 typename unordered_map<int, int>::size_type,
930 -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
932 template<
typename _Key,
typename _Tp,
typename _Allocator,
933 typename = _RequireAllocator<_Allocator>>
935 -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
937 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _Allocator,
938 typename = _RequireNotAllocatorOrIntegral<_Hash>,
939 typename = _RequireAllocator<_Allocator>>
941 typename unordered_map<int, int>::size_type,
943 -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
945#if __glibcxx_containers_ranges
946 template<ranges::input_range _Rg,
947 __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
948 __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
949 __allocator_like _Allocator =
950 allocator<__detail::__range_to_alloc_type<_Rg>>>
951 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type = {},
952 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
954 __detail::__range_mapped_type<_Rg>,
955 _Hash, _Pred, _Allocator>;
957 template<ranges::input_range _Rg,
958 __allocator_like _Allocator>
959 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type,
962 __detail::__range_mapped_type<_Rg>,
963 hash<__detail::__range_key_type<_Rg>>,
964 equal_to<__detail::__range_key_type<_Rg>>,
967 template<ranges::input_range _Rg,
968 __allocator_like _Allocator>
971 __detail::__range_mapped_type<_Rg>,
972 hash<__detail::__range_key_type<_Rg>>,
973 equal_to<__detail::__range_key_type<_Rg>>,
976 template<ranges::input_range _Rg,
977 __not_allocator_like _Hash,
978 __allocator_like _Allocator>
979 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type,
982 __detail::__range_mapped_type<_Rg>,
983 _Hash, equal_to<__detail::__range_key_type<_Rg>>,
988 template<
typename _Key,
typename _Tp,
typename _Hash,
989 typename _Pred,
typename _Alloc>
993 noexcept(
noexcept(__x.swap(__y)))
996 template<
typename _Key,
typename _Tp,
typename _Hash,
997 typename _Pred,
typename _Alloc>
1001 {
return __x._M_base() == __y._M_base(); }
1003#if __cpp_impl_three_way_comparison < 201907L
1004 template<
typename _Key,
typename _Tp,
typename _Hash,
1005 typename _Pred,
typename _Alloc>
1009 {
return !(__x == __y); }
1013 template<
typename _Key,
typename _Tp,
1014 typename _Hash = std::hash<_Key>,
1015 typename _Pred = std::equal_to<_Key>,
1016 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
1017 class unordered_multimap
1019 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
1020 __gnu_debug::_Safe_unordered_container>,
1021 public _GLIBCXX_STD_C::unordered_multimap<
1022 _Key, _Tp, _Hash, _Pred, _Alloc>
1024 typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
1025 _Pred, _Alloc> _Base;
1028 typedef typename _Base::const_iterator _Base_const_iterator;
1029 typedef typename _Base::iterator _Base_iterator;
1030 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
1031 typedef typename _Base::local_iterator _Base_local_iterator;
1033 template<
typename _ItT,
typename _SeqT,
typename _CatT>
1034 friend class ::__gnu_debug::_Safe_iterator;
1035 template<
typename _ItT,
typename _SeqT>
1036 friend class ::__gnu_debug::_Safe_local_iterator;
1041 _Base_ref(
const _Base& __r) : _M_ref(__r) { }
1043 const _Base& _M_ref;
1047 typedef typename _Base::size_type size_type;
1048 typedef typename _Base::hasher hasher;
1049 typedef typename _Base::key_equal key_equal;
1050 typedef typename _Base::allocator_type allocator_type;
1052 typedef typename _Base::key_type key_type;
1053 typedef typename _Base::value_type value_type;
1054 typedef typename _Base::mapped_type mapped_type;
1056 typedef typename _Base::pointer pointer;
1057 typedef typename _Base::const_pointer const_pointer;
1058 typedef typename _Base::reference reference;
1059 typedef typename _Base::const_reference const_reference;
1061 _Base_iterator, unordered_multimap> iterator;
1063 _Base_const_iterator, unordered_multimap> const_iterator;
1065 _Base_local_iterator, unordered_multimap> local_iterator;
1067 _Base_const_local_iterator, unordered_multimap> const_local_iterator;
1068 typedef typename _Base::difference_type difference_type;
1070 unordered_multimap() =
default;
1073 unordered_multimap(size_type __n,
1074 const hasher& __hf = hasher(),
1075 const key_equal& __eql = key_equal(),
1076 const allocator_type& __a = allocator_type())
1077 : _Base(__n, __hf, __eql, __a) { }
1079 template<
typename _InputIterator>
1080 unordered_multimap(_InputIterator __first, _InputIterator __last,
1082 const hasher& __hf = hasher(),
1083 const key_equal& __eql = key_equal(),
1084 const allocator_type& __a = allocator_type())
1086 __glibcxx_check_valid_constructor_range(__first, __last)),
1088 __hf, __eql, __a) { }
1090 unordered_multimap(
const unordered_multimap&) =
default;
1092 unordered_multimap(_Base_ref __x)
1093 : _Base(__x._M_ref) { }
1095 unordered_multimap(unordered_multimap&&) =
default;
1098 unordered_multimap(
const allocator_type& __a)
1101 unordered_multimap(
const unordered_multimap& __umap,
1102 const allocator_type& __a)
1103 : _Base(__umap, __a) { }
1105 unordered_multimap(unordered_multimap&& __umap,
1106 const allocator_type& __a)
1107 noexcept(
noexcept(_Base(
std::move(__umap), __a)) )
1113 const hasher& __hf = hasher(),
1114 const key_equal& __eql = key_equal(),
1115 const allocator_type& __a = allocator_type())
1116 : _Base(__l, __n, __hf, __eql, __a) { }
1118 unordered_multimap(size_type __n,
const allocator_type& __a)
1119 : unordered_multimap(__n, hasher(), key_equal(), __a)
1122 unordered_multimap(size_type __n,
const hasher& __hf,
1123 const allocator_type& __a)
1124 : unordered_multimap(__n, __hf, key_equal(), __a)
1127 template<
typename _InputIterator>
1128 unordered_multimap(_InputIterator __first, _InputIterator __last,
1129 const allocator_type& __a)
1130 : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a)
1133 template<
typename _InputIterator>
1134 unordered_multimap(_InputIterator __first, _InputIterator __last,
1136 const allocator_type& __a)
1137 : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
1140 template<
typename _InputIterator>
1141 unordered_multimap(_InputIterator __first, _InputIterator __last,
1142 size_type __n,
const hasher& __hf,
1143 const allocator_type& __a)
1144 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
1148 const allocator_type& __a)
1149 : unordered_multimap(__l, 0, hasher(), key_equal(), __a)
1154 const allocator_type& __a)
1155 : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
1159 size_type __n,
const hasher& __hf,
1160 const allocator_type& __a)
1161 : unordered_multimap(__l, __n, __hf, key_equal(), __a)
1164#if __glibcxx_containers_ranges
1165 template<__detail::__container_compatible_range<value_type> _Rg>
1166 unordered_multimap(from_range_t, _Rg&& __rg,
1168 const hasher& __hf = hasher(),
1169 const key_equal& __eql = key_equal(),
1170 const allocator_type& __a = allocator_type())
1174 template<__detail::__container_compatible_range<value_type> _Rg>
1175 unordered_multimap(from_range_t, _Rg&& __rg,
const allocator_type& __a)
1179 template<__detail::__container_compatible_range<value_type> _Rg>
1180 unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1181 const allocator_type& __a)
1185 template<__detail::__container_compatible_range<value_type> _Rg>
1186 unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1187 const hasher& __hf,
const allocator_type& __a)
1192 ~unordered_multimap() =
default;
1195 operator=(
const unordered_multimap&) =
default;
1198 operator=(unordered_multimap&&) =
default;
1203 _Base::operator=(__l);
1204 this->_M_invalidate_all();
1208 using _Base::get_allocator;
1211 using _Base::max_size;
1214 swap(unordered_multimap& __x)
1217 _Safe::_M_swap(__x);
1225 this->_M_invalidate_all();
1230 {
return { _Base::begin(),
this }; }
1233 begin()
const noexcept
1234 {
return { _Base::begin(),
this }; }
1238 {
return { _Base::end(),
this }; }
1241 end()
const noexcept
1242 {
return { _Base::end(),
this }; }
1245 cbegin()
const noexcept
1246 {
return { _Base::cbegin(),
this }; }
1249 cend()
const noexcept
1250 {
return { _Base::cend(),
this }; }
1254 begin(size_type __b)
1256 __glibcxx_check_bucket_index(__b);
1257 return { _Base::begin(__b),
this };
1263 __glibcxx_check_bucket_index(__b);
1264 return { _Base::end(__b),
this };
1267 const_local_iterator
1268 begin(size_type __b)
const
1270 __glibcxx_check_bucket_index(__b);
1271 return { _Base::begin(__b),
this };
1274 const_local_iterator
1275 end(size_type __b)
const
1277 __glibcxx_check_bucket_index(__b);
1278 return { _Base::end(__b),
this };
1281 const_local_iterator
1282 cbegin(size_type __b)
const
1284 __glibcxx_check_bucket_index(__b);
1285 return { _Base::cbegin(__b),
this };
1288 const_local_iterator
1289 cend(size_type __b)
const
1291 __glibcxx_check_bucket_index(__b);
1292 return { _Base::cend(__b),
this };
1295 using _Base::bucket_count;
1296 using _Base::max_bucket_count;
1297 using _Base::bucket;
1300 bucket_size(size_type __b)
const
1302 __glibcxx_check_bucket_index(__b);
1303 return _Base::bucket_size(__b);
1307 max_load_factor()
const noexcept
1308 {
return _Base::max_load_factor(); }
1311 max_load_factor(
float __f)
1313 __glibcxx_check_max_load_factor(__f);
1314 _Base::max_load_factor(__f);
1317 template<
typename... _Args>
1319 emplace(_Args&&... __args)
1321 size_type __bucket_count = this->bucket_count();
1323 _M_check_rehashed(__bucket_count);
1324 return { __it,
this };
1327 template<
typename... _Args>
1329 emplace_hint(const_iterator __hint, _Args&&... __args)
1332 size_type __bucket_count = this->bucket_count();
1333 auto __it = _Base::emplace_hint(__hint.
base(),
1335 _M_check_rehashed(__bucket_count);
1336 return { __it,
this };
1340 insert(
const value_type& __obj)
1342 size_type __bucket_count = this->bucket_count();
1343 auto __it = _Base::insert(__obj);
1344 _M_check_rehashed(__bucket_count);
1345 return { __it,
this };
1351 insert(value_type&& __x)
1353 size_type __bucket_count = this->bucket_count();
1354 auto __it = _Base::insert(
std::move(__x));
1355 _M_check_rehashed(__bucket_count);
1356 return { __it,
this };
1360 insert(const_iterator __hint,
const value_type& __obj)
1363 size_type __bucket_count = this->bucket_count();
1364 auto __it = _Base::insert(__hint.
base(), __obj);
1365 _M_check_rehashed(__bucket_count);
1366 return { __it,
this };
1372 insert(const_iterator __hint, value_type&& __x)
1375 size_type __bucket_count = this->bucket_count();
1377 _M_check_rehashed(__bucket_count);
1378 return { __it,
this };
1381 template<
typename _Pair,
typename =
typename
1385 insert(_Pair&& __obj)
1387 size_type __bucket_count = this->bucket_count();
1389 _M_check_rehashed(__bucket_count);
1390 return { __it,
this };
1393 template<
typename _Pair,
typename =
typename
1397 insert(const_iterator __hint, _Pair&& __obj)
1400 size_type __bucket_count = this->bucket_count();
1402 _M_check_rehashed(__bucket_count);
1403 return { __it,
this };
1408 { _Base::insert(__l); }
1410 template<
typename _InputIterator>
1412 insert(_InputIterator __first, _InputIterator __last)
1414 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
1415 __glibcxx_check_valid_range2(__first, __last, __dist);
1416 size_type __bucket_count = this->bucket_count();
1418 if (__dist.second >= __gnu_debug::__dp_sign)
1419 _Base::insert(__gnu_debug::__unsafe(__first),
1420 __gnu_debug::__unsafe(__last));
1422 _Base::insert(__first, __last);
1424 _M_check_rehashed(__bucket_count);
1427#ifdef __glibcxx_node_extract
1428 using node_type =
typename _Base::node_type;
1431 extract(const_iterator __position)
1434 return _M_extract(__position.
base());
1438 extract(
const key_type& __key)
1440 const auto __position = _Base::find(__key);
1441 if (__position != _Base::end())
1442 return _M_extract(__position);
1446# ifdef __glibcxx_associative_heterogeneous_erasure
1447 template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1449 extract(_Kt&& __key)
1451 const auto __position = _Base::find(__key);
1452 if (__position != _Base::end())
1453 return _M_extract(__position);
1459 insert(node_type&& __nh)
1460 {
return { _Base::insert(
std::move(__nh)),
this }; }
1463 insert(const_iterator __hint, node_type&& __nh)
1466 return { _Base::insert(__hint.
base(),
std::move(__nh)),
this };
1469 template<
typename _H2,
typename _P2>
1471 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
1474 = _Safe::_S_umc_guard(std::__detail::_Select1st{}, __source);
1475 _Base::merge(__source);
1478 template<
typename _H2,
typename _P2>
1480 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
1481 { merge(__source); }
1483 template<
typename _H2,
typename _P2>
1488 = _Safe::_S_uc_guard(std::__detail::_Select1st{}, __source);
1489 _Base::merge(__source);
1492 template<
typename _H2,
typename _P2>
1495 { merge(__source); }
1498 using _Base::hash_function;
1499 using _Base::key_eq;
1502 find(
const key_type& __key)
1503 {
return { _Base::find(__key),
this }; }
1505#ifdef __glibcxx_generic_unordered_lookup
1506 template<
typename _Kt,
1507 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1508 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1510 find(
const _Kt& __k)
1511 {
return { _Base::find(__k),
this }; }
1515 find(
const key_type& __key)
const
1516 {
return { _Base::find(__key),
this }; }
1518#ifdef __glibcxx_generic_unordered_lookup
1519 template<
typename _Kt,
1520 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1521 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1523 find(
const _Kt& __k)
const
1524 {
return { _Base::find(__k),
this }; }
1528#if __cplusplus > 201703L
1529 using _Base::contains;
1533 equal_range(
const key_type& __key)
1535 auto __res = _Base::equal_range(__key);
1536 return { { __res.first,
this }, { __res.second,
this } };
1539#ifdef __glibcxx_generic_unordered_lookup
1540 template<
typename _Kt,
1541 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1542 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1544 equal_range(
const _Kt& __k)
1546 auto __res = _Base::equal_range(__k);
1547 return { { __res.first,
this }, { __res.second,
this } };
1552 equal_range(
const key_type& __key)
const
1554 auto __res = _Base::equal_range(__key);
1555 return { { __res.first,
this }, { __res.second,
this } };
1558#ifdef __glibcxx_generic_unordered_lookup
1559 template<
typename _Kt,
1560 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1561 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1563 equal_range(
const _Kt& __k)
const
1565 auto __res = _Base::equal_range(__k);
1566 return { { __res.first,
this }, { __res.second,
this } };
1571 erase(
const key_type& __key)
1573 auto __victims = _Base::equal_range(__key);
1574 return _M_erase(__victims.first, __victims.second);
1577# ifdef __glibcxx_associative_heterogeneous_erasure
1578 template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1582 auto __victims = _Base::equal_range(__key);
1583 return _M_erase(__victims.first, __victims.second);
1588 erase(const_iterator __it)
1591 return { _M_erase(__it.
base()),
this };
1595 erase(_Base_const_iterator __it)
1597 __glibcxx_check_erase2(__it);
1598 return _M_erase(__it);
1602 erase(iterator __it)
1605 return { _M_erase(__it.
base()),
this };
1609 erase(const_iterator __first, const_iterator __last)
1614 for (
auto __tmp = __first.base(); __tmp != __last.
base(); ++__tmp)
1616 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
1617 _M_message(__gnu_debug::__msg_valid_range)
1618 ._M_iterator(__first,
"first")
1619 ._M_iterator(__last,
"last"));
1620 this->_M_invalidate(__tmp, sentry);
1624 auto __next = _Base::erase(__first.base(), __last.
base());
1625 return { __next,
this };
1628 using _Base::rehash;
1629 using _Base::reserve;
1632 _M_base()
noexcept {
return *
this; }
1635 _M_base()
const noexcept {
return *
this; }
1638 const unordered_multimap*
1639 _M_self()
const noexcept
1643 _M_check_rehashed(size_type __prev_count)
1645 if (__prev_count != this->bucket_count())
1646 this->_M_invalidate_all();
1650 _M_erase(_Base_const_iterator __victim)
1652 this->_M_invalidate(__victim);
1653 return _Base::erase(__victim);
1657 _M_erase(_Base_iterator __first, _Base_iterator __last)
1662 for (
auto __victim = __first; __victim != __last; ++__victim)
1664 this->_M_invalidate(__victim, sentry);
1669 _Base::erase(__first, __last);
1673#ifdef __glibcxx_node_extract
1675 _M_extract(_Base_const_iterator __victim)
1677 this->_M_invalidate(__victim);
1678 return _Base::extract(__victim);
1683#if __cpp_deduction_guides >= 201606
1685 template<
typename _InputIterator,
1689 typename = _RequireInputIter<_InputIterator>,
1690 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1691 typename = _RequireNotAllocator<_Pred>,
1692 typename = _RequireAllocator<_Allocator>>
1694 unordered_multimap<int, int>::size_type = {},
1695 _Hash = _Hash(), _Pred = _Pred(),
1696 _Allocator = _Allocator())
1698 __iter_val_t<_InputIterator>, _Hash, _Pred,
1701 template<
typename _Key,
typename _Tp,
typename _Hash = hash<_Key>,
1702 typename _Pred = equal_to<_Key>,
1703 typename _Allocator = allocator<pair<const _Key, _Tp>>,
1704 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1705 typename = _RequireNotAllocator<_Pred>,
1706 typename = _RequireAllocator<_Allocator>>
1709 _Hash = _Hash(), _Pred = _Pred(),
1710 _Allocator = _Allocator())
1711 -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
1713 template<
typename _InputIterator,
typename _Allocator,
1714 typename = _RequireInputIter<_InputIterator>,
1715 typename = _RequireAllocator<_Allocator>>
1716 unordered_multimap(_InputIterator, _InputIterator,
1717 unordered_multimap<int, int>::size_type, _Allocator)
1718 -> unordered_multimap<__iter_key_t<_InputIterator>,
1719 __iter_val_t<_InputIterator>,
1720 hash<__iter_key_t<_InputIterator>>,
1721 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1723 template<
typename _InputIterator,
typename _Allocator,
1724 typename = _RequireInputIter<_InputIterator>,
1725 typename = _RequireAllocator<_Allocator>>
1726 unordered_multimap(_InputIterator, _InputIterator, _Allocator)
1727 -> unordered_multimap<__iter_key_t<_InputIterator>,
1728 __iter_val_t<_InputIterator>,
1729 hash<__iter_key_t<_InputIterator>>,
1730 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1732 template<
typename _InputIterator,
typename _Hash,
typename _Allocator,
1733 typename = _RequireInputIter<_InputIterator>,
1734 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1735 typename = _RequireAllocator<_Allocator>>
1736 unordered_multimap(_InputIterator, _InputIterator,
1737 unordered_multimap<int, int>::size_type, _Hash,
1739 -> unordered_multimap<__iter_key_t<_InputIterator>,
1740 __iter_val_t<_InputIterator>, _Hash,
1741 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1743 template<
typename _Key,
typename _Tp,
typename _Allocator,
1744 typename = _RequireAllocator<_Allocator>>
1746 unordered_multimap<int, int>::size_type,
1748 -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1750 template<
typename _Key,
typename _Tp,
typename _Allocator,
1751 typename = _RequireAllocator<_Allocator>>
1753 -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1755 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _Allocator,
1756 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1757 typename = _RequireAllocator<_Allocator>>
1759 unordered_multimap<int, int>::size_type,
1761 -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
1763#if __glibcxx_containers_ranges
1764 template<ranges::input_range _Rg,
1765 __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
1766 __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
1767 __allocator_like _Allocator =
1768 allocator<__detail::__range_to_alloc_type<_Rg>>>
1769 unordered_multimap(from_range_t, _Rg&&,
1770 unordered_multimap<int, int>::size_type = {},
1771 _Hash = _Hash(), _Pred = _Pred(),
1772 _Allocator = _Allocator())
1774 __detail::__range_mapped_type<_Rg>,
1775 _Hash, _Pred, _Allocator>;
1777 template<ranges::input_range _Rg,
1778 __allocator_like _Allocator>
1782 __detail::__range_mapped_type<_Rg>,
1783 hash<__detail::__range_key_type<_Rg>>,
1784 equal_to<__detail::__range_key_type<_Rg>>,
1787 template<ranges::input_range _Rg,
1788 __allocator_like _Allocator>
1791 __detail::__range_mapped_type<_Rg>,
1792 hash<__detail::__range_key_type<_Rg>>,
1793 equal_to<__detail::__range_key_type<_Rg>>,
1796 template<ranges::input_range _Rg,
1797 __not_allocator_like _Hash,
1798 __allocator_like _Allocator>
1800 unordered_multimap<int, int>::size_type,
1803 __detail::__range_mapped_type<_Rg>,
1804 _Hash, equal_to<__detail::__range_key_type<_Rg>>,
1809 template<
typename _Key,
typename _Tp,
typename _Hash,
1810 typename _Pred,
typename _Alloc>
1814 noexcept(
noexcept(__x.swap(__y)))
1817 template<
typename _Key,
typename _Tp,
typename _Hash,
1818 typename _Pred,
typename _Alloc>
1822 {
return __x._M_base() == __y._M_base(); }
1824#if __cpp_impl_three_way_comparison < 201907L
1825 template<
typename _Key,
typename _Tp,
typename _Hash,
1826 typename _Pred,
typename _Alloc>
1830 {
return !(__x == __y); }
1835#ifdef __glibcxx_erase_if
1836_GLIBCXX_BEGIN_NAMESPACE_VERSION
1837 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _CPred,
1838 typename _Alloc,
typename _Predicate>
1840 _CPred, _Alloc>::size_type
1843 {
return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }
1845 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _CPred,
1846 typename _Alloc,
typename _Predicate>
1848 _CPred, _Alloc>::size_type
1851 {
return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }
1852_GLIBCXX_END_NAMESPACE_VERSION
#define __glibcxx_check_insert(_Position)
#define __glibcxx_check_erase_range(_First, _Last)
#define __glibcxx_check_erase(_Position)
pair(_T1, _T2) -> pair< _T1, _T2 >
Two pairs are equal iff their members are equal.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
ISO C++ entities toplevel namespace is std.
constexpr _Iterator __base(_Iterator __it)
GNU debug code, replaces standard behavior with debug behavior.
Primary class template hash.
Define a member typedef type only if a boolean constant is true.
The standard allocator, as per C++03 [20.4.1].
constexpr _Iterator & base() noexcept
Return the underlying iterator.
One of the comparison functors.
Struct holding two objects of arbitrary type.
A standard container composed of equivalent keys (possibly containing multiple of each key value) tha...
_Hashtable::size_type size_type
Iterator-related typedefs.
A standard container composed of unique keys (containing at most one of each key value) that associat...
_Hashtable::size_type size_type
Iterator-related typedefs.
Safe class dealing with some allocator dependent operations.
Base class for constructing a safe unordered container type that tracks iterators that reference it.
Class std::unordered_map with safety/checking/debug instrumentation.
Class std::unordered_multimap with safety/checking/debug instrumentation.