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