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 template <
typename... _Args>
505 try_emplace(const_iterator __hint,
const key_type& __k,
509 return { _Base::try_emplace(__hint.
base(), __k,
514 template <
typename... _Args>
516 try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
524 template <
typename _Obj>
526 insert_or_assign(
const key_type& __k, _Obj&& __obj)
528 auto __res = _Base::insert_or_assign(__k,
530 return { { __res.first,
this }, __res.second };
533 template <
typename _Obj>
535 insert_or_assign(key_type&& __k, _Obj&& __obj)
537 auto __res = _Base::insert_or_assign(
std::move(__k),
539 return { { __res.first,
this }, __res.second };
542 template <
typename _Obj>
544 insert_or_assign(const_iterator __hint,
const key_type& __k,
548 return { _Base::insert_or_assign(__hint.
base(), __k,
553 template <
typename _Obj>
555 insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj)
558 return { _Base::insert_or_assign(__hint.
base(),
std::move(__k),
564#ifdef __glibcxx_node_extract
565 using node_type =
typename _Base::node_type;
566 using insert_return_type = _Node_insert_return<iterator, node_type>;
569 extract(const_iterator __position)
572 return _M_extract(__position.
base());
576 extract(
const key_type& __key)
578 const auto __position = _Base::find(__key);
579 if (__position != _Base::end())
580 return _M_extract(__position);
584# ifdef __glibcxx_associative_heterogeneous_erasure
585 template <__heterogeneous_hash_key<unordered_map> _Kt>
589 const auto __position = _Base::find(__key);
590 if (__position != _Base::end())
591 return _M_extract(__position);
597 insert(node_type&& __nh)
599 auto __ret = _Base::insert(
std::move(__nh));
601 { { __ret.position,
this }, __ret.inserted,
std::move(__ret.node) };
605 insert(const_iterator __hint, node_type&& __nh)
608 return { _Base::insert(__hint.
base(),
std::move(__nh)),
this };
611 template<
typename _H2,
typename _P2>
613 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source)
616 = _Safe::_S_uc_guard(std::__detail::_Select1st{}, __source);
617 _Base::merge(__source);
620 template<
typename _H2,
typename _P2>
622 merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
625 template<
typename _H2,
typename _P2>
630 = _Safe::_S_umc_guard(std::__detail::_Select1st{}, __source);
631 _Base::merge(__source);
634 template<
typename _H2,
typename _P2>
640 using _Base::hash_function;
644 find(
const key_type& __key)
645 {
return { _Base::find(__key),
this }; }
647#ifdef __glibcxx_generic_unordered_lookup
648 template<
typename _Kt,
649 typename = std::__has_is_transparent_t<_Hash, _Kt>,
650 typename = std::__has_is_transparent_t<_Pred, _Kt>>
653 {
return { _Base::find(__k),
this }; }
657 find(
const key_type& __key)
const
658 {
return { _Base::find(__key),
this }; }
660#ifdef __glibcxx_generic_unordered_lookup
661 template<
typename _Kt,
662 typename = std::__has_is_transparent_t<_Hash, _Kt>,
663 typename = std::__has_is_transparent_t<_Pred, _Kt>>
665 find(
const _Kt& __k)
const
666 {
return { _Base::find(__k),
this }; }
670#if __cplusplus > 201703L
671 using _Base::contains;
675 equal_range(
const key_type& __key)
677 auto __res = _Base::equal_range(__key);
678 return { { __res.first,
this }, { __res.second,
this } };
681#ifdef __glibcxx_generic_unordered_lookup
682 template<
typename _Kt,
683 typename = std::__has_is_transparent_t<_Hash, _Kt>,
684 typename = std::__has_is_transparent_t<_Pred, _Kt>>
686 equal_range(
const _Kt& __k)
688 auto __res = _Base::equal_range(__k);
689 return { { __res.first,
this }, { __res.second,
this } };
694 equal_range(
const key_type& __key)
const
696 auto __res = _Base::equal_range(__key);
697 return { { __res.first,
this }, { __res.second,
this } };
700#ifdef __glibcxx_generic_unordered_lookup
701 template<
typename _Kt,
702 typename = std::__has_is_transparent_t<_Hash, _Kt>,
703 typename = std::__has_is_transparent_t<_Pred, _Kt>>
705 equal_range(
const _Kt& __k)
const
707 auto __res = _Base::equal_range(__k);
708 return { { __res.first,
this }, { __res.second,
this } };
712 using _Base::operator[];
716 erase(
const key_type& __key)
719 auto __victim = _Base::find(__key);
720 if (__victim != _Base::end())
728# ifdef __glibcxx_associative_heterogeneous_erasure
729 template <__heterogeneous_hash_key<unordered_map> _Kt>
733 auto __victim = _Base::find(__key);
734 if (__victim != _Base::end())
735 return _M_erase(__victim), 1;
741 erase(const_iterator __it)
744 return { _M_erase(__it.
base()),
this };
748 erase(_Base_const_iterator __it)
750 __glibcxx_check_erase2(__it);
751 return _M_erase(__it);
758 return { _M_erase(__it.
base()),
this };
762 erase(const_iterator __first, const_iterator __last)
765 for (
auto __tmp = __first.base(); __tmp != __last.
base(); ++__tmp)
767 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
768 _M_message(__gnu_debug::__msg_valid_range)
769 ._M_iterator(__first,
"first")
770 ._M_iterator(__last,
"last"));
771 _M_invalidate(__tmp);
774 size_type __bucket_count = this->bucket_count();
775 auto __next = _Base::erase(__first.base(), __last.
base());
776 _M_check_rehashed(__bucket_count);
777 return { __next,
this };
781 using _Base::reserve;
784 _M_base()
noexcept {
return *
this; }
787 _M_base()
const noexcept {
return *
this; }
791 _M_check_rehashed(size_type __prev_count)
793 if (__prev_count != this->bucket_count())
794 this->_M_invalidate_all();
798 _M_invalidate(_Base_const_iterator __victim)
800 this->_M_invalidate_if(
801 [__victim](_Base_const_iterator __it) {
return __it == __victim; });
802 this->_M_invalidate_local_if(
803 [__victim](_Base_const_local_iterator __it)
804 {
return __it == __victim; });
808 _M_erase(_Base_const_iterator __victim)
810 _M_invalidate(__victim);
811 size_type __bucket_count = this->bucket_count();
812 _Base_iterator __next = _Base::erase(__victim);
813 _M_check_rehashed(__bucket_count);
817#ifdef __glibcxx_node_extract
819 _M_extract(_Base_const_iterator __victim)
821 _M_invalidate(__victim);
822 return _Base::extract(__victim);
827#if __cpp_deduction_guides >= 201606
829 template<
typename _InputIterator,
833 typename = _RequireInputIter<_InputIterator>,
834 typename = _RequireNotAllocatorOrIntegral<_Hash>,
835 typename = _RequireNotAllocator<_Pred>,
836 typename = _RequireAllocator<_Allocator>>
838 typename unordered_map<int, int>::size_type = {},
839 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
841 __iter_val_t<_InputIterator>,
842 _Hash, _Pred, _Allocator>;
844 template<
typename _Key,
typename _Tp,
typename _Hash = hash<_Key>,
845 typename _Pred = equal_to<_Key>,
846 typename _Allocator = allocator<pair<const _Key, _Tp>>,
847 typename = _RequireNotAllocatorOrIntegral<_Hash>,
848 typename = _RequireNotAllocator<_Pred>,
849 typename = _RequireAllocator<_Allocator>>
852 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
853 -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>;
855 template<
typename _InputIterator,
typename _Allocator,
856 typename = _RequireInputIter<_InputIterator>,
857 typename = _RequireAllocator<_Allocator>>
858 unordered_map(_InputIterator, _InputIterator,
859 typename unordered_map<int, int>::size_type, _Allocator)
860 -> unordered_map<__iter_key_t<_InputIterator>,
861 __iter_val_t<_InputIterator>,
862 hash<__iter_key_t<_InputIterator>>,
863 equal_to<__iter_key_t<_InputIterator>>,
866 template<
typename _InputIterator,
typename _Allocator,
867 typename = _RequireInputIter<_InputIterator>,
868 typename = _RequireAllocator<_Allocator>>
869 unordered_map(_InputIterator, _InputIterator, _Allocator)
870 -> unordered_map<__iter_key_t<_InputIterator>,
871 __iter_val_t<_InputIterator>,
872 hash<__iter_key_t<_InputIterator>>,
873 equal_to<__iter_key_t<_InputIterator>>,
876 template<
typename _InputIterator,
typename _Hash,
typename _Allocator,
877 typename = _RequireInputIter<_InputIterator>,
878 typename = _RequireNotAllocatorOrIntegral<_Hash>,
879 typename = _RequireAllocator<_Allocator>>
880 unordered_map(_InputIterator, _InputIterator,
881 typename unordered_map<int, int>::size_type,
883 -> unordered_map<__iter_key_t<_InputIterator>,
884 __iter_val_t<_InputIterator>, _Hash,
885 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
887 template<
typename _Key,
typename _Tp,
typename _Allocator,
888 typename = _RequireAllocator<_Allocator>>
890 typename unordered_map<int, int>::size_type,
892 -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
894 template<
typename _Key,
typename _Tp,
typename _Allocator,
895 typename = _RequireAllocator<_Allocator>>
897 -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
899 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _Allocator,
900 typename = _RequireNotAllocatorOrIntegral<_Hash>,
901 typename = _RequireAllocator<_Allocator>>
903 typename unordered_map<int, int>::size_type,
905 -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
907#if __glibcxx_containers_ranges
908 template<ranges::input_range _Rg,
909 __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
910 __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
911 __allocator_like _Allocator =
912 allocator<__detail::__range_to_alloc_type<_Rg>>>
913 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type = {},
914 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
916 __detail::__range_mapped_type<_Rg>,
917 _Hash, _Pred, _Allocator>;
919 template<ranges::input_range _Rg,
920 __allocator_like _Allocator>
921 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type,
924 __detail::__range_mapped_type<_Rg>,
925 hash<__detail::__range_key_type<_Rg>>,
926 equal_to<__detail::__range_key_type<_Rg>>,
929 template<ranges::input_range _Rg,
930 __allocator_like _Allocator>
933 __detail::__range_mapped_type<_Rg>,
934 hash<__detail::__range_key_type<_Rg>>,
935 equal_to<__detail::__range_key_type<_Rg>>,
938 template<ranges::input_range _Rg,
939 __not_allocator_like _Hash,
940 __allocator_like _Allocator>
941 unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type,
944 __detail::__range_mapped_type<_Rg>,
945 _Hash, equal_to<__detail::__range_key_type<_Rg>>,
950 template<
typename _Key,
typename _Tp,
typename _Hash,
951 typename _Pred,
typename _Alloc>
955 noexcept(
noexcept(__x.swap(__y)))
958 template<
typename _Key,
typename _Tp,
typename _Hash,
959 typename _Pred,
typename _Alloc>
963 {
return __x._M_base() == __y._M_base(); }
965#if __cpp_impl_three_way_comparison < 201907L
966 template<
typename _Key,
typename _Tp,
typename _Hash,
967 typename _Pred,
typename _Alloc>
971 {
return !(__x == __y); }
975 template<
typename _Key,
typename _Tp,
976 typename _Hash = std::hash<_Key>,
977 typename _Pred = std::equal_to<_Key>,
978 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
979 class unordered_multimap
981 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
982 __gnu_debug::_Safe_unordered_container>,
983 public _GLIBCXX_STD_C::unordered_multimap<
984 _Key, _Tp, _Hash, _Pred, _Alloc>
986 typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
987 _Pred, _Alloc> _Base;
990 typedef typename _Base::const_iterator _Base_const_iterator;
991 typedef typename _Base::iterator _Base_iterator;
992 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
993 typedef typename _Base::local_iterator _Base_local_iterator;
995 template<
typename _ItT,
typename _SeqT,
typename _CatT>
996 friend class ::__gnu_debug::_Safe_iterator;
997 template<
typename _ItT,
typename _SeqT>
998 friend class ::__gnu_debug::_Safe_local_iterator;
1003 _Base_ref(
const _Base& __r) : _M_ref(__r) { }
1005 const _Base& _M_ref;
1009 typedef typename _Base::size_type size_type;
1010 typedef typename _Base::hasher hasher;
1011 typedef typename _Base::key_equal key_equal;
1012 typedef typename _Base::allocator_type allocator_type;
1014 typedef typename _Base::key_type key_type;
1015 typedef typename _Base::value_type value_type;
1016 typedef typename _Base::mapped_type mapped_type;
1018 typedef typename _Base::pointer pointer;
1019 typedef typename _Base::const_pointer const_pointer;
1020 typedef typename _Base::reference reference;
1021 typedef typename _Base::const_reference const_reference;
1023 _Base_iterator, unordered_multimap> iterator;
1025 _Base_const_iterator, unordered_multimap> const_iterator;
1027 _Base_local_iterator, unordered_multimap> local_iterator;
1029 _Base_const_local_iterator, unordered_multimap> const_local_iterator;
1030 typedef typename _Base::difference_type difference_type;
1032 unordered_multimap() =
default;
1035 unordered_multimap(size_type __n,
1036 const hasher& __hf = hasher(),
1037 const key_equal& __eql = key_equal(),
1038 const allocator_type& __a = allocator_type())
1039 : _Base(__n, __hf, __eql, __a) { }
1041 template<
typename _InputIterator>
1042 unordered_multimap(_InputIterator __first, _InputIterator __last,
1044 const hasher& __hf = hasher(),
1045 const key_equal& __eql = key_equal(),
1046 const allocator_type& __a = allocator_type())
1048 __glibcxx_check_valid_constructor_range(__first, __last)),
1050 __hf, __eql, __a) { }
1052 unordered_multimap(
const unordered_multimap&) =
default;
1054 unordered_multimap(_Base_ref __x)
1055 : _Base(__x._M_ref) { }
1057 unordered_multimap(unordered_multimap&&) =
default;
1060 unordered_multimap(
const allocator_type& __a)
1063 unordered_multimap(
const unordered_multimap& __umap,
1064 const allocator_type& __a)
1065 : _Base(__umap, __a) { }
1067 unordered_multimap(unordered_multimap&& __umap,
1068 const allocator_type& __a)
1069 noexcept(
noexcept(_Base(
std::move(__umap), __a)) )
1075 const hasher& __hf = hasher(),
1076 const key_equal& __eql = key_equal(),
1077 const allocator_type& __a = allocator_type())
1078 : _Base(__l, __n, __hf, __eql, __a) { }
1080 unordered_multimap(size_type __n,
const allocator_type& __a)
1081 : unordered_multimap(__n, hasher(), key_equal(), __a)
1084 unordered_multimap(size_type __n,
const hasher& __hf,
1085 const allocator_type& __a)
1086 : unordered_multimap(__n, __hf, key_equal(), __a)
1089 template<
typename _InputIterator>
1090 unordered_multimap(_InputIterator __first, _InputIterator __last,
1091 const allocator_type& __a)
1092 : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a)
1095 template<
typename _InputIterator>
1096 unordered_multimap(_InputIterator __first, _InputIterator __last,
1098 const allocator_type& __a)
1099 : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
1102 template<
typename _InputIterator>
1103 unordered_multimap(_InputIterator __first, _InputIterator __last,
1104 size_type __n,
const hasher& __hf,
1105 const allocator_type& __a)
1106 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
1110 const allocator_type& __a)
1111 : unordered_multimap(__l, 0, hasher(), key_equal(), __a)
1116 const allocator_type& __a)
1117 : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
1121 size_type __n,
const hasher& __hf,
1122 const allocator_type& __a)
1123 : unordered_multimap(__l, __n, __hf, key_equal(), __a)
1126#if __glibcxx_containers_ranges
1127 template<__detail::__container_compatible_range<value_type> _Rg>
1128 unordered_multimap(from_range_t, _Rg&& __rg,
1130 const hasher& __hf = hasher(),
1131 const key_equal& __eql = key_equal(),
1132 const allocator_type& __a = allocator_type())
1136 template<__detail::__container_compatible_range<value_type> _Rg>
1137 unordered_multimap(from_range_t, _Rg&& __rg,
const allocator_type& __a)
1141 template<__detail::__container_compatible_range<value_type> _Rg>
1142 unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1143 const allocator_type& __a)
1147 template<__detail::__container_compatible_range<value_type> _Rg>
1148 unordered_multimap(from_range_t, _Rg&& __rg, size_type __n,
1149 const hasher& __hf,
const allocator_type& __a)
1154 ~unordered_multimap() =
default;
1157 operator=(
const unordered_multimap&) =
default;
1160 operator=(unordered_multimap&&) =
default;
1165 _Base::operator=(__l);
1166 this->_M_invalidate_all();
1170 using _Base::get_allocator;
1173 using _Base::max_size;
1176 swap(unordered_multimap& __x)
1179 _Safe::_M_swap(__x);
1187 this->_M_invalidate_all();
1192 {
return { _Base::begin(),
this }; }
1195 begin()
const noexcept
1196 {
return { _Base::begin(),
this }; }
1200 {
return { _Base::end(),
this }; }
1203 end()
const noexcept
1204 {
return { _Base::end(),
this }; }
1207 cbegin()
const noexcept
1208 {
return { _Base::cbegin(),
this }; }
1211 cend()
const noexcept
1212 {
return { _Base::cend(),
this }; }
1216 begin(size_type __b)
1218 __glibcxx_check_bucket_index(__b);
1219 return { _Base::begin(__b),
this };
1225 __glibcxx_check_bucket_index(__b);
1226 return { _Base::end(__b),
this };
1229 const_local_iterator
1230 begin(size_type __b)
const
1232 __glibcxx_check_bucket_index(__b);
1233 return { _Base::begin(__b),
this };
1236 const_local_iterator
1237 end(size_type __b)
const
1239 __glibcxx_check_bucket_index(__b);
1240 return { _Base::end(__b),
this };
1243 const_local_iterator
1244 cbegin(size_type __b)
const
1246 __glibcxx_check_bucket_index(__b);
1247 return { _Base::cbegin(__b),
this };
1250 const_local_iterator
1251 cend(size_type __b)
const
1253 __glibcxx_check_bucket_index(__b);
1254 return { _Base::cend(__b),
this };
1257 using _Base::bucket_count;
1258 using _Base::max_bucket_count;
1259 using _Base::bucket;
1262 bucket_size(size_type __b)
const
1264 __glibcxx_check_bucket_index(__b);
1265 return _Base::bucket_size(__b);
1269 max_load_factor()
const noexcept
1270 {
return _Base::max_load_factor(); }
1273 max_load_factor(
float __f)
1275 __glibcxx_check_max_load_factor(__f);
1276 _Base::max_load_factor(__f);
1279 template<
typename... _Args>
1281 emplace(_Args&&... __args)
1283 size_type __bucket_count = this->bucket_count();
1285 _M_check_rehashed(__bucket_count);
1286 return { __it,
this };
1289 template<
typename... _Args>
1291 emplace_hint(const_iterator __hint, _Args&&... __args)
1294 size_type __bucket_count = this->bucket_count();
1295 auto __it = _Base::emplace_hint(__hint.
base(),
1297 _M_check_rehashed(__bucket_count);
1298 return { __it,
this };
1302 insert(
const value_type& __obj)
1304 size_type __bucket_count = this->bucket_count();
1305 auto __it = _Base::insert(__obj);
1306 _M_check_rehashed(__bucket_count);
1307 return { __it,
this };
1313 insert(value_type&& __x)
1315 size_type __bucket_count = this->bucket_count();
1316 auto __it = _Base::insert(
std::move(__x));
1317 _M_check_rehashed(__bucket_count);
1318 return { __it,
this };
1322 insert(const_iterator __hint,
const value_type& __obj)
1325 size_type __bucket_count = this->bucket_count();
1326 auto __it = _Base::insert(__hint.
base(), __obj);
1327 _M_check_rehashed(__bucket_count);
1328 return { __it,
this };
1334 insert(const_iterator __hint, value_type&& __x)
1337 size_type __bucket_count = this->bucket_count();
1339 _M_check_rehashed(__bucket_count);
1340 return { __it,
this };
1343 template<
typename _Pair,
typename =
typename
1347 insert(_Pair&& __obj)
1349 size_type __bucket_count = this->bucket_count();
1351 _M_check_rehashed(__bucket_count);
1352 return { __it,
this };
1355 template<
typename _Pair,
typename =
typename
1359 insert(const_iterator __hint, _Pair&& __obj)
1362 size_type __bucket_count = this->bucket_count();
1364 _M_check_rehashed(__bucket_count);
1365 return { __it,
this };
1370 { _Base::insert(__l); }
1372 template<
typename _InputIterator>
1374 insert(_InputIterator __first, _InputIterator __last)
1376 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
1377 __glibcxx_check_valid_range2(__first, __last, __dist);
1378 size_type __bucket_count = this->bucket_count();
1380 if (__dist.second >= __gnu_debug::__dp_sign)
1381 _Base::insert(__gnu_debug::__unsafe(__first),
1382 __gnu_debug::__unsafe(__last));
1384 _Base::insert(__first, __last);
1386 _M_check_rehashed(__bucket_count);
1389#ifdef __glibcxx_node_extract
1390 using node_type =
typename _Base::node_type;
1393 extract(const_iterator __position)
1396 return _M_extract(__position.
base());
1400 extract(
const key_type& __key)
1402 const auto __position = _Base::find(__key);
1403 if (__position != _Base::end())
1404 return _M_extract(__position);
1408# ifdef __glibcxx_associative_heterogeneous_erasure
1409 template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1411 extract(_Kt&& __key)
1413 const auto __position = _Base::find(__key);
1414 if (__position != _Base::end())
1415 return _M_extract(__position);
1421 insert(node_type&& __nh)
1422 {
return { _Base::insert(
std::move(__nh)),
this }; }
1425 insert(const_iterator __hint, node_type&& __nh)
1428 return { _Base::insert(__hint.
base(),
std::move(__nh)),
this };
1431 template<
typename _H2,
typename _P2>
1433 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source)
1436 = _Safe::_S_umc_guard(std::__detail::_Select1st{}, __source);
1437 _Base::merge(__source);
1440 template<
typename _H2,
typename _P2>
1442 merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
1443 { merge(__source); }
1445 template<
typename _H2,
typename _P2>
1450 = _Safe::_S_uc_guard(std::__detail::_Select1st{}, __source);
1451 _Base::merge(__source);
1454 template<
typename _H2,
typename _P2>
1457 { merge(__source); }
1460 using _Base::hash_function;
1461 using _Base::key_eq;
1464 find(
const key_type& __key)
1465 {
return { _Base::find(__key),
this }; }
1467#ifdef __glibcxx_generic_unordered_lookup
1468 template<
typename _Kt,
1469 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1470 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1472 find(
const _Kt& __k)
1473 {
return { _Base::find(__k),
this }; }
1477 find(
const key_type& __key)
const
1478 {
return { _Base::find(__key),
this }; }
1480#ifdef __glibcxx_generic_unordered_lookup
1481 template<
typename _Kt,
1482 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1483 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1485 find(
const _Kt& __k)
const
1486 {
return { _Base::find(__k),
this }; }
1490#if __cplusplus > 201703L
1491 using _Base::contains;
1495 equal_range(
const key_type& __key)
1497 auto __res = _Base::equal_range(__key);
1498 return { { __res.first,
this }, { __res.second,
this } };
1501#ifdef __glibcxx_generic_unordered_lookup
1502 template<
typename _Kt,
1503 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1504 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1506 equal_range(
const _Kt& __k)
1508 auto __res = _Base::equal_range(__k);
1509 return { { __res.first,
this }, { __res.second,
this } };
1514 equal_range(
const key_type& __key)
const
1516 auto __res = _Base::equal_range(__key);
1517 return { { __res.first,
this }, { __res.second,
this } };
1520#ifdef __glibcxx_generic_unordered_lookup
1521 template<
typename _Kt,
1522 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1523 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1525 equal_range(
const _Kt& __k)
const
1527 auto __res = _Base::equal_range(__k);
1528 return { { __res.first,
this }, { __res.second,
this } };
1533 erase(
const key_type& __key)
1536 size_type __bucket_count = this->bucket_count();
1537 auto __pair = _Base::equal_range(__key);
1538 for (
auto __victim = __pair.first; __victim != __pair.second;)
1540 _M_invalidate(__victim);
1541 __victim = _Base::erase(__victim);
1545 _M_check_rehashed(__bucket_count);
1549# ifdef __glibcxx_associative_heterogeneous_erasure
1550 template <__heterogeneous_hash_key<unordered_multimap> _Kt>
1554 size_type __count(0);
1555 auto __victims = _Base::equal_range(__key);
1556 for (
auto __victim = __victims.first; __victim != __victims.second;)
1558 _M_invalidate(__victim);
1559 __victim = _Base::erase(__victim);
1567 erase(const_iterator __it)
1570 return { _M_erase(__it.
base()),
this };
1574 erase(_Base_const_iterator __it)
1576 __glibcxx_check_erase2(__it);
1577 return _M_erase(__it);
1581 erase(iterator __it)
1584 return { _M_erase(__it.
base()),
this };
1588 erase(const_iterator __first, const_iterator __last)
1591 for (
auto __tmp = __first.base(); __tmp != __last.
base(); ++__tmp)
1593 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
1594 _M_message(__gnu_debug::__msg_valid_range)
1595 ._M_iterator(__first,
"first")
1596 ._M_iterator(__last,
"last"));
1597 _M_invalidate(__tmp);
1600 size_type __bucket_count = this->bucket_count();
1601 auto __next = _Base::erase(__first.base(), __last.
base());
1602 _M_check_rehashed(__bucket_count);
1603 return { __next,
this };
1606 using _Base::rehash;
1607 using _Base::reserve;
1610 _M_base()
noexcept {
return *
this; }
1613 _M_base()
const noexcept {
return *
this; }
1617 _M_check_rehashed(size_type __prev_count)
1619 if (__prev_count != this->bucket_count())
1620 this->_M_invalidate_all();
1624 _M_invalidate(_Base_const_iterator __victim)
1626 this->_M_invalidate_if(
1627 [__victim](_Base_const_iterator __it) {
return __it == __victim; });
1628 this->_M_invalidate_local_if(
1629 [__victim](_Base_const_local_iterator __it)
1630 {
return __it == __victim; });
1634 _M_erase(_Base_const_iterator __victim)
1636 _M_invalidate(__victim);
1637 size_type __bucket_count = this->bucket_count();
1638 _Base_iterator __next = _Base::erase(__victim);
1639 _M_check_rehashed(__bucket_count);
1643#ifdef __glibcxx_node_extract
1645 _M_extract(_Base_const_iterator __victim)
1647 _M_invalidate(__victim);
1648 return _Base::extract(__victim);
1653#if __cpp_deduction_guides >= 201606
1655 template<
typename _InputIterator,
1659 typename = _RequireInputIter<_InputIterator>,
1660 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1661 typename = _RequireNotAllocator<_Pred>,
1662 typename = _RequireAllocator<_Allocator>>
1664 unordered_multimap<int, int>::size_type = {},
1665 _Hash = _Hash(), _Pred = _Pred(),
1666 _Allocator = _Allocator())
1668 __iter_val_t<_InputIterator>, _Hash, _Pred,
1671 template<
typename _Key,
typename _Tp,
typename _Hash = hash<_Key>,
1672 typename _Pred = equal_to<_Key>,
1673 typename _Allocator = allocator<pair<const _Key, _Tp>>,
1674 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1675 typename = _RequireNotAllocator<_Pred>,
1676 typename = _RequireAllocator<_Allocator>>
1679 _Hash = _Hash(), _Pred = _Pred(),
1680 _Allocator = _Allocator())
1681 -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>;
1683 template<
typename _InputIterator,
typename _Allocator,
1684 typename = _RequireInputIter<_InputIterator>,
1685 typename = _RequireAllocator<_Allocator>>
1686 unordered_multimap(_InputIterator, _InputIterator,
1687 unordered_multimap<int, int>::size_type, _Allocator)
1688 -> unordered_multimap<__iter_key_t<_InputIterator>,
1689 __iter_val_t<_InputIterator>,
1690 hash<__iter_key_t<_InputIterator>>,
1691 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1693 template<
typename _InputIterator,
typename _Allocator,
1694 typename = _RequireInputIter<_InputIterator>,
1695 typename = _RequireAllocator<_Allocator>>
1696 unordered_multimap(_InputIterator, _InputIterator, _Allocator)
1697 -> unordered_multimap<__iter_key_t<_InputIterator>,
1698 __iter_val_t<_InputIterator>,
1699 hash<__iter_key_t<_InputIterator>>,
1700 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1702 template<
typename _InputIterator,
typename _Hash,
typename _Allocator,
1703 typename = _RequireInputIter<_InputIterator>,
1704 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1705 typename = _RequireAllocator<_Allocator>>
1706 unordered_multimap(_InputIterator, _InputIterator,
1707 unordered_multimap<int, int>::size_type, _Hash,
1709 -> unordered_multimap<__iter_key_t<_InputIterator>,
1710 __iter_val_t<_InputIterator>, _Hash,
1711 equal_to<__iter_key_t<_InputIterator>>, _Allocator>;
1713 template<
typename _Key,
typename _Tp,
typename _Allocator,
1714 typename = _RequireAllocator<_Allocator>>
1716 unordered_multimap<int, int>::size_type,
1718 -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1720 template<
typename _Key,
typename _Tp,
typename _Allocator,
1721 typename = _RequireAllocator<_Allocator>>
1723 -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>;
1725 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _Allocator,
1726 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1727 typename = _RequireAllocator<_Allocator>>
1729 unordered_multimap<int, int>::size_type,
1731 -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>;
1733#if __glibcxx_containers_ranges
1734 template<ranges::input_range _Rg,
1735 __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>,
1736 __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>,
1737 __allocator_like _Allocator =
1738 allocator<__detail::__range_to_alloc_type<_Rg>>>
1739 unordered_multimap(from_range_t, _Rg&&,
1740 unordered_multimap<int, int>::size_type = {},
1741 _Hash = _Hash(), _Pred = _Pred(),
1742 _Allocator = _Allocator())
1744 __detail::__range_mapped_type<_Rg>,
1745 _Hash, _Pred, _Allocator>;
1747 template<ranges::input_range _Rg,
1748 __allocator_like _Allocator>
1752 __detail::__range_mapped_type<_Rg>,
1753 hash<__detail::__range_key_type<_Rg>>,
1754 equal_to<__detail::__range_key_type<_Rg>>,
1757 template<ranges::input_range _Rg,
1758 __allocator_like _Allocator>
1761 __detail::__range_mapped_type<_Rg>,
1762 hash<__detail::__range_key_type<_Rg>>,
1763 equal_to<__detail::__range_key_type<_Rg>>,
1766 template<ranges::input_range _Rg,
1767 __not_allocator_like _Hash,
1768 __allocator_like _Allocator>
1770 unordered_multimap<int, int>::size_type,
1773 __detail::__range_mapped_type<_Rg>,
1774 _Hash, equal_to<__detail::__range_key_type<_Rg>>,
1779 template<
typename _Key,
typename _Tp,
typename _Hash,
1780 typename _Pred,
typename _Alloc>
1784 noexcept(
noexcept(__x.swap(__y)))
1787 template<
typename _Key,
typename _Tp,
typename _Hash,
1788 typename _Pred,
typename _Alloc>
1792 {
return __x._M_base() == __y._M_base(); }
1794#if __cpp_impl_three_way_comparison < 201907L
1795 template<
typename _Key,
typename _Tp,
typename _Hash,
1796 typename _Pred,
typename _Alloc>
1800 {
return !(__x == __y); }
1805#ifdef __glibcxx_erase_if
1806_GLIBCXX_BEGIN_NAMESPACE_VERSION
1807 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _CPred,
1808 typename _Alloc,
typename _Predicate>
1810 _CPred, _Alloc>::size_type
1813 {
return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }
1815 template<
typename _Key,
typename _Tp,
typename _Hash,
typename _CPred,
1816 typename _Alloc,
typename _Predicate>
1818 _CPred, _Alloc>::size_type
1821 {
return __detail::__erase_nodes_if(__cont, __cont._M_base(), __pred); }
1822_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.