1// Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
2
3// Copyright (C) 2003-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file debug/unordered_set
26 *  This file is a GNU debug extension to the Standard C++ Library.
27 */
28
29#ifndef _GLIBCXX_DEBUG_UNORDERED_SET
30#define _GLIBCXX_DEBUG_UNORDERED_SET 1
31
32#pragma GCC system_header
33
34#if __cplusplus < 201103L
35# include <bits/c++0x_warning.h>
36#else
37# include <bits/c++config.h>
38namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
39  template<typename _Key, typename _Hash, typename _Pred, typename _Allocator>
40    class unordered_set;
41  template<typename _Key, typename _Hash, typename _Pred, typename _Allocator>
42    class unordered_multiset;
43} } // namespace std::__debug
44# include <unordered_set>
45
46#include <debug/safe_unordered_container.h>
47#include <debug/safe_container.h>
48#include <debug/safe_iterator.h>
49#include <debug/safe_local_iterator.h>
50
51namespace std _GLIBCXX_VISIBILITY(default)
52{
53namespace __debug
54{
55  /// Class std::unordered_set with safety/checking/debug instrumentation.
56  template<typename _Value,
57	   typename _Hash = std::hash<_Value>,
58	   typename _Pred = std::equal_to<_Value>,
59	   typename _Alloc = std::allocator<_Value> >
60    class unordered_set
61    : public __gnu_debug::_Safe_container<
62	unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
63	__gnu_debug::_Safe_unordered_container>,
64      public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
65    {
66      typedef _GLIBCXX_STD_C::unordered_set<
67	_Value, _Hash, _Pred, _Alloc>					_Base;
68      typedef __gnu_debug::_Safe_container<
69	unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container>	_Safe;
70
71      typedef typename _Base::const_iterator	   _Base_const_iterator;
72      typedef typename _Base::iterator		   _Base_iterator;
73      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
74      typedef typename _Base::local_iterator	   _Base_local_iterator;
75
76      template<typename _ItT, typename _SeqT, typename _CatT>
77	friend class ::__gnu_debug::_Safe_iterator;
78      template<typename _ItT, typename _SeqT>
79	friend class ::__gnu_debug::_Safe_local_iterator;
80
81    public:
82      typedef typename _Base::size_type			size_type;
83      typedef typename _Base::hasher			hasher;
84      typedef typename _Base::key_equal			key_equal;
85      typedef typename _Base::allocator_type		allocator_type;
86
87      typedef typename _Base::key_type			key_type;
88      typedef typename _Base::value_type		value_type;
89
90      typedef __gnu_debug::_Safe_iterator<
91	_Base_iterator, unordered_set>			iterator;
92      typedef __gnu_debug::_Safe_iterator<
93	_Base_const_iterator, unordered_set>		const_iterator;
94      typedef __gnu_debug::_Safe_local_iterator<
95	_Base_local_iterator, unordered_set>		local_iterator;
96      typedef __gnu_debug::_Safe_local_iterator<
97	_Base_const_local_iterator, unordered_set>	const_local_iterator;
98
99      unordered_set() = default;
100
101      explicit
102      unordered_set(size_type __n,
103		    const hasher& __hf = hasher(),
104		    const key_equal& __eql = key_equal(),
105		    const allocator_type& __a = allocator_type())
106      : _Base(__n, __hf, __eql, __a) { }
107
108      template<typename _InputIterator>
109	unordered_set(_InputIterator __first, _InputIterator __last,
110		      size_type __n = 0,
111		      const hasher& __hf = hasher(),
112		      const key_equal& __eql = key_equal(),
113		      const allocator_type& __a = allocator_type())
114	: _Base(__gnu_debug::__base(
115		  __glibcxx_check_valid_constructor_range(__first, __last)),
116		__gnu_debug::__base(__last), __n,
117		__hf, __eql, __a) { }
118
119      unordered_set(const unordered_set&) = default;
120
121      unordered_set(const _Base& __x)
122      : _Base(__x) { }
123
124      unordered_set(unordered_set&&) = default;
125
126      explicit
127      unordered_set(const allocator_type& __a)
128      : _Base(__a) { }
129
130      unordered_set(const unordered_set& __uset,
131		    const allocator_type& __a)
132      : _Base(__uset, __a) { }
133
134      unordered_set(unordered_set&& __uset,
135		    const allocator_type& __a)
136      noexcept( noexcept(_Base(std::move(__uset._M_base()), __a)) )
137      : _Safe(std::move(__uset._M_safe()), __a),
138	_Base(std::move(__uset._M_base()), __a) { }
139
140      unordered_set(initializer_list<value_type> __l,
141		    size_type __n = 0,
142		    const hasher& __hf = hasher(),
143		    const key_equal& __eql = key_equal(),
144		    const allocator_type& __a = allocator_type())
145      : _Base(__l, __n, __hf, __eql, __a) { }
146
147      unordered_set(size_type __n, const allocator_type& __a)
148      : unordered_set(__n, hasher(), key_equal(), __a)
149      { }
150
151      unordered_set(size_type __n, const hasher& __hf,
152		    const allocator_type& __a)
153      : unordered_set(__n, __hf, key_equal(), __a)
154      { }
155
156      template<typename _InputIterator>
157	unordered_set(_InputIterator __first, _InputIterator __last,
158		      size_type __n,
159		      const allocator_type& __a)
160	: unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
161	{ }
162
163      template<typename _InputIterator>
164	unordered_set(_InputIterator __first, _InputIterator __last,
165		      size_type __n, const hasher& __hf,
166		      const allocator_type& __a)
167	: unordered_set(__first, __last, __n, __hf, key_equal(), __a)
168	{ }
169
170      unordered_set(initializer_list<value_type> __l,
171		    size_type __n,
172		    const allocator_type& __a)
173      : unordered_set(__l, __n, hasher(), key_equal(), __a)
174      { }
175
176      unordered_set(initializer_list<value_type> __l,
177		    size_type __n, const hasher& __hf,
178		    const allocator_type& __a)
179      : unordered_set(__l, __n, __hf, key_equal(), __a)
180      { }
181
182      ~unordered_set() = default;
183
184      unordered_set&
185      operator=(const unordered_set&) = default;
186
187      unordered_set&
188      operator=(unordered_set&&) = default;
189
190      unordered_set&
191      operator=(initializer_list<value_type> __l)
192      {
193	_M_base() = __l;
194	this->_M_invalidate_all();
195	return *this;
196      }
197
198      void
199      swap(unordered_set& __x)
200	noexcept( noexcept(declval<_Base&>().swap(__x)) )
201      {
202	_Safe::_M_swap(__x);
203	_Base::swap(__x);
204      }
205
206      void
207      clear() noexcept
208      {
209	_Base::clear();
210	this->_M_invalidate_all();
211      }
212
213      iterator
214      begin() noexcept
215      { return { _Base::begin(), this }; }
216
217      const_iterator
218      begin() const noexcept
219      { return { _Base::begin(), this }; }
220
221      iterator
222      end() noexcept
223      { return { _Base::end(), this }; }
224
225      const_iterator
226      end() const noexcept
227      { return { _Base::end(), this }; }
228
229      const_iterator
230      cbegin() const noexcept
231      { return { _Base::cbegin(), this }; }
232
233      const_iterator
234      cend() const noexcept
235      { return { _Base::cend(), this }; }
236
237      // local versions
238      local_iterator
239      begin(size_type __b)
240      {
241	__glibcxx_check_bucket_index(__b);
242	return { _Base::begin(__b), this };
243      }
244
245      local_iterator
246      end(size_type __b)
247      {
248	__glibcxx_check_bucket_index(__b);
249	return { _Base::end(__b), this };
250      }
251
252      const_local_iterator
253      begin(size_type __b) const
254      {
255	__glibcxx_check_bucket_index(__b);
256	return { _Base::begin(__b), this };
257      }
258
259      const_local_iterator
260      end(size_type __b) const
261      {
262	__glibcxx_check_bucket_index(__b);
263	return { _Base::end(__b), this };
264      }
265
266      const_local_iterator
267      cbegin(size_type __b) const
268      {
269	__glibcxx_check_bucket_index(__b);
270	return { _Base::cbegin(__b), this };
271      }
272
273      const_local_iterator
274      cend(size_type __b) const
275      {
276	__glibcxx_check_bucket_index(__b);
277	return { _Base::cend(__b), this };
278      }
279
280      size_type
281      bucket_size(size_type __b) const
282      {
283	__glibcxx_check_bucket_index(__b);
284	return _Base::bucket_size(__b);
285      }
286
287      float
288      max_load_factor() const noexcept
289      { return _Base::max_load_factor(); }
290
291      void
292      max_load_factor(float __f)
293      {
294	__glibcxx_check_max_load_factor(__f);
295	_Base::max_load_factor(__f);
296      }
297
298      template<typename... _Args>
299	std::pair<iterator, bool>
300	emplace(_Args&&... __args)
301	{
302	  size_type __bucket_count = this->bucket_count();
303	  auto __res = _Base::emplace(std::forward<_Args>(__args)...);
304	  _M_check_rehashed(__bucket_count);
305	  return { { __res.first, this }, __res.second };
306	}
307
308      template<typename... _Args>
309	iterator
310	emplace_hint(const_iterator __hint, _Args&&... __args)
311	{
312	  __glibcxx_check_insert(__hint);
313	  size_type __bucket_count = this->bucket_count();
314	  auto __it = _Base::emplace_hint(__hint.base(),
315					  std::forward<_Args>(__args)...);
316	  _M_check_rehashed(__bucket_count);
317	  return { __it, this };
318	}
319
320      std::pair<iterator, bool>
321      insert(const value_type& __obj)
322      {
323	size_type __bucket_count = this->bucket_count();
324	auto __res = _Base::insert(__obj);
325	_M_check_rehashed(__bucket_count);
326	return { { __res.first, this }, __res.second };
327      }
328
329      iterator
330      insert(const_iterator __hint, const value_type& __obj)
331      {
332	__glibcxx_check_insert(__hint);
333	size_type __bucket_count = this->bucket_count();
334	auto __it = _Base::insert(__hint.base(), __obj);
335	_M_check_rehashed(__bucket_count);
336	return { __it, this };
337      }
338
339      std::pair<iterator, bool>
340      insert(value_type&& __obj)
341      {
342	size_type __bucket_count = this->bucket_count();
343	auto __res = _Base::insert(std::move(__obj));
344	_M_check_rehashed(__bucket_count);
345	return { { __res.first, this }, __res.second };
346      }
347
348      iterator
349      insert(const_iterator __hint, value_type&& __obj)
350      {
351	__glibcxx_check_insert(__hint);
352	size_type __bucket_count = this->bucket_count();
353	auto __it = _Base::insert(__hint.base(), std::move(__obj));
354	_M_check_rehashed(__bucket_count);
355	return { __it, this };
356      }
357
358      void
359      insert(std::initializer_list<value_type> __l)
360      {
361	size_type __bucket_count = this->bucket_count();
362	_Base::insert(__l);
363	_M_check_rehashed(__bucket_count);
364      }
365
366      template<typename _InputIterator>
367	void
368	insert(_InputIterator __first, _InputIterator __last)
369	{
370	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
371	  __glibcxx_check_valid_range2(__first, __last, __dist);
372	  size_type __bucket_count = this->bucket_count();
373
374	  if (__dist.second >= __gnu_debug::__dp_sign)
375	    _Base::insert(__gnu_debug::__unsafe(__first),
376			  __gnu_debug::__unsafe(__last));
377	  else
378	    _Base::insert(__first, __last);
379
380	  _M_check_rehashed(__bucket_count);
381	}
382
383#if __cplusplus > 201402L
384      using node_type = typename _Base::node_type;
385      using insert_return_type = _Node_insert_return<iterator, node_type>;
386
387      node_type
388      extract(const_iterator __position)
389      {
390	__glibcxx_check_erase(__position);
391	return _M_extract(__position.base());
392      }
393
394      node_type
395      extract(const key_type& __key)
396      {
397	const auto __position = _Base::find(__key);
398	if (__position != _Base::end())
399	  return _M_extract(__position);
400	return {};
401      }
402
403      insert_return_type
404      insert(node_type&& __nh)
405      {
406	auto __ret = _Base::insert(std::move(__nh));
407	return
408	  { { __ret.position, this }, __ret.inserted, std::move(__ret.node) };
409      }
410
411      iterator
412      insert(const_iterator __hint, node_type&& __nh)
413      {
414	__glibcxx_check_insert(__hint);
415	return { _Base::insert(__hint.base(), std::move(__nh)), this };
416      }
417
418      using _Base::merge;
419#endif // C++17
420
421      iterator
422      find(const key_type& __key)
423      { return { _Base::find(__key), this }; }
424
425      const_iterator
426      find(const key_type& __key) const
427      { return { _Base::find(__key), this }; }
428
429      std::pair<iterator, iterator>
430      equal_range(const key_type& __key)
431      {
432	auto __res = _Base::equal_range(__key);
433	return { { __res.first, this }, { __res.second, this } };
434      }
435
436      std::pair<const_iterator, const_iterator>
437      equal_range(const key_type& __key) const
438      {
439	auto __res = _Base::equal_range(__key);
440	return { { __res.first, this }, { __res.second, this } };
441      }
442
443      size_type
444      erase(const key_type& __key)
445      {
446	size_type __ret(0);
447	auto __victim = _Base::find(__key);
448	if (__victim != _Base::end())
449	  {
450	    _M_erase(__victim);
451	    __ret = 1;
452	  }
453	return __ret;
454      }
455
456      iterator
457      erase(const_iterator __it)
458      {
459	__glibcxx_check_erase(__it);
460	return { _M_erase(__it.base()), this };
461      }
462
463      iterator
464      erase(iterator __it)
465      {
466	__glibcxx_check_erase(__it);
467	return { _M_erase(__it.base()), this };
468      }
469
470      iterator
471      erase(const_iterator __first, const_iterator __last)
472      {
473	__glibcxx_check_erase_range(__first, __last);
474	for (auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
475	  {
476	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
477				  _M_message(__gnu_debug::__msg_valid_range)
478				  ._M_iterator(__first, "first")
479				  ._M_iterator(__last, "last"));
480	    _M_invalidate(__tmp);
481	  }
482
483	size_type __bucket_count = this->bucket_count();
484	auto __next = _Base::erase(__first.base(), __last.base());
485	_M_check_rehashed(__bucket_count);
486	return { __next, this };
487      }
488
489      _Base&
490      _M_base() noexcept { return *this; }
491
492      const _Base&
493      _M_base() const noexcept { return *this; }
494
495    private:
496      void
497      _M_check_rehashed(size_type __prev_count)
498      {
499	if (__prev_count != this->bucket_count())
500	  this->_M_invalidate_all();
501      }
502
503      void
504      _M_invalidate(_Base_const_iterator __victim)
505      {
506	this->_M_invalidate_if(
507	  [__victim](_Base_const_iterator __it) { return __it == __victim; });
508	this->_M_invalidate_local_if(
509	  [__victim](_Base_const_local_iterator __it)
510	  { return __it._M_curr() == __victim._M_cur; });
511      }
512
513      _Base_iterator
514      _M_erase(_Base_const_iterator __victim)
515      {
516	_M_invalidate(__victim);
517	size_type __bucket_count = this->bucket_count();
518	_Base_iterator __next = _Base::erase(__victim);
519	_M_check_rehashed(__bucket_count);
520	return __next;
521      }
522
523#if __cplusplus > 201402L
524      node_type
525      _M_extract(_Base_const_iterator __victim)
526      {
527	_M_invalidate(__victim);
528	return _Base::extract(__victim);
529      }
530#endif
531    };
532
533#if __cpp_deduction_guides >= 201606
534
535  template<typename _InputIterator,
536	   typename _Hash =
537	     hash<typename iterator_traits<_InputIterator>::value_type>,
538	   typename _Pred =
539	     equal_to<typename iterator_traits<_InputIterator>::value_type>,
540	   typename _Allocator =
541	     allocator<typename iterator_traits<_InputIterator>::value_type>,
542	   typename = _RequireInputIter<_InputIterator>,
543	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
544	   typename = _RequireNotAllocator<_Pred>,
545	   typename = _RequireAllocator<_Allocator>>
546    unordered_set(_InputIterator, _InputIterator,
547		  unordered_set<int>::size_type = {},
548		  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
549    -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
550		     _Hash, _Pred, _Allocator>;
551
552  template<typename _Tp, typename _Hash = hash<_Tp>,
553	   typename _Pred = equal_to<_Tp>,
554	   typename _Allocator = allocator<_Tp>,
555	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
556	   typename = _RequireNotAllocator<_Pred>,
557	   typename = _RequireAllocator<_Allocator>>
558    unordered_set(initializer_list<_Tp>,
559		  unordered_set<int>::size_type = {},
560		  _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
561    -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
562
563  template<typename _InputIterator, typename _Allocator,
564	   typename = _RequireInputIter<_InputIterator>,
565	   typename = _RequireAllocator<_Allocator>>
566    unordered_set(_InputIterator, _InputIterator,
567		  unordered_set<int>::size_type, _Allocator)
568    -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
569		     hash<
570		       typename iterator_traits<_InputIterator>::value_type>,
571		     equal_to<
572		       typename iterator_traits<_InputIterator>::value_type>,
573		     _Allocator>;
574
575  template<typename _InputIterator, typename _Hash, typename _Allocator,
576	   typename = _RequireInputIter<_InputIterator>,
577	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
578	   typename = _RequireAllocator<_Allocator>>
579    unordered_set(_InputIterator, _InputIterator,
580		  unordered_set<int>::size_type,
581		  _Hash, _Allocator)
582    -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
583		     _Hash,
584		     equal_to<
585		       typename iterator_traits<_InputIterator>::value_type>,
586		     _Allocator>;
587
588  template<typename _Tp, typename _Allocator,
589	   typename = _RequireAllocator<_Allocator>>
590    unordered_set(initializer_list<_Tp>,
591		  unordered_set<int>::size_type, _Allocator)
592    -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
593
594  template<typename _Tp, typename _Hash, typename _Allocator,
595	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
596	   typename = _RequireAllocator<_Allocator>>
597    unordered_set(initializer_list<_Tp>,
598		  unordered_set<int>::size_type, _Hash, _Allocator)
599    -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
600
601#endif
602
603  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
604    inline void
605    swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
606	 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
607    noexcept(noexcept(__x.swap(__y)))
608    { __x.swap(__y); }
609
610  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
611    inline bool
612    operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
613	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
614    { return __x._M_base() == __y._M_base(); }
615
616#if __cpp_impl_three_way_comparison < 201907L
617  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
618    inline bool
619    operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
620	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
621    { return !(__x == __y); }
622#endif
623
624  /// Class std::unordered_multiset with safety/checking/debug instrumentation.
625  template<typename _Value,
626	   typename _Hash = std::hash<_Value>,
627	   typename _Pred = std::equal_to<_Value>,
628	   typename _Alloc = std::allocator<_Value> >
629    class unordered_multiset
630    : public __gnu_debug::_Safe_container<
631	unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
632	__gnu_debug::_Safe_unordered_container>,
633      public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
634    {
635      typedef _GLIBCXX_STD_C::unordered_multiset<
636	_Value, _Hash, _Pred, _Alloc>				_Base;
637      typedef __gnu_debug::_Safe_container<unordered_multiset,
638	_Alloc, __gnu_debug::_Safe_unordered_container>		_Safe;
639      typedef typename _Base::const_iterator	_Base_const_iterator;
640      typedef typename _Base::iterator		_Base_iterator;
641      typedef typename _Base::const_local_iterator
642						_Base_const_local_iterator;
643      typedef typename _Base::local_iterator	_Base_local_iterator;
644
645      template<typename _ItT, typename _SeqT, typename _CatT>
646	friend class ::__gnu_debug::_Safe_iterator;
647      template<typename _ItT, typename _SeqT>
648	friend class ::__gnu_debug::_Safe_local_iterator;
649
650    public:
651      typedef typename _Base::size_type			size_type;
652      typedef typename _Base::hasher			hasher;
653      typedef typename _Base::key_equal			key_equal;
654      typedef typename _Base::allocator_type		allocator_type;
655
656      typedef typename _Base::key_type			key_type;
657      typedef typename _Base::value_type		value_type;
658
659      typedef __gnu_debug::_Safe_iterator<
660	_Base_iterator, unordered_multiset>		iterator;
661      typedef __gnu_debug::_Safe_iterator<
662	_Base_const_iterator, unordered_multiset>	const_iterator;
663      typedef __gnu_debug::_Safe_local_iterator<
664	_Base_local_iterator, unordered_multiset>	local_iterator;
665      typedef __gnu_debug::_Safe_local_iterator<
666	_Base_const_local_iterator, unordered_multiset>	const_local_iterator;
667
668      unordered_multiset() = default;
669
670      explicit
671      unordered_multiset(size_type __n,
672			 const hasher& __hf = hasher(),
673			 const key_equal& __eql = key_equal(),
674			 const allocator_type& __a = allocator_type())
675      : _Base(__n, __hf, __eql, __a) { }
676
677      template<typename _InputIterator>
678	unordered_multiset(_InputIterator __first, _InputIterator __last,
679			   size_type __n = 0,
680			   const hasher& __hf = hasher(),
681			   const key_equal& __eql = key_equal(),
682			   const allocator_type& __a = allocator_type())
683	: _Base(__gnu_debug::__base(
684		  __glibcxx_check_valid_constructor_range(__first, __last)),
685		__gnu_debug::__base(__last), __n,
686		__hf, __eql, __a) { }
687
688      unordered_multiset(const unordered_multiset&) = default;
689
690      unordered_multiset(const _Base& __x)
691      : _Base(__x) { }
692
693      unordered_multiset(unordered_multiset&&) = default;
694
695      explicit
696      unordered_multiset(const allocator_type& __a)
697      : _Base(__a) { }
698
699      unordered_multiset(const unordered_multiset& __uset,
700			 const allocator_type& __a)
701      : _Base(__uset, __a) { }
702
703      unordered_multiset(unordered_multiset&& __uset,
704			 const allocator_type& __a)
705      noexcept( noexcept(_Base(std::move(__uset._M_base()), __a)) )
706      : _Safe(std::move(__uset._M_safe()), __a),
707	_Base(std::move(__uset._M_base()), __a) { }
708
709      unordered_multiset(initializer_list<value_type> __l,
710			 size_type __n = 0,
711			 const hasher& __hf = hasher(),
712			 const key_equal& __eql = key_equal(),
713			 const allocator_type& __a = allocator_type())
714      : _Base(__l, __n, __hf, __eql, __a) { }
715
716      unordered_multiset(size_type __n, const allocator_type& __a)
717      : unordered_multiset(__n, hasher(), key_equal(), __a)
718      { }
719
720      unordered_multiset(size_type __n, const hasher& __hf,
721			 const allocator_type& __a)
722      : unordered_multiset(__n, __hf, key_equal(), __a)
723      { }
724
725      template<typename _InputIterator>
726	unordered_multiset(_InputIterator __first, _InputIterator __last,
727			   size_type __n,
728			   const allocator_type& __a)
729	: unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
730	{ }
731
732      template<typename _InputIterator>
733	unordered_multiset(_InputIterator __first, _InputIterator __last,
734			   size_type __n, const hasher& __hf,
735			   const allocator_type& __a)
736	: unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
737	{ }
738
739      unordered_multiset(initializer_list<value_type> __l,
740			 size_type __n,
741			 const allocator_type& __a)
742      : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
743      { }
744
745      unordered_multiset(initializer_list<value_type> __l,
746			 size_type __n, const hasher& __hf,
747			 const allocator_type& __a)
748      : unordered_multiset(__l, __n, __hf, key_equal(), __a)
749      { }
750
751      ~unordered_multiset() = default;
752
753      unordered_multiset&
754      operator=(const unordered_multiset&) = default;
755
756      unordered_multiset&
757      operator=(unordered_multiset&&) = default;
758
759      unordered_multiset&
760      operator=(initializer_list<value_type> __l)
761      {
762	this->_M_base() = __l;
763	this->_M_invalidate_all();
764	return *this;
765      }
766
767      void
768      swap(unordered_multiset& __x)
769	noexcept( noexcept(declval<_Base&>().swap(__x)) )
770      {
771	_Safe::_M_swap(__x);
772	_Base::swap(__x);
773      }
774
775      void
776      clear() noexcept
777      {
778	_Base::clear();
779	this->_M_invalidate_all();
780      }
781
782      iterator
783      begin() noexcept
784      { return { _Base::begin(), this }; }
785
786      const_iterator
787      begin() const noexcept
788      { return { _Base::begin(), this }; }
789
790      iterator
791      end() noexcept
792      { return { _Base::end(), this }; }
793
794      const_iterator
795      end() const noexcept
796      { return { _Base::end(), this }; }
797
798      const_iterator
799      cbegin() const noexcept
800      { return { _Base::cbegin(), this }; }
801
802      const_iterator
803      cend() const noexcept
804      { return { _Base::cend(), this }; }
805
806      // local versions
807      local_iterator
808      begin(size_type __b)
809      {
810	__glibcxx_check_bucket_index(__b);
811	return { _Base::begin(__b), this };
812      }
813
814      local_iterator
815      end(size_type __b)
816      {
817	__glibcxx_check_bucket_index(__b);
818	return { _Base::end(__b), this };
819      }
820
821      const_local_iterator
822      begin(size_type __b) const
823      {
824	__glibcxx_check_bucket_index(__b);
825	return { _Base::begin(__b), this };
826      }
827
828      const_local_iterator
829      end(size_type __b) const
830      {
831	__glibcxx_check_bucket_index(__b);
832	return { _Base::end(__b), this };
833      }
834
835      const_local_iterator
836      cbegin(size_type __b) const
837      {
838	__glibcxx_check_bucket_index(__b);
839	return { _Base::cbegin(__b), this };
840      }
841
842      const_local_iterator
843      cend(size_type __b) const
844      {
845	__glibcxx_check_bucket_index(__b);
846	return { _Base::cend(__b), this };
847      }
848
849      size_type
850      bucket_size(size_type __b) const
851      {
852	__glibcxx_check_bucket_index(__b);
853	return _Base::bucket_size(__b);
854      }
855
856      float
857      max_load_factor() const noexcept
858      { return _Base::max_load_factor(); }
859
860      void
861      max_load_factor(float __f)
862      {
863	__glibcxx_check_max_load_factor(__f);
864	_Base::max_load_factor(__f);
865      }
866
867      template<typename... _Args>
868	iterator
869	emplace(_Args&&... __args)
870	{
871	  size_type __bucket_count = this->bucket_count();
872	  auto __it = _Base::emplace(std::forward<_Args>(__args)...);
873	  _M_check_rehashed(__bucket_count);
874	  return { __it, this };
875	}
876
877      template<typename... _Args>
878	iterator
879	emplace_hint(const_iterator __hint, _Args&&... __args)
880	{
881	  __glibcxx_check_insert(__hint);
882	  size_type __bucket_count = this->bucket_count();
883	  auto __it = _Base::emplace_hint(__hint.base(),
884					  std::forward<_Args>(__args)...);
885	  _M_check_rehashed(__bucket_count);
886	  return { __it, this };
887	}
888
889      iterator
890      insert(const value_type& __obj)
891      {
892	size_type __bucket_count = this->bucket_count();
893	auto __it = _Base::insert(__obj);
894	_M_check_rehashed(__bucket_count);
895	return { __it, this };
896      }
897
898      iterator
899      insert(const_iterator __hint, const value_type& __obj)
900      {
901	__glibcxx_check_insert(__hint);
902	size_type __bucket_count = this->bucket_count();
903	auto __it = _Base::insert(__hint.base(), __obj);
904	_M_check_rehashed(__bucket_count);
905	return { __it, this };
906      }
907
908      iterator
909      insert(value_type&& __obj)
910      {
911	size_type __bucket_count = this->bucket_count();
912	auto __it = _Base::insert(std::move(__obj));
913	_M_check_rehashed(__bucket_count);
914	return { __it, this };
915      }
916
917      iterator
918      insert(const_iterator __hint, value_type&& __obj)
919      {
920	__glibcxx_check_insert(__hint);
921	size_type __bucket_count = this->bucket_count();
922	auto __it = _Base::insert(__hint.base(), std::move(__obj));
923	_M_check_rehashed(__bucket_count);
924	return { __it, this };
925      }
926
927      void
928      insert(std::initializer_list<value_type> __l)
929      {
930	size_type __bucket_count = this->bucket_count();
931	_Base::insert(__l);
932	_M_check_rehashed(__bucket_count);
933      }
934
935      template<typename _InputIterator>
936	void
937	insert(_InputIterator __first, _InputIterator __last)
938	{
939	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
940	  __glibcxx_check_valid_range2(__first, __last, __dist);
941	  size_type __bucket_count = this->bucket_count();
942
943	  if (__dist.second >= __gnu_debug::__dp_sign)
944	    _Base::insert(__gnu_debug::__unsafe(__first),
945			  __gnu_debug::__unsafe(__last));
946	  else
947	    _Base::insert(__first, __last);
948
949	  _M_check_rehashed(__bucket_count);
950	}
951
952#if __cplusplus > 201402L
953      using node_type = typename _Base::node_type;
954
955      node_type
956      extract(const_iterator __position)
957      {
958	__glibcxx_check_erase(__position);
959	return _M_extract(__position.base());
960      }
961
962      node_type
963      extract(const key_type& __key)
964      {
965	const auto __position = _Base::find(__key);
966	if (__position != _Base::end())
967	  return _M_extract(__position);
968	return {};
969      }
970
971      iterator
972      insert(node_type&& __nh)
973      { return { _Base::insert(std::move(__nh)), this }; }
974
975      iterator
976      insert(const_iterator __hint, node_type&& __nh)
977      {
978	__glibcxx_check_insert(__hint);
979	return { _Base::insert(__hint.base(), std::move(__nh)), this };
980      }
981
982      using _Base::merge;
983#endif // C++17
984
985      iterator
986      find(const key_type& __key)
987      { return { _Base::find(__key), this }; }
988
989      const_iterator
990      find(const key_type& __key) const
991      { return { _Base::find(__key), this }; }
992
993      std::pair<iterator, iterator>
994      equal_range(const key_type& __key)
995      {
996	auto __res = _Base::equal_range(__key);
997	return { { __res.first, this }, { __res.second, this } };
998      }
999
1000      std::pair<const_iterator, const_iterator>
1001      equal_range(const key_type& __key) const
1002      {
1003	auto __res = _Base::equal_range(__key);
1004	return { { __res.first, this }, { __res.second, this } };
1005      }
1006
1007      size_type
1008      erase(const key_type& __key)
1009      {
1010	size_type __ret(0);
1011	auto __pair = _Base::equal_range(__key);
1012	for (auto __victim = __pair.first; __victim != __pair.second;)
1013	  {
1014	    _M_invalidate(__victim);
1015	    __victim = _Base::erase(__victim);
1016	    ++__ret;
1017	  }
1018
1019	return __ret;
1020      }
1021
1022      iterator
1023      erase(const_iterator __it)
1024      {
1025	__glibcxx_check_erase(__it);
1026	return { _M_erase(__it.base()), this };
1027      }
1028
1029      iterator
1030      erase(iterator __it)
1031      {
1032	__glibcxx_check_erase(__it);
1033	return { _M_erase(__it.base()), this };
1034      }
1035
1036      iterator
1037      erase(const_iterator __first, const_iterator __last)
1038      {
1039	__glibcxx_check_erase_range(__first, __last);
1040	for (auto __tmp = __first.base(); __tmp != __last.base(); ++__tmp)
1041	  {
1042	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::cend(),
1043				  _M_message(__gnu_debug::__msg_valid_range)
1044				  ._M_iterator(__first, "first")
1045				  ._M_iterator(__last, "last"));
1046	    _M_invalidate(__tmp);
1047	  }
1048	return { _Base::erase(__first.base(), __last.base()), this };
1049      }
1050
1051      _Base&
1052      _M_base() noexcept	{ return *this; }
1053
1054      const _Base&
1055      _M_base() const noexcept	{ return *this; }
1056
1057    private:
1058      void
1059      _M_check_rehashed(size_type __prev_count)
1060      {
1061	if (__prev_count != this->bucket_count())
1062	  this->_M_invalidate_all();
1063      }
1064
1065      void
1066      _M_invalidate(_Base_const_iterator __victim)
1067      {
1068	this->_M_invalidate_if(
1069	  [__victim](_Base_const_iterator __it) { return __it == __victim; });
1070	this->_M_invalidate_local_if(
1071	  [__victim](_Base_const_local_iterator __it)
1072	  { return __it._M_curr() == __victim._M_cur; });
1073      }
1074
1075      _Base_iterator
1076      _M_erase(_Base_const_iterator __victim)
1077      {
1078	_M_invalidate(__victim);
1079	size_type __bucket_count = this->bucket_count();
1080	_Base_iterator __next = _Base::erase(__victim);
1081	_M_check_rehashed(__bucket_count);
1082	return __next;
1083      }
1084
1085#if __cplusplus > 201402L
1086      node_type
1087      _M_extract(_Base_const_iterator __victim)
1088      {
1089	_M_invalidate(__victim);
1090	return _Base::extract(__victim);
1091      }
1092#endif
1093    };
1094
1095#if __cpp_deduction_guides >= 201606
1096
1097  template<typename _InputIterator,
1098	   typename _Hash =
1099	     hash<typename iterator_traits<_InputIterator>::value_type>,
1100	   typename _Pred =
1101	     equal_to<typename iterator_traits<_InputIterator>::value_type>,
1102	   typename _Allocator =
1103	     allocator<typename iterator_traits<_InputIterator>::value_type>,
1104	   typename = _RequireInputIter<_InputIterator>,
1105	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1106	   typename = _RequireNotAllocator<_Pred>,
1107	   typename = _RequireAllocator<_Allocator>>
1108    unordered_multiset(_InputIterator, _InputIterator,
1109		       unordered_multiset<int>::size_type = {},
1110		       _Hash = _Hash(), _Pred = _Pred(),
1111		       _Allocator = _Allocator())
1112    -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1113			  _Hash, _Pred, _Allocator>;
1114
1115  template<typename _Tp, typename _Hash = hash<_Tp>,
1116	   typename _Pred = equal_to<_Tp>,
1117	   typename _Allocator = allocator<_Tp>,
1118	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1119	   typename = _RequireNotAllocator<_Pred>,
1120	   typename = _RequireAllocator<_Allocator>>
1121    unordered_multiset(initializer_list<_Tp>,
1122		       unordered_multiset<int>::size_type = {},
1123		       _Hash = _Hash(), _Pred = _Pred(),
1124		       _Allocator = _Allocator())
1125    -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1126
1127  template<typename _InputIterator, typename _Allocator,
1128	   typename = _RequireInputIter<_InputIterator>,
1129	   typename = _RequireAllocator<_Allocator>>
1130    unordered_multiset(_InputIterator, _InputIterator,
1131		       unordered_multiset<int>::size_type, _Allocator)
1132    -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1133			  hash<typename
1134			       iterator_traits<_InputIterator>::value_type>,
1135			  equal_to<typename
1136				   iterator_traits<_InputIterator>::value_type>,
1137			  _Allocator>;
1138
1139  template<typename _InputIterator, typename _Hash, typename _Allocator,
1140	   typename = _RequireInputIter<_InputIterator>,
1141	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1142	   typename = _RequireAllocator<_Allocator>>
1143    unordered_multiset(_InputIterator, _InputIterator,
1144		       unordered_multiset<int>::size_type,
1145		       _Hash, _Allocator)
1146    -> unordered_multiset<typename
1147			  iterator_traits<_InputIterator>::value_type,
1148			  _Hash,
1149			  equal_to<
1150			    typename
1151			    iterator_traits<_InputIterator>::value_type>,
1152			  _Allocator>;
1153
1154  template<typename _Tp, typename _Allocator,
1155	   typename = _RequireAllocator<_Allocator>>
1156    unordered_multiset(initializer_list<_Tp>,
1157		       unordered_multiset<int>::size_type, _Allocator)
1158    -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1159
1160  template<typename _Tp, typename _Hash, typename _Allocator,
1161	   typename = _RequireNotAllocatorOrIntegral<_Hash>,
1162	   typename = _RequireAllocator<_Allocator>>
1163    unordered_multiset(initializer_list<_Tp>,
1164		       unordered_multiset<int>::size_type, _Hash, _Allocator)
1165    -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1166
1167#endif
1168
1169  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1170    inline void
1171    swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1172	 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1173    noexcept(noexcept(__x.swap(__y)))
1174    { __x.swap(__y); }
1175
1176  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1177    inline bool
1178    operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1179	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1180    { return __x._M_base() == __y._M_base(); }
1181
1182#if __cpp_impl_three_way_comparison < 201907L
1183  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1184    inline bool
1185    operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1186	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1187    { return !(__x == __y); }
1188#endif
1189
1190} // namespace __debug
1191} // namespace std
1192
1193#endif // C++11
1194
1195#endif
1196