29 #ifndef _GLIBCXX_DEBUG_UNORDERED_SET
30 #define _GLIBCXX_DEBUG_UNORDERED_SET 1
32 #ifdef _GLIBCXX_SYSHDR
33 #pragma GCC system_header
36 #if __cplusplus < 201103L
40 namespace std _GLIBCXX_VISIBILITY(default) {
namespace __debug {
41 template<
typename _Key,
typename _Hash,
typename _Pred,
typename _Allocator>
43 template<
typename _Key,
typename _Hash,
typename _Pred,
typename _Allocator>
53 namespace std _GLIBCXX_VISIBILITY(default)
58 template<
typename _Value,
64 unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
65 __gnu_debug::_Safe_unordered_container>,
66 public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
68 typedef _GLIBCXX_STD_C::unordered_set<
69 _Value, _Hash, _Pred, _Alloc> _Base;
73 typedef typename _Base::const_iterator _Base_const_iterator;
74 typedef typename _Base::iterator _Base_iterator;
75 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
76 typedef typename _Base::local_iterator _Base_local_iterator;
78 template<
typename _ItT,
typename _SeqT,
typename _CatT>
79 friend class ::__gnu_debug::_Safe_iterator;
80 template<
typename _ItT,
typename _SeqT>
81 friend class ::__gnu_debug::_Safe_local_iterator;
86 _Base_ref(
const _Base& __r) : _M_ref(__r) { }
92 typedef typename _Base::size_type size_type;
93 typedef typename _Base::difference_type difference_type;
94 typedef typename _Base::hasher hasher;
95 typedef typename _Base::key_equal key_equal;
96 typedef typename _Base::allocator_type allocator_type;
98 typedef typename _Base::key_type key_type;
99 typedef typename _Base::value_type value_type;
101 typedef typename _Base::pointer pointer;
102 typedef typename _Base::const_pointer const_pointer;
103 typedef typename _Base::reference reference;
104 typedef typename _Base::const_reference const_reference;
106 _Base_iterator, unordered_set> iterator;
108 _Base_const_iterator, unordered_set> const_iterator;
110 _Base_local_iterator, unordered_set> local_iterator;
112 _Base_const_local_iterator, unordered_set> const_local_iterator;
114 unordered_set() =
default;
117 unordered_set(size_type __n,
118 const hasher& __hf = hasher(),
119 const key_equal& __eql = key_equal(),
120 const allocator_type& __a = allocator_type())
121 : _Base(__n, __hf, __eql, __a) { }
123 template<
typename _InputIterator>
124 unordered_set(_InputIterator __first, _InputIterator __last,
126 const hasher& __hf = hasher(),
127 const key_equal& __eql = key_equal(),
128 const allocator_type& __a = allocator_type())
130 __glibcxx_check_valid_constructor_range(__first, __last)),
132 __hf, __eql, __a) { }
134 unordered_set(
const unordered_set&) =
default;
136 unordered_set(_Base_ref __x)
137 : _Base(__x._M_ref) { }
139 unordered_set(unordered_set&&) =
default;
142 unordered_set(
const allocator_type& __a)
145 unordered_set(
const unordered_set& __uset,
146 const allocator_type& __a)
147 : _Base(__uset, __a) { }
149 unordered_set(unordered_set&& __uset,
150 const allocator_type& __a)
151 noexcept( noexcept(_Base(
std::move(__uset), __a)) )
152 : _Safe(
std::
move(__uset), __a),
153 _Base(
std::
move(__uset), __a) { }
155 unordered_set(initializer_list<value_type> __l,
157 const hasher& __hf = hasher(),
158 const key_equal& __eql = key_equal(),
159 const allocator_type& __a = allocator_type())
160 : _Base(__l, __n, __hf, __eql, __a) { }
162 unordered_set(size_type __n,
const allocator_type& __a)
163 : unordered_set(__n, hasher(), key_equal(), __a)
166 unordered_set(size_type __n,
const hasher& __hf,
167 const allocator_type& __a)
168 : unordered_set(__n, __hf, key_equal(), __a)
171 template<
typename _InputIterator>
172 unordered_set(_InputIterator __first, _InputIterator __last,
173 const allocator_type& __a)
174 : unordered_set(__first, __last, 0, hasher(), key_equal(), __a)
177 template<
typename _InputIterator>
178 unordered_set(_InputIterator __first, _InputIterator __last,
180 const allocator_type& __a)
181 : unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
184 template<
typename _InputIterator>
185 unordered_set(_InputIterator __first, _InputIterator __last,
186 size_type __n,
const hasher& __hf,
187 const allocator_type& __a)
188 : unordered_set(__first, __last, __n, __hf, key_equal(), __a)
191 unordered_set(initializer_list<value_type> __l,
192 const allocator_type& __a)
193 : unordered_set(__l, 0, hasher(), key_equal(), __a)
196 unordered_set(initializer_list<value_type> __l,
198 const allocator_type& __a)
199 : unordered_set(__l, __n, hasher(), key_equal(), __a)
202 unordered_set(initializer_list<value_type> __l,
203 size_type __n,
const hasher& __hf,
204 const allocator_type& __a)
205 : unordered_set(__l, __n, __hf, key_equal(), __a)
208 #if __glibcxx_containers_ranges // C++ >= 23
209 template<__detail::__container_compatible_range<value_type> _Rg>
210 unordered_set(from_range_t, _Rg&& __rg,
212 const hasher& __hf = hasher(),
213 const key_equal& __eql = key_equal(),
214 const allocator_type& __a = allocator_type())
215 : _Base(from_range,
std::
forward<_Rg>(__rg), __n, __hf, __eql, __a)
218 template<__detail::__container_compatible_range<value_type> _Rg>
219 unordered_set(from_range_t, _Rg&& __rg,
const allocator_type& __a)
220 : _Base(from_range,
std::
forward<_Rg>(__rg), __a)
223 template<__detail::__container_compatible_range<value_type> _Rg>
224 unordered_set(from_range_t, _Rg&& __rg, size_type __n,
225 const allocator_type& __a)
226 : _Base(from_range,
std::
forward<_Rg>(__rg), __n, __a)
229 template<__detail::__container_compatible_range<value_type> _Rg>
230 unordered_set(from_range_t, _Rg&& __rg, size_type __n,
231 const hasher& __hf,
const allocator_type& __a)
232 : _Base(from_range,
std::
forward<_Rg>(__rg), __n, __hf, __a)
236 ~unordered_set() =
default;
239 operator=(
const unordered_set&) =
default;
242 operator=(unordered_set&&) =
default;
245 operator=(initializer_list<value_type> __l)
247 _Base::operator=(__l);
248 this->_M_invalidate_all();
252 using _Base::get_allocator;
255 using _Base::max_size;
258 swap(unordered_set& __x)
259 noexcept( noexcept(declval<_Base&>().swap(__x)) )
269 this->_M_invalidate_all();
274 {
return { _Base::begin(),
this }; }
277 begin() const noexcept
278 {
return { _Base::begin(),
this }; }
282 {
return { _Base::end(),
this }; }
286 {
return { _Base::end(),
this }; }
289 cbegin() const noexcept
290 {
return { _Base::cbegin(),
this }; }
293 cend() const noexcept
294 {
return { _Base::cend(),
this }; }
300 __glibcxx_check_bucket_index(__b);
301 return { _Base::begin(__b),
this };
307 __glibcxx_check_bucket_index(__b);
308 return { _Base::end(__b),
this };
312 begin(size_type __b)
const
314 __glibcxx_check_bucket_index(__b);
315 return { _Base::begin(__b),
this };
319 end(size_type __b)
const
321 __glibcxx_check_bucket_index(__b);
322 return { _Base::end(__b),
this };
326 cbegin(size_type __b)
const
328 __glibcxx_check_bucket_index(__b);
329 return { _Base::cbegin(__b),
this };
333 cend(size_type __b)
const
335 __glibcxx_check_bucket_index(__b);
336 return { _Base::cend(__b),
this };
339 using _Base::bucket_count;
340 using _Base::max_bucket_count;
343 bucket_size(size_type __b)
const
345 __glibcxx_check_bucket_index(__b);
346 return _Base::bucket_size(__b);
350 using _Base::load_factor;
353 max_load_factor() const noexcept
354 {
return _Base::max_load_factor(); }
357 max_load_factor(
float __f)
359 __glibcxx_check_max_load_factor(__f);
360 _Base::max_load_factor(__f);
364 using _Base::reserve;
366 template<
typename... _Args>
368 emplace(_Args&&... __args)
370 size_type __bucket_count = this->bucket_count();
371 auto __res = _Base::emplace(std::forward<_Args>(__args)...);
372 _M_check_rehashed(__bucket_count);
373 return { { __res.first,
this }, __res.second };
376 template<
typename... _Args>
378 emplace_hint(const_iterator __hint, _Args&&... __args)
381 size_type __bucket_count = this->bucket_count();
382 auto __it = _Base::emplace_hint(__hint.base(),
383 std::forward<_Args>(__args)...);
384 _M_check_rehashed(__bucket_count);
385 return { __it,
this };
389 insert(
const value_type& __obj)
391 size_type __bucket_count = this->bucket_count();
392 auto __res = _Base::insert(__obj);
393 _M_check_rehashed(__bucket_count);
394 return { { __res.first,
this }, __res.second };
398 insert(const_iterator __hint,
const value_type& __obj)
401 size_type __bucket_count = this->bucket_count();
402 auto __it = _Base::insert(__hint.base(), __obj);
403 _M_check_rehashed(__bucket_count);
404 return { __it,
this };
408 insert(value_type&& __obj)
410 size_type __bucket_count = this->bucket_count();
411 auto __res = _Base::insert(
std::move(__obj));
412 _M_check_rehashed(__bucket_count);
413 return { { __res.first,
this }, __res.second };
416 # ifdef __glibcxx_associative_heterogeneous_insertion
417 template <__heterogeneous_hash_key<unordered_set> _Kt>
421 size_type __bucket_count = this->bucket_count();
422 auto __res = _Base::insert(std::forward<_Kt>(__obj));
423 _M_check_rehashed(__bucket_count);
424 return { { __res.first,
this }, __res.second };
429 insert(const_iterator __hint, value_type&& __obj)
432 size_type __bucket_count = this->bucket_count();
433 auto __it = _Base::insert(__hint.base(),
std::move(__obj));
434 _M_check_rehashed(__bucket_count);
435 return { __it,
this };
438 # ifdef __glibcxx_associative_heterogeneous_insertion
439 template <__heterogeneous_hash_key<unordered_set> _Kt>
441 insert(const_iterator __hint, _Kt&& __obj)
444 size_type __bucket_count = this->bucket_count();
445 auto __it = _Base::insert(
446 __hint.base(), std::forward<_Kt>(__obj));
447 _M_check_rehashed(__bucket_count);
448 return { __it,
this };
455 size_type __bucket_count = this->bucket_count();
457 _M_check_rehashed(__bucket_count);
460 template<
typename _InputIterator>
462 insert(_InputIterator __first, _InputIterator __last)
465 __glibcxx_check_valid_range2(__first, __last, __dist);
466 size_type __bucket_count = this->bucket_count();
468 if (__dist.
second >= __gnu_debug::__dp_sign)
469 _Base::insert(__gnu_debug::__unsafe(__first),
470 __gnu_debug::__unsafe(__last));
472 _Base::insert(__first, __last);
474 _M_check_rehashed(__bucket_count);
477 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
478 using node_type =
typename _Base::node_type;
479 using insert_return_type = _Node_insert_return<iterator, node_type>;
482 extract(const_iterator __position)
485 return _M_extract(__position.base());
489 extract(
const key_type& __key)
491 const auto __position = _Base::find(__key);
492 if (__position != _Base::end())
493 return _M_extract(__position);
497 # ifdef __glibcxx_associative_heterogeneous_erasure
498 template <__heterogeneous_hash_key<unordered_set> _Kt>
502 const auto __position = _Base::find(__key);
503 if (__position != _Base::end())
504 return _M_extract(__position);
510 insert(node_type&& __nh)
512 auto __ret = _Base::insert(
std::move(__nh));
514 { { __ret.position,
this }, __ret.inserted,
std::move(__ret.node) };
518 insert(const_iterator __hint, node_type&& __nh)
521 return { _Base::insert(__hint.base(),
std::move(__nh)),
this };
524 template<
typename _H2,
typename _P2>
526 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
529 = _Safe::_S_uc_guard(std::__detail::_Identity{}, __source);
530 _Base::merge(__source);
533 template<
typename _H2,
typename _P2>
535 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
538 template<
typename _H2,
typename _P2>
540 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
543 = _Safe::_S_umc_guard(std::__detail::_Identity{}, __source);
544 _Base::merge(__source);
547 template<
typename _H2,
typename _P2>
549 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
553 using _Base::hash_function;
557 find(
const key_type& __key)
558 {
return { _Base::find(__key),
this }; }
560 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
561 template<
typename _Kt,
562 typename = std::__has_is_transparent_t<_Hash, _Kt>,
563 typename = std::__has_is_transparent_t<_Pred, _Kt>>
566 {
return { _Base::find(__k),
this }; }
570 find(
const key_type& __key)
const
571 {
return { _Base::find(__key),
this }; }
573 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
574 template<
typename _Kt,
575 typename = std::__has_is_transparent_t<_Hash, _Kt>,
576 typename = std::__has_is_transparent_t<_Pred, _Kt>>
578 find(
const _Kt& __k)
const
579 {
return { _Base::find(__k),
this }; }
584 #if __cplusplus > 201703L
585 using _Base::contains;
589 equal_range(
const key_type& __key)
591 auto __res = _Base::equal_range(__key);
592 return { { __res.first,
this }, { __res.second,
this } };
595 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
596 template<
typename _Kt,
597 typename = std::__has_is_transparent_t<_Hash, _Kt>,
598 typename = std::__has_is_transparent_t<_Pred, _Kt>>
600 equal_range(
const _Kt& __k)
602 auto __res = _Base::equal_range(__k);
603 return { { __res.first,
this }, { __res.second,
this } };
608 equal_range(
const key_type& __key)
const
610 auto __res = _Base::equal_range(__key);
611 return { { __res.first,
this }, { __res.second,
this } };
614 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
615 template<
typename _Kt,
616 typename = std::__has_is_transparent_t<_Hash, _Kt>,
617 typename = std::__has_is_transparent_t<_Pred, _Kt>>
619 equal_range(
const _Kt& __k)
const
621 auto __res = _Base::equal_range(__k);
622 return { { __res.first,
this }, { __res.second,
this } };
627 erase(
const key_type& __key)
630 auto __victim = _Base::find(__key);
631 if (__victim != _Base::end())
639 # ifdef __glibcxx_associative_heterogeneous_erasure
640 template <__heterogeneous_hash_key<unordered_set> _Kt>
644 auto __victim = _Base::find(__key);
645 if (__victim != _Base::end())
646 return _M_erase(__victim), 1;
652 erase(const_iterator __it)
655 return { _M_erase(__it.base()),
this };
659 erase(_Base_const_iterator __it)
661 __glibcxx_check_erase2(__it);
662 return _M_erase(__it);
669 return { _M_erase(__it.base()),
this };
673 erase(const_iterator __first, const_iterator __last)
678 for (
auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
680 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
681 _M_message(__gnu_debug::__msg_valid_range)
682 ._M_iterator(__first,
"first")
683 ._M_iterator(__last,
"last"));
684 this->_M_invalidate(__tmp, sentry);
688 auto __next = _Base::erase(__first.base(), __last.base());
689 return { __next,
this };
693 _M_base() noexcept {
return *
this; }
696 _M_base() const noexcept {
return *
this; }
700 _M_self() const noexcept
704 _M_check_rehashed(size_type __prev_count)
706 if (__prev_count != this->bucket_count())
707 this->_M_invalidate_all();
711 _M_erase(_Base_const_iterator __victim)
713 this->_M_invalidate(__victim);
714 return _Base::erase(__victim);
717 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
719 _M_extract(_Base_const_iterator __victim)
721 this->_M_invalidate(__victim);
722 return _Base::extract(__victim);
727 #if __cpp_deduction_guides >= 201606
729 template<
typename _InputIterator,
731 hash<typename iterator_traits<_InputIterator>::value_type>,
733 equal_to<typename iterator_traits<_InputIterator>::value_type>,
734 typename _Allocator =
735 allocator<typename iterator_traits<_InputIterator>::value_type>,
736 typename = _RequireInputIter<_InputIterator>,
737 typename = _RequireNotAllocatorOrIntegral<_Hash>,
738 typename = _RequireNotAllocator<_Pred>,
739 typename = _RequireAllocator<_Allocator>>
740 unordered_set(_InputIterator, _InputIterator,
741 unordered_set<int>::size_type = {},
742 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
743 -> unordered_set<
typename iterator_traits<_InputIterator>::value_type,
744 _Hash, _Pred, _Allocator>;
746 template<
typename _Tp,
typename _Hash = hash<_Tp>,
747 typename _Pred = equal_to<_Tp>,
748 typename _Allocator = allocator<_Tp>,
749 typename = _RequireNotAllocatorOrIntegral<_Hash>,
750 typename = _RequireNotAllocator<_Pred>,
751 typename = _RequireAllocator<_Allocator>>
752 unordered_set(initializer_list<_Tp>,
753 unordered_set<int>::size_type = {},
754 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
755 -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
757 template<
typename _InputIterator,
typename _Allocator,
758 typename = _RequireInputIter<_InputIterator>,
759 typename = _RequireAllocator<_Allocator>>
760 unordered_set(_InputIterator, _InputIterator,
761 unordered_set<int>::size_type, _Allocator)
762 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
764 typename iterator_traits<_InputIterator>::value_type>,
766 typename iterator_traits<_InputIterator>::value_type>,
769 template<
typename _InputIterator,
typename _Allocator,
770 typename = _RequireInputIter<_InputIterator>,
771 typename = _RequireAllocator<_Allocator>>
772 unordered_set(_InputIterator, _InputIterator, _Allocator)
773 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
775 typename iterator_traits<_InputIterator>::value_type>,
777 typename iterator_traits<_InputIterator>::value_type>,
780 template<
typename _InputIterator,
typename _Hash,
typename _Allocator,
781 typename = _RequireInputIter<_InputIterator>,
782 typename = _RequireNotAllocatorOrIntegral<_Hash>,
783 typename = _RequireAllocator<_Allocator>>
784 unordered_set(_InputIterator, _InputIterator,
785 unordered_set<int>::size_type,
787 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
790 typename iterator_traits<_InputIterator>::value_type>,
793 template<
typename _Tp,
typename _Allocator,
794 typename = _RequireAllocator<_Allocator>>
795 unordered_set(initializer_list<_Tp>,
796 unordered_set<int>::size_type, _Allocator)
797 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
799 template<
typename _Tp,
typename _Allocator,
800 typename = _RequireAllocator<_Allocator>>
801 unordered_set(initializer_list<_Tp>, _Allocator)
802 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
804 template<
typename _Tp,
typename _Hash,
typename _Allocator,
805 typename = _RequireNotAllocatorOrIntegral<_Hash>,
806 typename = _RequireAllocator<_Allocator>>
807 unordered_set(initializer_list<_Tp>,
808 unordered_set<int>::size_type, _Hash, _Allocator)
809 -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
813 template<
typename _Value,
typename _Hash,
typename _Pred,
typename _Alloc>
815 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
816 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
817 noexcept(noexcept(__x.swap(__y)))
820 template<
typename _Value,
typename _Hash,
typename _Pred,
typename _Alloc>
822 operator==(
const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
823 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
824 {
return __x._M_base() == __y._M_base(); }
826 #if __cpp_impl_three_way_comparison < 201907L
827 template<
typename _Value,
typename _Hash,
typename _Pred,
typename _Alloc>
829 operator!=(
const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
830 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
831 {
return !(__x == __y); }
835 template<
typename _Value,
839 class unordered_multiset
841 unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
842 __gnu_debug::_Safe_unordered_container>,
843 public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
845 typedef _GLIBCXX_STD_C::unordered_multiset<
846 _Value, _Hash, _Pred, _Alloc> _Base;
849 typedef typename _Base::const_iterator _Base_const_iterator;
850 typedef typename _Base::iterator _Base_iterator;
851 typedef typename _Base::const_local_iterator
852 _Base_const_local_iterator;
853 typedef typename _Base::local_iterator _Base_local_iterator;
855 template<
typename _ItT,
typename _SeqT,
typename _CatT>
856 friend class ::__gnu_debug::_Safe_iterator;
857 template<
typename _ItT,
typename _SeqT>
858 friend class ::__gnu_debug::_Safe_local_iterator;
863 _Base_ref(
const _Base& __r) : _M_ref(__r) { }
869 typedef typename _Base::size_type size_type;
870 typedef typename _Base::difference_type difference_type;
871 typedef typename _Base::hasher hasher;
872 typedef typename _Base::key_equal key_equal;
873 typedef typename _Base::allocator_type allocator_type;
875 typedef typename _Base::key_type key_type;
876 typedef typename _Base::value_type value_type;
878 typedef typename _Base::pointer pointer;
879 typedef typename _Base::const_pointer const_pointer;
880 typedef typename _Base::reference reference;
881 typedef typename _Base::const_reference const_reference;
883 _Base_iterator, unordered_multiset> iterator;
885 _Base_const_iterator, unordered_multiset> const_iterator;
887 _Base_local_iterator, unordered_multiset> local_iterator;
889 _Base_const_local_iterator, unordered_multiset> const_local_iterator;
891 unordered_multiset() =
default;
894 unordered_multiset(size_type __n,
895 const hasher& __hf = hasher(),
896 const key_equal& __eql = key_equal(),
897 const allocator_type& __a = allocator_type())
898 : _Base(__n, __hf, __eql, __a) { }
900 template<
typename _InputIterator>
901 unordered_multiset(_InputIterator __first, _InputIterator __last,
903 const hasher& __hf = hasher(),
904 const key_equal& __eql = key_equal(),
905 const allocator_type& __a = allocator_type())
907 __glibcxx_check_valid_constructor_range(__first, __last)),
909 __hf, __eql, __a) { }
911 unordered_multiset(
const unordered_multiset&) =
default;
913 unordered_multiset(_Base_ref __x)
914 : _Base(__x._M_ref) { }
916 unordered_multiset(unordered_multiset&&) =
default;
919 unordered_multiset(
const allocator_type& __a)
922 unordered_multiset(
const unordered_multiset& __uset,
923 const allocator_type& __a)
924 : _Base(__uset, __a) { }
926 unordered_multiset(unordered_multiset&& __uset,
927 const allocator_type& __a)
928 noexcept( noexcept(_Base(
std::move(__uset), __a)) )
929 : _Safe(
std::
move(__uset), __a),
930 _Base(
std::
move(__uset), __a) { }
932 unordered_multiset(initializer_list<value_type> __l,
934 const hasher& __hf = hasher(),
935 const key_equal& __eql = key_equal(),
936 const allocator_type& __a = allocator_type())
937 : _Base(__l, __n, __hf, __eql, __a) { }
939 unordered_multiset(size_type __n,
const allocator_type& __a)
940 : unordered_multiset(__n, hasher(), key_equal(), __a)
943 unordered_multiset(size_type __n,
const hasher& __hf,
944 const allocator_type& __a)
945 : unordered_multiset(__n, __hf, key_equal(), __a)
948 template<
typename _InputIterator>
949 unordered_multiset(_InputIterator __first, _InputIterator __last,
950 const allocator_type& __a)
951 : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a)
954 template<
typename _InputIterator>
955 unordered_multiset(_InputIterator __first, _InputIterator __last,
957 const allocator_type& __a)
958 : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
961 template<
typename _InputIterator>
962 unordered_multiset(_InputIterator __first, _InputIterator __last,
963 size_type __n,
const hasher& __hf,
964 const allocator_type& __a)
965 : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
968 unordered_multiset(initializer_list<value_type> __l,
969 const allocator_type& __a)
970 : unordered_multiset(__l, 0, hasher(), key_equal(), __a)
973 unordered_multiset(initializer_list<value_type> __l,
975 const allocator_type& __a)
976 : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
979 unordered_multiset(initializer_list<value_type> __l,
980 size_type __n,
const hasher& __hf,
981 const allocator_type& __a)
982 : unordered_multiset(__l, __n, __hf, key_equal(), __a)
985 #if __glibcxx_containers_ranges // C++ >= 23
986 template<__detail::__container_compatible_range<value_type> _Rg>
987 unordered_multiset(from_range_t, _Rg&& __rg,
989 const hasher& __hf = hasher(),
990 const key_equal& __eql = key_equal(),
991 const allocator_type& __a = allocator_type())
992 : _Base(from_range,
std::
forward<_Rg>(__rg), __n, __hf, __eql, __a)
995 template<__detail::__container_compatible_range<value_type> _Rg>
996 unordered_multiset(from_range_t, _Rg&& __rg,
const allocator_type& __a)
997 : _Base(from_range,
std::
forward<_Rg>(__rg), __a)
1000 template<__detail::__container_compatible_range<value_type> _Rg>
1001 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
1002 const allocator_type& __a)
1003 : _Base(from_range,
std::
forward<_Rg>(__rg), __n, __a)
1006 template<__detail::__container_compatible_range<value_type> _Rg>
1007 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
1008 const hasher& __hf,
const allocator_type& __a)
1009 : _Base(from_range,
std::
forward<_Rg>(__rg), __n, __hf, __a)
1013 ~unordered_multiset() =
default;
1016 operator=(
const unordered_multiset&) =
default;
1019 operator=(unordered_multiset&&) =
default;
1022 operator=(initializer_list<value_type> __l)
1024 _Base::operator=(__l);
1025 this->_M_invalidate_all();
1029 using _Base::get_allocator;
1032 using _Base::max_size;
1035 swap(unordered_multiset& __x)
1036 noexcept( noexcept(declval<_Base&>().swap(__x)) )
1038 _Safe::_M_swap(__x);
1046 this->_M_invalidate_all();
1051 {
return { _Base::begin(),
this }; }
1054 begin() const noexcept
1055 {
return { _Base::begin(),
this }; }
1059 {
return { _Base::end(),
this }; }
1062 end() const noexcept
1063 {
return { _Base::end(),
this }; }
1066 cbegin() const noexcept
1067 {
return { _Base::cbegin(),
this }; }
1070 cend() const noexcept
1071 {
return { _Base::cend(),
this }; }
1075 begin(size_type __b)
1077 __glibcxx_check_bucket_index(__b);
1078 return { _Base::begin(__b),
this };
1084 __glibcxx_check_bucket_index(__b);
1085 return { _Base::end(__b),
this };
1088 const_local_iterator
1089 begin(size_type __b)
const
1091 __glibcxx_check_bucket_index(__b);
1092 return { _Base::begin(__b),
this };
1095 const_local_iterator
1096 end(size_type __b)
const
1098 __glibcxx_check_bucket_index(__b);
1099 return { _Base::end(__b),
this };
1102 const_local_iterator
1103 cbegin(size_type __b)
const
1105 __glibcxx_check_bucket_index(__b);
1106 return { _Base::cbegin(__b),
this };
1109 const_local_iterator
1110 cend(size_type __b)
const
1112 __glibcxx_check_bucket_index(__b);
1113 return { _Base::cend(__b),
this };
1116 using _Base::bucket_count;
1117 using _Base::max_bucket_count;
1120 bucket_size(size_type __b)
const
1122 __glibcxx_check_bucket_index(__b);
1123 return _Base::bucket_size(__b);
1126 using _Base::bucket;
1127 using _Base::load_factor;
1130 max_load_factor() const noexcept
1131 {
return _Base::max_load_factor(); }
1134 max_load_factor(
float __f)
1136 __glibcxx_check_max_load_factor(__f);
1137 _Base::max_load_factor(__f);
1140 using _Base::rehash;
1141 using _Base::reserve;
1143 template<
typename... _Args>
1145 emplace(_Args&&... __args)
1147 size_type __bucket_count = this->bucket_count();
1148 auto __it = _Base::emplace(std::forward<_Args>(__args)...);
1149 _M_check_rehashed(__bucket_count);
1150 return { __it,
this };
1153 template<
typename... _Args>
1155 emplace_hint(const_iterator __hint, _Args&&... __args)
1158 size_type __bucket_count = this->bucket_count();
1159 auto __it = _Base::emplace_hint(__hint.base(),
1160 std::forward<_Args>(__args)...);
1161 _M_check_rehashed(__bucket_count);
1162 return { __it,
this };
1166 insert(
const value_type& __obj)
1168 size_type __bucket_count = this->bucket_count();
1169 auto __it = _Base::insert(__obj);
1170 _M_check_rehashed(__bucket_count);
1171 return { __it,
this };
1175 insert(const_iterator __hint,
const value_type& __obj)
1178 size_type __bucket_count = this->bucket_count();
1179 auto __it = _Base::insert(__hint.base(), __obj);
1180 _M_check_rehashed(__bucket_count);
1181 return { __it,
this };
1185 insert(value_type&& __obj)
1187 size_type __bucket_count = this->bucket_count();
1188 auto __it = _Base::insert(
std::move(__obj));
1189 _M_check_rehashed(__bucket_count);
1190 return { __it,
this };
1194 insert(const_iterator __hint, value_type&& __obj)
1197 size_type __bucket_count = this->bucket_count();
1198 auto __it = _Base::insert(__hint.base(),
std::move(__obj));
1199 _M_check_rehashed(__bucket_count);
1200 return { __it,
this };
1206 size_type __bucket_count = this->bucket_count();
1208 _M_check_rehashed(__bucket_count);
1211 template<
typename _InputIterator>
1213 insert(_InputIterator __first, _InputIterator __last)
1216 __glibcxx_check_valid_range2(__first, __last, __dist);
1217 size_type __bucket_count = this->bucket_count();
1219 if (__dist.
second >= __gnu_debug::__dp_sign)
1220 _Base::insert(__gnu_debug::__unsafe(__first),
1221 __gnu_debug::__unsafe(__last));
1223 _Base::insert(__first, __last);
1225 _M_check_rehashed(__bucket_count);
1228 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1229 using node_type =
typename _Base::node_type;
1232 extract(const_iterator __position)
1235 return _M_extract(__position.base());
1239 extract(
const key_type& __key)
1241 const auto __position = _Base::find(__key);
1242 if (__position != _Base::end())
1243 return _M_extract(__position);
1247 # ifdef __glibcxx_associative_heterogeneous_erasure
1248 template <__heterogeneous_hash_key<unordered_multiset> _Kt>
1250 extract(
const _Kt& __key)
1252 const auto __position = _Base::find(__key);
1253 return __position != _Base::end() ?
1254 _M_extract(__position) : node_type{};
1259 insert(node_type&& __nh)
1260 {
return { _Base::insert(
std::move(__nh)),
this }; }
1263 insert(const_iterator __hint, node_type&& __nh)
1266 return { _Base::insert(__hint.base(),
std::move(__nh)),
this };
1269 template<
typename _H2,
typename _P2>
1271 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
1274 = _Safe::_S_umc_guard(std::__detail::_Identity{}, __source);
1275 _Base::merge(__source);
1278 template<
typename _H2,
typename _P2>
1280 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
1281 { merge(__source); }
1283 template<
typename _H2,
typename _P2>
1285 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
1288 = _Safe::_S_uc_guard(std::__detail::_Identity{}, __source);
1289 _Base::merge(__source);
1292 template<
typename _H2,
typename _P2>
1294 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
1295 { merge(__source); }
1298 using _Base::hash_function;
1299 using _Base::key_eq;
1302 find(
const key_type& __key)
1303 {
return { _Base::find(__key),
this }; }
1305 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1306 template<
typename _Kt,
1307 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1308 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1310 find(
const _Kt& __k)
1311 {
return { _Base::find(__k),
this }; }
1315 find(
const key_type& __key)
const
1316 {
return { _Base::find(__key),
this }; }
1318 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1319 template<
typename _Kt,
1320 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1321 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1323 find(
const _Kt& __k)
const
1324 {
return { _Base::find(__k),
this }; }
1329 #if __cplusplus > 201703L
1330 using _Base::contains;
1334 equal_range(
const key_type& __key)
1336 auto __res = _Base::equal_range(__key);
1337 return { { __res.first,
this }, { __res.second,
this } };
1340 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1341 template<
typename _Kt,
1342 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1343 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1345 equal_range(
const _Kt& __k)
1347 auto __res = _Base::equal_range(__k);
1348 return { { __res.first,
this }, { __res.second,
this } };
1353 equal_range(
const key_type& __key)
const
1355 auto __res = _Base::equal_range(__key);
1356 return { { __res.first,
this }, { __res.second,
this } };
1359 #ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1360 template<
typename _Kt,
1361 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1362 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1364 equal_range(
const _Kt& __k)
const
1366 auto __res = _Base::equal_range(__k);
1367 return { { __res.first,
this }, { __res.second,
this } };
1372 erase(
const key_type& __key)
1374 auto __victims = _Base::equal_range(__key);
1375 return _M_erase(__victims.first, __victims.second);
1378 # ifdef __glibcxx_associative_heterogeneous_erasure
1379 template <__heterogeneous_hash_key<unordered_multiset> _Kt>
1383 auto __victims = _Base::equal_range(__key);
1384 return _M_erase(__victims.first, __victims.second);
1389 erase(const_iterator __it)
1392 return { _M_erase(__it.base()),
this };
1396 erase(_Base_const_iterator __it)
1398 __glibcxx_check_erase2(__it);
1399 return _M_erase(__it);
1403 erase(iterator __it)
1406 return { _M_erase(__it.base()),
this };
1410 erase(const_iterator __first, const_iterator __last)
1415 for (
auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
1417 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
1418 _M_message(__gnu_debug::__msg_valid_range)
1419 ._M_iterator(__first,
"first")
1420 ._M_iterator(__last,
"last"));
1421 this->_M_invalidate(__tmp, sentry);
1425 return { _Base::erase(__first.base(), __last.base()),
this };
1429 _M_base() noexcept {
return *
this; }
1432 _M_base() const noexcept {
return *
this; }
1435 const unordered_multiset*
1436 _M_self() const noexcept
1440 _M_check_rehashed(size_type __prev_count)
1442 if (__prev_count != this->bucket_count())
1443 this->_M_invalidate_all();
1447 _M_erase(_Base_const_iterator __victim)
1449 this->_M_invalidate(__victim);
1450 return _Base::erase(__victim);
1454 _M_erase(_Base_iterator __first, _Base_iterator __last)
1456 size_type __count(0);
1459 for (
auto __victim = __first; __victim != __last; ++__victim)
1461 this->_M_invalidate(__victim, sentry);
1466 _Base::erase(__first, __last);
1470 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1472 _M_extract(_Base_const_iterator __victim)
1474 this->_M_invalidate(__victim);
1475 return _Base::extract(__victim);
1480 #if __cpp_deduction_guides >= 201606
1482 template<
typename _InputIterator,
1484 hash<typename iterator_traits<_InputIterator>::value_type>,
1486 equal_to<typename iterator_traits<_InputIterator>::value_type>,
1487 typename _Allocator =
1488 allocator<typename iterator_traits<_InputIterator>::value_type>,
1489 typename = _RequireInputIter<_InputIterator>,
1490 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1491 typename = _RequireNotAllocator<_Pred>,
1492 typename = _RequireAllocator<_Allocator>>
1493 unordered_multiset(_InputIterator, _InputIterator,
1494 unordered_multiset<int>::size_type = {},
1495 _Hash = _Hash(), _Pred = _Pred(),
1496 _Allocator = _Allocator())
1497 -> unordered_multiset<
typename iterator_traits<_InputIterator>::value_type,
1498 _Hash, _Pred, _Allocator>;
1500 template<
typename _Tp,
typename _Hash = hash<_Tp>,
1501 typename _Pred = equal_to<_Tp>,
1502 typename _Allocator = allocator<_Tp>,
1503 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1504 typename = _RequireNotAllocator<_Pred>,
1505 typename = _RequireAllocator<_Allocator>>
1506 unordered_multiset(initializer_list<_Tp>,
1507 unordered_multiset<int>::size_type = {},
1508 _Hash = _Hash(), _Pred = _Pred(),
1509 _Allocator = _Allocator())
1510 -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1512 template<
typename _InputIterator,
typename _Allocator,
1513 typename = _RequireInputIter<_InputIterator>,
1514 typename = _RequireAllocator<_Allocator>>
1515 unordered_multiset(_InputIterator, _InputIterator,
1516 unordered_multiset<int>::size_type, _Allocator)
1517 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1519 iterator_traits<_InputIterator>::value_type>,
1521 iterator_traits<_InputIterator>::value_type>,
1524 template<
typename _InputIterator,
typename _Allocator,
1525 typename = _RequireInputIter<_InputIterator>,
1526 typename = _RequireAllocator<_Allocator>>
1527 unordered_multiset(_InputIterator, _InputIterator, _Allocator)
1528 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1530 iterator_traits<_InputIterator>::value_type>,
1532 iterator_traits<_InputIterator>::value_type>,
1535 template<
typename _InputIterator,
typename _Hash,
typename _Allocator,
1536 typename = _RequireInputIter<_InputIterator>,
1537 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1538 typename = _RequireAllocator<_Allocator>>
1539 unordered_multiset(_InputIterator, _InputIterator,
1540 unordered_multiset<int>::size_type,
1542 -> unordered_multiset<
typename
1543 iterator_traits<_InputIterator>::value_type,
1547 iterator_traits<_InputIterator>::value_type>,
1550 template<
typename _Tp,
typename _Allocator,
1551 typename = _RequireAllocator<_Allocator>>
1552 unordered_multiset(initializer_list<_Tp>,
1553 unordered_multiset<int>::size_type, _Allocator)
1554 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1556 template<
typename _Tp,
typename _Allocator,
1557 typename = _RequireAllocator<_Allocator>>
1558 unordered_multiset(initializer_list<_Tp>, _Allocator)
1559 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1561 template<
typename _Tp,
typename _Hash,
typename _Allocator,
1562 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1563 typename = _RequireAllocator<_Allocator>>
1564 unordered_multiset(initializer_list<_Tp>,
1565 unordered_multiset<int>::size_type, _Hash, _Allocator)
1566 -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1568 #if __glibcxx_containers_ranges // C++ >= 23
1569 template<ranges::input_range _Rg,
1570 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
1571 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
1572 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
1573 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type = {},
1574 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1575 -> unordered_set<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
1577 template<ranges::input_range _Rg,
1578 __allocator_like _Allocator>
1579 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1581 -> unordered_set<ranges::range_value_t<_Rg>,
1582 hash<ranges::range_value_t<_Rg>>,
1583 equal_to<ranges::range_value_t<_Rg>>,
1586 template<ranges::input_range _Rg,
1587 __allocator_like _Allocator>
1588 unordered_set(from_range_t, _Rg&&, _Allocator)
1589 -> unordered_set<ranges::range_value_t<_Rg>,
1590 hash<ranges::range_value_t<_Rg>>,
1591 equal_to<ranges::range_value_t<_Rg>>,
1594 template<ranges::input_range _Rg,
1595 __not_allocator_like _Hash,
1596 __allocator_like _Allocator>
1597 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1599 -> unordered_set<ranges::range_value_t<_Rg>, _Hash,
1600 equal_to<ranges::range_value_t<_Rg>>,
1603 #if __glibcxx_containers_ranges // C++ >= 23
1604 template<ranges::input_range _Rg,
1605 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
1606 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
1607 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
1608 unordered_multiset(from_range_t, _Rg&&,
1609 unordered_multiset<int>::size_type = {},
1610 _Hash = _Hash(), _Pred = _Pred(),
1611 _Allocator = _Allocator())
1612 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
1614 template<ranges::input_range _Rg,
1615 __allocator_like _Allocator>
1616 unordered_multiset(from_range_t, _Rg&&, _Allocator)
1617 -> unordered_multiset<ranges::range_value_t<_Rg>,
1618 hash<ranges::range_value_t<_Rg>>,
1619 equal_to<ranges::range_value_t<_Rg>>,
1622 template<ranges::input_range _Rg,
1623 __allocator_like _Allocator>
1624 unordered_multiset(from_range_t, _Rg&&, unordered_multiset<int>::size_type,
1626 -> unordered_multiset<ranges::range_value_t<_Rg>,
1627 hash<ranges::range_value_t<_Rg>>,
1628 equal_to<ranges::range_value_t<_Rg>>,
1631 template<ranges::input_range _Rg,
1632 __not_allocator_like _Hash,
1633 __allocator_like _Allocator>
1634 unordered_multiset(from_range_t, _Rg&&,
1635 unordered_multiset<int>::size_type,
1637 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash,
1638 equal_to<ranges::range_value_t<_Rg>>,
1645 template<
typename _Value,
typename _Hash,
typename _Pred,
typename _Alloc>
1647 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1648 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1649 noexcept(noexcept(__x.swap(__y)))
1652 template<
typename _Value,
typename _Hash,
typename _Pred,
typename _Alloc>
1654 operator==(
const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1655 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1656 {
return __x._M_base() == __y._M_base(); }
1658 #if __cpp_impl_three_way_comparison < 201907L
1659 template<
typename _Value,
typename _Hash,
typename _Pred,
typename _Alloc>
1661 operator!=(
const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1662 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1663 {
return !(__x == __y); }
1668 #ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED
1669 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1670 template<
typename _Key,
typename _Hash,
typename _CPred,
typename _Alloc,
1671 typename _Predicate>
1672 inline typename __debug::unordered_set<_Key, _Hash,
1673 _CPred, _Alloc>::size_type
1674 erase_if(__debug::unordered_set<_Key, _Hash, _CPred, _Alloc>&
__cont,
1676 {
return __detail::__erase_nodes_if(
__cont,
__cont._M_base(), __pred); }
1678 template<
typename _Key,
typename _Hash,
typename _CPred,
typename _Alloc,
1679 typename _Predicate>
1680 inline typename __debug::unordered_multiset<_Key, _Hash,
1681 _CPred, _Alloc>::size_type
1682 erase_if(__debug::unordered_multiset<_Key, _Hash, _CPred, _Alloc>&
__cont,
1684 {
return __detail::__erase_nodes_if(
__cont,
__cont._M_base(), __pred); }
1685 _GLIBCXX_END_NAMESPACE_VERSION
1686 #endif // __glibcxx_erase_if