1 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
3 // Copyright (C) 2003-2025 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file debug/unordered_set
26 * This file is a GNU debug extension to the Standard C++ Library.
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
37 # include <bits/c++0x_warning.h>
39 # include <bits/c++config.h>
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>
44 class unordered_multiset;
45 } } // namespace std::__debug
46 # include <unordered_set>
48 #include <debug/safe_unordered_container.h>
49 #include <debug/safe_container.h>
50 #include <debug/safe_iterator.h>
51 #include <debug/safe_local_iterator.h>
53 namespace std _GLIBCXX_VISIBILITY(default)
57 /// Class std::unordered_set with safety/checking/debug instrumentation.
58 template<typename _Value,
59 typename _Hash = std::hash<_Value>,
60 typename _Pred = std::equal_to<_Value>,
61 typename _Alloc = std::allocator<_Value> >
63 : public __gnu_debug::_Safe_container<
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;
70 typedef __gnu_debug::_Safe_container<
71 unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
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;
83 // Reference wrapper for base class. See PR libstdc++/90102.
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;
105 typedef __gnu_debug::_Safe_iterator<
106 _Base_iterator, unordered_set> iterator;
107 typedef __gnu_debug::_Safe_iterator<
108 _Base_const_iterator, unordered_set> const_iterator;
109 typedef __gnu_debug::_Safe_local_iterator<
110 _Base_local_iterator, unordered_set> local_iterator;
111 typedef __gnu_debug::_Safe_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())
129 : _Base(__gnu_debug::__base(
130 __glibcxx_check_valid_constructor_range(__first, __last)),
131 __gnu_debug::__base(__last), __n,
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>
367 std::pair<iterator, bool>
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)
380 __glibcxx_check_insert(__hint);
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 };
388 std::pair<iterator, bool>
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)
400 __glibcxx_check_insert(__hint);
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 };
407 std::pair<iterator, bool>
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 };
417 insert(const_iterator __hint, value_type&& __obj)
419 __glibcxx_check_insert(__hint);
420 size_type __bucket_count = this->bucket_count();
421 auto __it = _Base::insert(__hint.base(), std::move(__obj));
422 _M_check_rehashed(__bucket_count);
423 return { __it, this };
427 insert(std::initializer_list<value_type> __l)
429 size_type __bucket_count = this->bucket_count();
431 _M_check_rehashed(__bucket_count);
434 template<typename _InputIterator>
436 insert(_InputIterator __first, _InputIterator __last)
438 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
439 __glibcxx_check_valid_range2(__first, __last, __dist);
440 size_type __bucket_count = this->bucket_count();
442 if (__dist.second >= __gnu_debug::__dp_sign)
443 _Base::insert(__gnu_debug::__unsafe(__first),
444 __gnu_debug::__unsafe(__last));
446 _Base::insert(__first, __last);
448 _M_check_rehashed(__bucket_count);
451 #if __cplusplus > 201402L
452 using node_type = typename _Base::node_type;
453 using insert_return_type = _Node_insert_return<iterator, node_type>;
456 extract(const_iterator __position)
458 __glibcxx_check_erase(__position);
459 return _M_extract(__position.base());
463 extract(const key_type& __key)
465 const auto __position = _Base::find(__key);
466 if (__position != _Base::end())
467 return _M_extract(__position);
472 insert(node_type&& __nh)
474 auto __ret = _Base::insert(std::move(__nh));
476 { { __ret.position, this }, __ret.inserted, std::move(__ret.node) };
480 insert(const_iterator __hint, node_type&& __nh)
482 __glibcxx_check_insert(__hint);
483 return { _Base::insert(__hint.base(), std::move(__nh)), this };
486 template<typename _H2, typename _P2>
488 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
491 = _Safe::_S_uc_guard(std::__detail::_Identity{}, __source);
492 _Base::merge(__source);
495 template<typename _H2, typename _P2>
497 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
500 template<typename _H2, typename _P2>
502 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
505 = _Safe::_S_umc_guard(std::__detail::_Identity{}, __source);
506 _Base::merge(__source);
509 template<typename _H2, typename _P2>
511 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
515 using _Base::hash_function;
519 find(const key_type& __key)
520 { return { _Base::find(__key), this }; }
522 #if __cplusplus > 201703L
523 template<typename _Kt,
524 typename = std::__has_is_transparent_t<_Hash, _Kt>,
525 typename = std::__has_is_transparent_t<_Pred, _Kt>>
528 { return { _Base::find(__k), this }; }
532 find(const key_type& __key) const
533 { return { _Base::find(__key), this }; }
535 #if __cplusplus > 201703L
536 template<typename _Kt,
537 typename = std::__has_is_transparent_t<_Hash, _Kt>,
538 typename = std::__has_is_transparent_t<_Pred, _Kt>>
540 find(const _Kt& __k) const
541 { return { _Base::find(__k), this }; }
546 #if __cplusplus > 201703L
547 using _Base::contains;
550 std::pair<iterator, iterator>
551 equal_range(const key_type& __key)
553 auto __res = _Base::equal_range(__key);
554 return { { __res.first, this }, { __res.second, this } };
557 #if __cplusplus > 201703L
558 template<typename _Kt,
559 typename = std::__has_is_transparent_t<_Hash, _Kt>,
560 typename = std::__has_is_transparent_t<_Pred, _Kt>>
561 std::pair<iterator, iterator>
562 equal_range(const _Kt& __k)
564 auto __res = _Base::equal_range(__k);
565 return { { __res.first, this }, { __res.second, this } };
569 std::pair<const_iterator, const_iterator>
570 equal_range(const key_type& __key) const
572 auto __res = _Base::equal_range(__key);
573 return { { __res.first, this }, { __res.second, this } };
576 #if __cplusplus > 201703L
577 template<typename _Kt,
578 typename = std::__has_is_transparent_t<_Hash, _Kt>,
579 typename = std::__has_is_transparent_t<_Pred, _Kt>>
580 std::pair<const_iterator, const_iterator>
581 equal_range(const _Kt& __k) const
583 auto __res = _Base::equal_range(__k);
584 return { { __res.first, this }, { __res.second, this } };
589 erase(const key_type& __key)
592 auto __victim = _Base::find(__key);
593 if (__victim != _Base::end())
602 erase(const_iterator __it)
604 __glibcxx_check_erase(__it);
605 return { _M_erase(__it.base()), this };
609 erase(_Base_const_iterator __it)
611 __glibcxx_check_erase2(__it);
612 return _M_erase(__it);
618 __glibcxx_check_erase(__it);
619 return { _M_erase(__it.base()), this };
623 erase(const_iterator __first, const_iterator __last)
625 __glibcxx_check_erase_range(__first, __last);
626 for (auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
628 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
629 _M_message(__gnu_debug::__msg_valid_range)
630 ._M_iterator(__first, "first")
631 ._M_iterator(__last, "last"));
632 _M_invalidate(__tmp);
635 size_type __bucket_count = this->bucket_count();
636 auto __next = _Base::erase(__first.base(), __last.base());
637 _M_check_rehashed(__bucket_count);
638 return { __next, this };
642 _M_base() noexcept { return *this; }
645 _M_base() const noexcept { return *this; }
649 _M_check_rehashed(size_type __prev_count)
651 if (__prev_count != this->bucket_count())
652 this->_M_invalidate_all();
656 _M_invalidate(_Base_const_iterator __victim)
658 this->_M_invalidate_if(
659 [__victim](_Base_const_iterator __it) { return __it == __victim; });
660 this->_M_invalidate_local_if(
661 [__victim](_Base_const_local_iterator __it)
662 { return __it == __victim; });
666 _M_erase(_Base_const_iterator __victim)
668 _M_invalidate(__victim);
669 size_type __bucket_count = this->bucket_count();
670 _Base_iterator __next = _Base::erase(__victim);
671 _M_check_rehashed(__bucket_count);
675 #if __cplusplus > 201402L
677 _M_extract(_Base_const_iterator __victim)
679 _M_invalidate(__victim);
680 return _Base::extract(__victim);
685 #if __cpp_deduction_guides >= 201606
687 template<typename _InputIterator,
689 hash<typename iterator_traits<_InputIterator>::value_type>,
691 equal_to<typename iterator_traits<_InputIterator>::value_type>,
692 typename _Allocator =
693 allocator<typename iterator_traits<_InputIterator>::value_type>,
694 typename = _RequireInputIter<_InputIterator>,
695 typename = _RequireNotAllocatorOrIntegral<_Hash>,
696 typename = _RequireNotAllocator<_Pred>,
697 typename = _RequireAllocator<_Allocator>>
698 unordered_set(_InputIterator, _InputIterator,
699 unordered_set<int>::size_type = {},
700 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
701 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
702 _Hash, _Pred, _Allocator>;
704 template<typename _Tp, typename _Hash = hash<_Tp>,
705 typename _Pred = equal_to<_Tp>,
706 typename _Allocator = allocator<_Tp>,
707 typename = _RequireNotAllocatorOrIntegral<_Hash>,
708 typename = _RequireNotAllocator<_Pred>,
709 typename = _RequireAllocator<_Allocator>>
710 unordered_set(initializer_list<_Tp>,
711 unordered_set<int>::size_type = {},
712 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
713 -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
715 template<typename _InputIterator, typename _Allocator,
716 typename = _RequireInputIter<_InputIterator>,
717 typename = _RequireAllocator<_Allocator>>
718 unordered_set(_InputIterator, _InputIterator,
719 unordered_set<int>::size_type, _Allocator)
720 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
722 typename iterator_traits<_InputIterator>::value_type>,
724 typename iterator_traits<_InputIterator>::value_type>,
727 template<typename _InputIterator, typename _Allocator,
728 typename = _RequireInputIter<_InputIterator>,
729 typename = _RequireAllocator<_Allocator>>
730 unordered_set(_InputIterator, _InputIterator, _Allocator)
731 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
733 typename iterator_traits<_InputIterator>::value_type>,
735 typename iterator_traits<_InputIterator>::value_type>,
738 template<typename _InputIterator, typename _Hash, typename _Allocator,
739 typename = _RequireInputIter<_InputIterator>,
740 typename = _RequireNotAllocatorOrIntegral<_Hash>,
741 typename = _RequireAllocator<_Allocator>>
742 unordered_set(_InputIterator, _InputIterator,
743 unordered_set<int>::size_type,
745 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
748 typename iterator_traits<_InputIterator>::value_type>,
751 template<typename _Tp, typename _Allocator,
752 typename = _RequireAllocator<_Allocator>>
753 unordered_set(initializer_list<_Tp>,
754 unordered_set<int>::size_type, _Allocator)
755 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
757 template<typename _Tp, typename _Allocator,
758 typename = _RequireAllocator<_Allocator>>
759 unordered_set(initializer_list<_Tp>, _Allocator)
760 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
762 template<typename _Tp, typename _Hash, typename _Allocator,
763 typename = _RequireNotAllocatorOrIntegral<_Hash>,
764 typename = _RequireAllocator<_Allocator>>
765 unordered_set(initializer_list<_Tp>,
766 unordered_set<int>::size_type, _Hash, _Allocator)
767 -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
771 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
773 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
774 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
775 noexcept(noexcept(__x.swap(__y)))
778 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
780 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
781 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
782 { return __x._M_base() == __y._M_base(); }
784 #if __cpp_impl_three_way_comparison < 201907L
785 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
787 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
788 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
789 { return !(__x == __y); }
792 /// Class std::unordered_multiset with safety/checking/debug instrumentation.
793 template<typename _Value,
794 typename _Hash = std::hash<_Value>,
795 typename _Pred = std::equal_to<_Value>,
796 typename _Alloc = std::allocator<_Value> >
797 class unordered_multiset
798 : public __gnu_debug::_Safe_container<
799 unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
800 __gnu_debug::_Safe_unordered_container>,
801 public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
803 typedef _GLIBCXX_STD_C::unordered_multiset<
804 _Value, _Hash, _Pred, _Alloc> _Base;
805 typedef __gnu_debug::_Safe_container<unordered_multiset,
806 _Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
807 typedef typename _Base::const_iterator _Base_const_iterator;
808 typedef typename _Base::iterator _Base_iterator;
809 typedef typename _Base::const_local_iterator
810 _Base_const_local_iterator;
811 typedef typename _Base::local_iterator _Base_local_iterator;
813 template<typename _ItT, typename _SeqT, typename _CatT>
814 friend class ::__gnu_debug::_Safe_iterator;
815 template<typename _ItT, typename _SeqT>
816 friend class ::__gnu_debug::_Safe_local_iterator;
818 // Reference wrapper for base class. See PR libstdc++/90102.
821 _Base_ref(const _Base& __r) : _M_ref(__r) { }
827 typedef typename _Base::size_type size_type;
828 typedef typename _Base::difference_type difference_type;
829 typedef typename _Base::hasher hasher;
830 typedef typename _Base::key_equal key_equal;
831 typedef typename _Base::allocator_type allocator_type;
833 typedef typename _Base::key_type key_type;
834 typedef typename _Base::value_type value_type;
836 typedef typename _Base::pointer pointer;
837 typedef typename _Base::const_pointer const_pointer;
838 typedef typename _Base::reference reference;
839 typedef typename _Base::const_reference const_reference;
840 typedef __gnu_debug::_Safe_iterator<
841 _Base_iterator, unordered_multiset> iterator;
842 typedef __gnu_debug::_Safe_iterator<
843 _Base_const_iterator, unordered_multiset> const_iterator;
844 typedef __gnu_debug::_Safe_local_iterator<
845 _Base_local_iterator, unordered_multiset> local_iterator;
846 typedef __gnu_debug::_Safe_local_iterator<
847 _Base_const_local_iterator, unordered_multiset> const_local_iterator;
849 unordered_multiset() = default;
852 unordered_multiset(size_type __n,
853 const hasher& __hf = hasher(),
854 const key_equal& __eql = key_equal(),
855 const allocator_type& __a = allocator_type())
856 : _Base(__n, __hf, __eql, __a) { }
858 template<typename _InputIterator>
859 unordered_multiset(_InputIterator __first, _InputIterator __last,
861 const hasher& __hf = hasher(),
862 const key_equal& __eql = key_equal(),
863 const allocator_type& __a = allocator_type())
864 : _Base(__gnu_debug::__base(
865 __glibcxx_check_valid_constructor_range(__first, __last)),
866 __gnu_debug::__base(__last), __n,
867 __hf, __eql, __a) { }
869 unordered_multiset(const unordered_multiset&) = default;
871 unordered_multiset(_Base_ref __x)
872 : _Base(__x._M_ref) { }
874 unordered_multiset(unordered_multiset&&) = default;
877 unordered_multiset(const allocator_type& __a)
880 unordered_multiset(const unordered_multiset& __uset,
881 const allocator_type& __a)
882 : _Base(__uset, __a) { }
884 unordered_multiset(unordered_multiset&& __uset,
885 const allocator_type& __a)
886 noexcept( noexcept(_Base(std::move(__uset), __a)) )
887 : _Safe(std::move(__uset), __a),
888 _Base(std::move(__uset), __a) { }
890 unordered_multiset(initializer_list<value_type> __l,
892 const hasher& __hf = hasher(),
893 const key_equal& __eql = key_equal(),
894 const allocator_type& __a = allocator_type())
895 : _Base(__l, __n, __hf, __eql, __a) { }
897 unordered_multiset(size_type __n, const allocator_type& __a)
898 : unordered_multiset(__n, hasher(), key_equal(), __a)
901 unordered_multiset(size_type __n, const hasher& __hf,
902 const allocator_type& __a)
903 : unordered_multiset(__n, __hf, key_equal(), __a)
906 template<typename _InputIterator>
907 unordered_multiset(_InputIterator __first, _InputIterator __last,
908 const allocator_type& __a)
909 : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a)
912 template<typename _InputIterator>
913 unordered_multiset(_InputIterator __first, _InputIterator __last,
915 const allocator_type& __a)
916 : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
919 template<typename _InputIterator>
920 unordered_multiset(_InputIterator __first, _InputIterator __last,
921 size_type __n, const hasher& __hf,
922 const allocator_type& __a)
923 : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
926 unordered_multiset(initializer_list<value_type> __l,
927 const allocator_type& __a)
928 : unordered_multiset(__l, 0, hasher(), key_equal(), __a)
931 unordered_multiset(initializer_list<value_type> __l,
933 const allocator_type& __a)
934 : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
937 unordered_multiset(initializer_list<value_type> __l,
938 size_type __n, const hasher& __hf,
939 const allocator_type& __a)
940 : unordered_multiset(__l, __n, __hf, key_equal(), __a)
943 #if __glibcxx_containers_ranges // C++ >= 23
944 template<__detail::__container_compatible_range<value_type> _Rg>
945 unordered_multiset(from_range_t, _Rg&& __rg,
947 const hasher& __hf = hasher(),
948 const key_equal& __eql = key_equal(),
949 const allocator_type& __a = allocator_type())
950 : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __eql, __a)
953 template<__detail::__container_compatible_range<value_type> _Rg>
954 unordered_multiset(from_range_t, _Rg&& __rg, const allocator_type& __a)
955 : _Base(from_range, std::forward<_Rg>(__rg), __a)
958 template<__detail::__container_compatible_range<value_type> _Rg>
959 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
960 const allocator_type& __a)
961 : _Base(from_range, std::forward<_Rg>(__rg), __n, __a)
964 template<__detail::__container_compatible_range<value_type> _Rg>
965 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
966 const hasher& __hf, const allocator_type& __a)
967 : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __a)
971 ~unordered_multiset() = default;
974 operator=(const unordered_multiset&) = default;
977 operator=(unordered_multiset&&) = default;
980 operator=(initializer_list<value_type> __l)
982 _Base::operator=(__l);
983 this->_M_invalidate_all();
987 using _Base::get_allocator;
990 using _Base::max_size;
993 swap(unordered_multiset& __x)
994 noexcept( noexcept(declval<_Base&>().swap(__x)) )
1004 this->_M_invalidate_all();
1009 { return { _Base::begin(), this }; }
1012 begin() const noexcept
1013 { return { _Base::begin(), this }; }
1017 { return { _Base::end(), this }; }
1020 end() const noexcept
1021 { return { _Base::end(), this }; }
1024 cbegin() const noexcept
1025 { return { _Base::cbegin(), this }; }
1028 cend() const noexcept
1029 { return { _Base::cend(), this }; }
1033 begin(size_type __b)
1035 __glibcxx_check_bucket_index(__b);
1036 return { _Base::begin(__b), this };
1042 __glibcxx_check_bucket_index(__b);
1043 return { _Base::end(__b), this };
1046 const_local_iterator
1047 begin(size_type __b) const
1049 __glibcxx_check_bucket_index(__b);
1050 return { _Base::begin(__b), this };
1053 const_local_iterator
1054 end(size_type __b) const
1056 __glibcxx_check_bucket_index(__b);
1057 return { _Base::end(__b), this };
1060 const_local_iterator
1061 cbegin(size_type __b) const
1063 __glibcxx_check_bucket_index(__b);
1064 return { _Base::cbegin(__b), this };
1067 const_local_iterator
1068 cend(size_type __b) const
1070 __glibcxx_check_bucket_index(__b);
1071 return { _Base::cend(__b), this };
1074 using _Base::bucket_count;
1075 using _Base::max_bucket_count;
1078 bucket_size(size_type __b) const
1080 __glibcxx_check_bucket_index(__b);
1081 return _Base::bucket_size(__b);
1084 using _Base::bucket;
1085 using _Base::load_factor;
1088 max_load_factor() const noexcept
1089 { return _Base::max_load_factor(); }
1092 max_load_factor(float __f)
1094 __glibcxx_check_max_load_factor(__f);
1095 _Base::max_load_factor(__f);
1098 using _Base::rehash;
1099 using _Base::reserve;
1101 template<typename... _Args>
1103 emplace(_Args&&... __args)
1105 size_type __bucket_count = this->bucket_count();
1106 auto __it = _Base::emplace(std::forward<_Args>(__args)...);
1107 _M_check_rehashed(__bucket_count);
1108 return { __it, this };
1111 template<typename... _Args>
1113 emplace_hint(const_iterator __hint, _Args&&... __args)
1115 __glibcxx_check_insert(__hint);
1116 size_type __bucket_count = this->bucket_count();
1117 auto __it = _Base::emplace_hint(__hint.base(),
1118 std::forward<_Args>(__args)...);
1119 _M_check_rehashed(__bucket_count);
1120 return { __it, this };
1124 insert(const value_type& __obj)
1126 size_type __bucket_count = this->bucket_count();
1127 auto __it = _Base::insert(__obj);
1128 _M_check_rehashed(__bucket_count);
1129 return { __it, this };
1133 insert(const_iterator __hint, const value_type& __obj)
1135 __glibcxx_check_insert(__hint);
1136 size_type __bucket_count = this->bucket_count();
1137 auto __it = _Base::insert(__hint.base(), __obj);
1138 _M_check_rehashed(__bucket_count);
1139 return { __it, this };
1143 insert(value_type&& __obj)
1145 size_type __bucket_count = this->bucket_count();
1146 auto __it = _Base::insert(std::move(__obj));
1147 _M_check_rehashed(__bucket_count);
1148 return { __it, this };
1152 insert(const_iterator __hint, value_type&& __obj)
1154 __glibcxx_check_insert(__hint);
1155 size_type __bucket_count = this->bucket_count();
1156 auto __it = _Base::insert(__hint.base(), std::move(__obj));
1157 _M_check_rehashed(__bucket_count);
1158 return { __it, this };
1162 insert(std::initializer_list<value_type> __l)
1164 size_type __bucket_count = this->bucket_count();
1166 _M_check_rehashed(__bucket_count);
1169 template<typename _InputIterator>
1171 insert(_InputIterator __first, _InputIterator __last)
1173 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
1174 __glibcxx_check_valid_range2(__first, __last, __dist);
1175 size_type __bucket_count = this->bucket_count();
1177 if (__dist.second >= __gnu_debug::__dp_sign)
1178 _Base::insert(__gnu_debug::__unsafe(__first),
1179 __gnu_debug::__unsafe(__last));
1181 _Base::insert(__first, __last);
1183 _M_check_rehashed(__bucket_count);
1186 #if __cplusplus > 201402L
1187 using node_type = typename _Base::node_type;
1190 extract(const_iterator __position)
1192 __glibcxx_check_erase(__position);
1193 return _M_extract(__position.base());
1197 extract(const key_type& __key)
1199 const auto __position = _Base::find(__key);
1200 if (__position != _Base::end())
1201 return _M_extract(__position);
1206 insert(node_type&& __nh)
1207 { return { _Base::insert(std::move(__nh)), this }; }
1210 insert(const_iterator __hint, node_type&& __nh)
1212 __glibcxx_check_insert(__hint);
1213 return { _Base::insert(__hint.base(), std::move(__nh)), this };
1216 template<typename _H2, typename _P2>
1218 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
1221 = _Safe::_S_umc_guard(std::__detail::_Identity{}, __source);
1222 _Base::merge(__source);
1225 template<typename _H2, typename _P2>
1227 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
1228 { merge(__source); }
1230 template<typename _H2, typename _P2>
1232 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
1235 = _Safe::_S_uc_guard(std::__detail::_Identity{}, __source);
1236 _Base::merge(__source);
1239 template<typename _H2, typename _P2>
1241 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
1242 { merge(__source); }
1245 using _Base::hash_function;
1246 using _Base::key_eq;
1249 find(const key_type& __key)
1250 { return { _Base::find(__key), this }; }
1252 #if __cplusplus > 201703L
1253 template<typename _Kt,
1254 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1255 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1257 find(const _Kt& __k)
1258 { return { _Base::find(__k), this }; }
1262 find(const key_type& __key) const
1263 { return { _Base::find(__key), this }; }
1265 #if __cplusplus > 201703L
1266 template<typename _Kt,
1267 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1268 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1270 find(const _Kt& __k) const
1271 { return { _Base::find(__k), this }; }
1276 #if __cplusplus > 201703L
1277 using _Base::contains;
1280 std::pair<iterator, iterator>
1281 equal_range(const key_type& __key)
1283 auto __res = _Base::equal_range(__key);
1284 return { { __res.first, this }, { __res.second, this } };
1287 #if __cplusplus > 201703L
1288 template<typename _Kt,
1289 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1290 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1291 std::pair<iterator, iterator>
1292 equal_range(const _Kt& __k)
1294 auto __res = _Base::equal_range(__k);
1295 return { { __res.first, this }, { __res.second, this } };
1299 std::pair<const_iterator, const_iterator>
1300 equal_range(const key_type& __key) const
1302 auto __res = _Base::equal_range(__key);
1303 return { { __res.first, this }, { __res.second, this } };
1306 #if __cplusplus > 201703L
1307 template<typename _Kt,
1308 typename = std::__has_is_transparent_t<_Hash, _Kt>,
1309 typename = std::__has_is_transparent_t<_Pred, _Kt>>
1310 std::pair<const_iterator, const_iterator>
1311 equal_range(const _Kt& __k) const
1313 auto __res = _Base::equal_range(__k);
1314 return { { __res.first, this }, { __res.second, this } };
1319 erase(const key_type& __key)
1322 auto __pair = _Base::equal_range(__key);
1323 for (auto __victim = __pair.first; __victim != __pair.second;)
1325 _M_invalidate(__victim);
1326 __victim = _Base::erase(__victim);
1334 erase(const_iterator __it)
1336 __glibcxx_check_erase(__it);
1337 return { _M_erase(__it.base()), this };
1341 erase(_Base_const_iterator __it)
1343 __glibcxx_check_erase2(__it);
1344 return _M_erase(__it);
1348 erase(iterator __it)
1350 __glibcxx_check_erase(__it);
1351 return { _M_erase(__it.base()), this };
1355 erase(const_iterator __first, const_iterator __last)
1357 __glibcxx_check_erase_range(__first, __last);
1358 for (auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
1360 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
1361 _M_message(__gnu_debug::__msg_valid_range)
1362 ._M_iterator(__first, "first")
1363 ._M_iterator(__last, "last"));
1364 _M_invalidate(__tmp);
1366 return { _Base::erase(__first.base(), __last.base()), this };
1370 _M_base() noexcept { return *this; }
1373 _M_base() const noexcept { return *this; }
1377 _M_check_rehashed(size_type __prev_count)
1379 if (__prev_count != this->bucket_count())
1380 this->_M_invalidate_all();
1384 _M_invalidate(_Base_const_iterator __victim)
1386 this->_M_invalidate_if(
1387 [__victim](_Base_const_iterator __it) { return __it == __victim; });
1388 this->_M_invalidate_local_if(
1389 [__victim](_Base_const_local_iterator __it)
1390 { return __it == __victim; });
1394 _M_erase(_Base_const_iterator __victim)
1396 _M_invalidate(__victim);
1397 size_type __bucket_count = this->bucket_count();
1398 _Base_iterator __next = _Base::erase(__victim);
1399 _M_check_rehashed(__bucket_count);
1403 #if __cplusplus > 201402L
1405 _M_extract(_Base_const_iterator __victim)
1407 _M_invalidate(__victim);
1408 return _Base::extract(__victim);
1413 #if __cpp_deduction_guides >= 201606
1415 template<typename _InputIterator,
1417 hash<typename iterator_traits<_InputIterator>::value_type>,
1419 equal_to<typename iterator_traits<_InputIterator>::value_type>,
1420 typename _Allocator =
1421 allocator<typename iterator_traits<_InputIterator>::value_type>,
1422 typename = _RequireInputIter<_InputIterator>,
1423 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1424 typename = _RequireNotAllocator<_Pred>,
1425 typename = _RequireAllocator<_Allocator>>
1426 unordered_multiset(_InputIterator, _InputIterator,
1427 unordered_multiset<int>::size_type = {},
1428 _Hash = _Hash(), _Pred = _Pred(),
1429 _Allocator = _Allocator())
1430 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1431 _Hash, _Pred, _Allocator>;
1433 template<typename _Tp, typename _Hash = hash<_Tp>,
1434 typename _Pred = equal_to<_Tp>,
1435 typename _Allocator = allocator<_Tp>,
1436 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1437 typename = _RequireNotAllocator<_Pred>,
1438 typename = _RequireAllocator<_Allocator>>
1439 unordered_multiset(initializer_list<_Tp>,
1440 unordered_multiset<int>::size_type = {},
1441 _Hash = _Hash(), _Pred = _Pred(),
1442 _Allocator = _Allocator())
1443 -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1445 template<typename _InputIterator, typename _Allocator,
1446 typename = _RequireInputIter<_InputIterator>,
1447 typename = _RequireAllocator<_Allocator>>
1448 unordered_multiset(_InputIterator, _InputIterator,
1449 unordered_multiset<int>::size_type, _Allocator)
1450 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1452 iterator_traits<_InputIterator>::value_type>,
1454 iterator_traits<_InputIterator>::value_type>,
1457 template<typename _InputIterator, typename _Allocator,
1458 typename = _RequireInputIter<_InputIterator>,
1459 typename = _RequireAllocator<_Allocator>>
1460 unordered_multiset(_InputIterator, _InputIterator, _Allocator)
1461 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1463 iterator_traits<_InputIterator>::value_type>,
1465 iterator_traits<_InputIterator>::value_type>,
1468 template<typename _InputIterator, typename _Hash, typename _Allocator,
1469 typename = _RequireInputIter<_InputIterator>,
1470 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1471 typename = _RequireAllocator<_Allocator>>
1472 unordered_multiset(_InputIterator, _InputIterator,
1473 unordered_multiset<int>::size_type,
1475 -> unordered_multiset<typename
1476 iterator_traits<_InputIterator>::value_type,
1480 iterator_traits<_InputIterator>::value_type>,
1483 template<typename _Tp, typename _Allocator,
1484 typename = _RequireAllocator<_Allocator>>
1485 unordered_multiset(initializer_list<_Tp>,
1486 unordered_multiset<int>::size_type, _Allocator)
1487 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1489 template<typename _Tp, typename _Allocator,
1490 typename = _RequireAllocator<_Allocator>>
1491 unordered_multiset(initializer_list<_Tp>, _Allocator)
1492 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1494 template<typename _Tp, typename _Hash, typename _Allocator,
1495 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1496 typename = _RequireAllocator<_Allocator>>
1497 unordered_multiset(initializer_list<_Tp>,
1498 unordered_multiset<int>::size_type, _Hash, _Allocator)
1499 -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1501 #if __glibcxx_containers_ranges // C++ >= 23
1502 template<ranges::input_range _Rg,
1503 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
1504 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
1505 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
1506 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type = {},
1507 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1508 -> unordered_set<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
1510 template<ranges::input_range _Rg,
1511 __allocator_like _Allocator>
1512 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1514 -> unordered_set<ranges::range_value_t<_Rg>,
1515 hash<ranges::range_value_t<_Rg>>,
1516 equal_to<ranges::range_value_t<_Rg>>,
1519 template<ranges::input_range _Rg,
1520 __allocator_like _Allocator>
1521 unordered_set(from_range_t, _Rg&&, _Allocator)
1522 -> unordered_set<ranges::range_value_t<_Rg>,
1523 hash<ranges::range_value_t<_Rg>>,
1524 equal_to<ranges::range_value_t<_Rg>>,
1527 template<ranges::input_range _Rg,
1528 __not_allocator_like _Hash,
1529 __allocator_like _Allocator>
1530 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1532 -> unordered_set<ranges::range_value_t<_Rg>, _Hash,
1533 equal_to<ranges::range_value_t<_Rg>>,
1536 #if __glibcxx_containers_ranges // C++ >= 23
1537 template<ranges::input_range _Rg,
1538 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
1539 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
1540 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
1541 unordered_multiset(from_range_t, _Rg&&,
1542 unordered_multiset<int>::size_type = {},
1543 _Hash = _Hash(), _Pred = _Pred(),
1544 _Allocator = _Allocator())
1545 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
1547 template<ranges::input_range _Rg,
1548 __allocator_like _Allocator>
1549 unordered_multiset(from_range_t, _Rg&&, _Allocator)
1550 -> unordered_multiset<ranges::range_value_t<_Rg>,
1551 hash<ranges::range_value_t<_Rg>>,
1552 equal_to<ranges::range_value_t<_Rg>>,
1555 template<ranges::input_range _Rg,
1556 __allocator_like _Allocator>
1557 unordered_multiset(from_range_t, _Rg&&, unordered_multiset<int>::size_type,
1559 -> unordered_multiset<ranges::range_value_t<_Rg>,
1560 hash<ranges::range_value_t<_Rg>>,
1561 equal_to<ranges::range_value_t<_Rg>>,
1564 template<ranges::input_range _Rg,
1565 __not_allocator_like _Hash,
1566 __allocator_like _Allocator>
1567 unordered_multiset(from_range_t, _Rg&&,
1568 unordered_multiset<int>::size_type,
1570 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash,
1571 equal_to<ranges::range_value_t<_Rg>>,
1578 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1580 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1581 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1582 noexcept(noexcept(__x.swap(__y)))
1585 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1587 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1588 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1589 { return __x._M_base() == __y._M_base(); }
1591 #if __cpp_impl_three_way_comparison < 201907L
1592 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1594 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1595 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1596 { return !(__x == __y); }
1599 } // namespace __debug