1// Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
2
3// Copyright (C) 2003-2014 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#if __cplusplus < 201103L
33# include <bits/c++0x_warning.h>
34#else
35# include <unordered_set>
36
37#include <debug/safe_unordered_container.h>
38#include <debug/safe_iterator.h>
39#include <debug/safe_local_iterator.h>
40
41namespace std _GLIBCXX_VISIBILITY(default)
42{
43namespace __debug
44{
45  /// Class std::unordered_set with safety/checking/debug instrumentation.
46  template<typename _Value,
47	   typename _Hash = std::hash<_Value>,
48	   typename _Pred = std::equal_to<_Value>,
49	   typename _Alloc = std::allocator<_Value> >
50    class unordered_set
51    : public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
52      public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
53						       _Pred, _Alloc> >
54    {
55      typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
56					    _Pred, _Alloc> _Base;
57      typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
58      typedef typename _Base::const_iterator _Base_const_iterator;
59      typedef typename _Base::iterator _Base_iterator;
60      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
61      typedef typename _Base::local_iterator _Base_local_iterator;
62
63      typedef __gnu_cxx::__alloc_traits<typename
64					_Base::allocator_type> _Alloc_traits;
65    public:
66      typedef typename _Base::size_type       size_type;
67      typedef typename _Base::hasher          hasher;
68      typedef typename _Base::key_equal       key_equal;
69      typedef typename _Base::allocator_type  allocator_type;
70
71      typedef typename _Base::key_type        key_type;
72      typedef typename _Base::value_type      value_type;
73
74      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
75					  unordered_set> iterator;
76      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
77					  unordered_set> const_iterator;
78      typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
79					  unordered_set> local_iterator;
80      typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
81					  unordered_set> const_local_iterator;
82
83      explicit
84      unordered_set(size_type __n = 10,
85		    const hasher& __hf = hasher(),
86		    const key_equal& __eql = key_equal(),
87		    const allocator_type& __a = allocator_type())
88      : _Base(__n, __hf, __eql, __a) { }
89
90      template<typename _InputIterator>
91        unordered_set(_InputIterator __first, _InputIterator __last,
92		      size_type __n = 0,
93		      const hasher& __hf = hasher(),
94		      const key_equal& __eql = key_equal(),
95		      const allocator_type& __a = allocator_type())
96	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
97								     __last)),
98		__gnu_debug::__base(__last), __n,
99		__hf, __eql, __a) { }
100
101      unordered_set(const unordered_set&) = default;
102
103      unordered_set(const _Base& __x)
104	: _Base(__x) { }
105
106      unordered_set(unordered_set&&) = default;
107
108      explicit
109      unordered_set(const allocator_type& __a)
110	: _Base(__a)
111      { }
112
113      unordered_set(const unordered_set& __uset,
114		    const allocator_type& __a)
115	: _Base(__uset._M_base(), __a)
116      { }
117
118      unordered_set(unordered_set&& __uset,
119		    const allocator_type& __a)
120	: _Base(std::move(__uset._M_base()), __a)
121      { }
122
123      unordered_set(initializer_list<value_type> __l,
124		    size_type __n = 0,
125		    const hasher& __hf = hasher(),
126		    const key_equal& __eql = key_equal(),
127		    const allocator_type& __a = allocator_type())
128      : _Base(__l, __n, __hf, __eql, __a) { }
129
130      ~unordered_set() noexcept { }
131
132      unordered_set&
133      operator=(const unordered_set& __x)
134      {
135	_M_base() = __x._M_base();
136	this->_M_invalidate_all();
137	return *this;
138      }
139
140      unordered_set&
141      operator=(unordered_set&& __x)
142      noexcept(_Alloc_traits::_S_nothrow_move())
143      {
144	__glibcxx_check_self_move_assign(__x);
145	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
146	    || __x.get_allocator() == this->get_allocator();
147	_M_base() = std::move(__x._M_base());
148	if (__xfer_memory)
149	  this->_M_swap(__x);
150	else
151	  this->_M_invalidate_all();
152	__x._M_invalidate_all();
153	return *this;
154      }
155
156      unordered_set&
157      operator=(initializer_list<value_type> __l)
158      {
159	_M_base() = __l;
160	this->_M_invalidate_all();
161	return *this;
162      }
163
164      void
165      swap(unordered_set& __x)
166      noexcept(_Alloc_traits::_S_nothrow_swap())
167      {
168	if (!_Alloc_traits::_S_propagate_on_swap())
169	  __glibcxx_check_equal_allocs(__x);
170	_Base::swap(__x);
171	_Safe_base::_M_swap(__x);
172      }
173
174      void
175      clear() noexcept
176      {
177	_Base::clear();
178	this->_M_invalidate_all();
179      }
180
181      iterator
182      begin() noexcept
183      { return iterator(_Base::begin(), this); }
184
185      const_iterator
186      begin() const noexcept
187      { return const_iterator(_Base::begin(), this); }
188
189      iterator
190      end() noexcept
191      { return iterator(_Base::end(), this); }
192
193      const_iterator
194      end() const noexcept
195      { return const_iterator(_Base::end(), this); }
196
197      const_iterator
198      cbegin() const noexcept
199      { return const_iterator(_Base::begin(), this); }
200
201      const_iterator
202      cend() const noexcept
203      { return const_iterator(_Base::end(), this); }
204
205      // local versions
206      local_iterator
207      begin(size_type __b)
208      {
209	__glibcxx_check_bucket_index(__b);
210	return local_iterator(_Base::begin(__b), this);
211      }
212
213      local_iterator
214      end(size_type __b)
215      {
216	__glibcxx_check_bucket_index(__b);
217	return local_iterator(_Base::end(__b), this);
218      }
219
220      const_local_iterator
221      begin(size_type __b) const
222      {
223	__glibcxx_check_bucket_index(__b);
224	return const_local_iterator(_Base::begin(__b), this);
225      }
226
227      const_local_iterator
228      end(size_type __b) const
229      {
230	__glibcxx_check_bucket_index(__b);
231	return const_local_iterator(_Base::end(__b), this);
232      }
233
234      const_local_iterator
235      cbegin(size_type __b) const
236      {
237	__glibcxx_check_bucket_index(__b);
238	return const_local_iterator(_Base::cbegin(__b), this);
239      }
240
241      const_local_iterator
242      cend(size_type __b) const
243      {
244	__glibcxx_check_bucket_index(__b);
245	return const_local_iterator(_Base::cend(__b), this);
246      }
247
248      size_type
249      bucket_size(size_type __b) const
250      {
251	__glibcxx_check_bucket_index(__b);
252	return _Base::bucket_size(__b);
253      }
254
255      float
256      max_load_factor() const noexcept
257      { return _Base::max_load_factor(); }
258
259      void
260      max_load_factor(float __f)
261      {
262	__glibcxx_check_max_load_factor(__f);
263	_Base::max_load_factor(__f);
264      }
265
266      template<typename... _Args>
267	std::pair<iterator, bool>
268	emplace(_Args&&... __args)
269	{
270	  size_type __bucket_count = this->bucket_count();
271	  std::pair<_Base_iterator, bool> __res
272	    = _Base::emplace(std::forward<_Args>(__args)...);
273	  _M_check_rehashed(__bucket_count);
274	  return std::make_pair(iterator(__res.first, this), __res.second);
275	}
276
277      template<typename... _Args>
278	iterator
279	emplace_hint(const_iterator __hint, _Args&&... __args)
280	{
281	  __glibcxx_check_insert(__hint);
282	  size_type __bucket_count = this->bucket_count();
283	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
284					std::forward<_Args>(__args)...);
285	  _M_check_rehashed(__bucket_count);
286	  return iterator(__it, this);
287	}
288
289      std::pair<iterator, bool>
290      insert(const value_type& __obj)
291      {
292	size_type __bucket_count = this->bucket_count();
293	typedef std::pair<_Base_iterator, bool> __pair_type;
294	  __pair_type __res = _Base::insert(__obj);
295	_M_check_rehashed(__bucket_count);
296	return std::make_pair(iterator(__res.first, this), __res.second);
297      }
298
299      iterator
300      insert(const_iterator __hint, const value_type& __obj)
301      {
302	__glibcxx_check_insert(__hint);
303	size_type __bucket_count = this->bucket_count();
304	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
305	_M_check_rehashed(__bucket_count);
306	return iterator(__it, this);
307      }
308
309      std::pair<iterator, bool>
310      insert(value_type&& __obj)
311      {
312	size_type __bucket_count = this->bucket_count();
313	typedef std::pair<typename _Base::iterator, bool> __pair_type;
314	  __pair_type __res = _Base::insert(std::move(__obj));
315	_M_check_rehashed(__bucket_count);
316	return std::make_pair(iterator(__res.first, this), __res.second);
317      }
318
319      iterator
320      insert(const_iterator __hint, value_type&& __obj)
321      {
322	__glibcxx_check_insert(__hint);
323	size_type __bucket_count = this->bucket_count();
324	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
325	_M_check_rehashed(__bucket_count);
326	return iterator(__it, this);
327      }
328
329      void
330      insert(std::initializer_list<value_type> __l)
331      {
332	size_type __bucket_count = this->bucket_count();
333	_Base::insert(__l);
334	_M_check_rehashed(__bucket_count);
335      }
336
337      template<typename _InputIterator>
338	void
339	insert(_InputIterator __first, _InputIterator __last)
340	{
341	  __glibcxx_check_valid_range(__first, __last);
342	  size_type __bucket_count = this->bucket_count();
343	  _Base::insert(__gnu_debug::__base(__first),
344			__gnu_debug::__base(__last));
345	  _M_check_rehashed(__bucket_count);
346	}
347
348      iterator
349      find(const key_type& __key)
350      { return iterator(_Base::find(__key), this); }
351
352      const_iterator
353      find(const key_type& __key) const
354      { return const_iterator(_Base::find(__key), this); }
355
356      std::pair<iterator, iterator>
357      equal_range(const key_type& __key)
358      {
359	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
360	__pair_type __res = _Base::equal_range(__key);
361	return std::make_pair(iterator(__res.first, this),
362			      iterator(__res.second, this));
363      }
364
365      std::pair<const_iterator, const_iterator>
366      equal_range(const key_type& __key) const
367      {
368	std::pair<_Base_const_iterator, _Base_const_iterator>
369	  __res = _Base::equal_range(__key);
370	return std::make_pair(const_iterator(__res.first, this),
371			      const_iterator(__res.second, this));
372      }
373
374      size_type
375      erase(const key_type& __key)
376      {
377	size_type __ret(0);
378	_Base_iterator __victim(_Base::find(__key));
379	if (__victim != _Base::end())
380	  {
381	    this->_M_invalidate_if(
382			    [__victim](_Base_const_iterator __it)
383			    { return __it == __victim; });
384	    this->_M_invalidate_local_if(
385			    [__victim](_Base_const_local_iterator __it)
386			    { return __it._M_curr() == __victim._M_cur; });
387	    size_type __bucket_count = this->bucket_count();
388	    _Base::erase(__victim);
389	    _M_check_rehashed(__bucket_count);
390	    __ret = 1;
391	  }
392	return __ret;
393      }
394
395      iterator
396      erase(const_iterator __it)
397      {
398	__glibcxx_check_erase(__it);
399	_Base_const_iterator __victim = __it.base();
400	this->_M_invalidate_if(
401			[__victim](_Base_const_iterator __it)
402			{ return __it == __victim; });
403	this->_M_invalidate_local_if(
404			[__victim](_Base_const_local_iterator __it)
405			{ return __it._M_curr() == __victim._M_cur; });
406	size_type __bucket_count = this->bucket_count();
407	_Base_iterator __next = _Base::erase(__it.base());
408	_M_check_rehashed(__bucket_count);
409	return iterator(__next, this);
410      }
411
412      iterator
413      erase(iterator __it)
414      { return erase(const_iterator(__it)); }
415
416      iterator
417      erase(const_iterator __first, const_iterator __last)
418      {
419	__glibcxx_check_erase_range(__first, __last);
420	for (_Base_const_iterator __tmp = __first.base();
421	     __tmp != __last.base(); ++__tmp)
422	  {
423	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
424				  _M_message(__gnu_debug::__msg_valid_range)
425				  ._M_iterator(__first, "first")
426				  ._M_iterator(__last, "last"));
427	    this->_M_invalidate_if(
428			    [__tmp](_Base_const_iterator __it)
429			    { return __it == __tmp; });
430	    this->_M_invalidate_local_if(
431			    [__tmp](_Base_const_local_iterator __it)
432			    { return __it._M_curr() == __tmp._M_cur; });
433	  }
434	size_type __bucket_count = this->bucket_count();
435	_Base_iterator __next = _Base::erase(__first.base(),
436					     __last.base());
437	_M_check_rehashed(__bucket_count);
438	return iterator(__next, this);
439      }
440
441      _Base&
442      _M_base() noexcept       { return *this; }
443
444      const _Base&
445      _M_base() const noexcept { return *this; }
446
447    private:
448      void
449      _M_invalidate_locals()
450      {
451	_Base_local_iterator __local_end = _Base::end(0);
452	this->_M_invalidate_local_if(
453			[__local_end](_Base_const_local_iterator __it)
454			{ return __it != __local_end; });
455      }
456
457      void
458      _M_invalidate_all()
459      {
460	_Base_iterator __end = _Base::end();
461	this->_M_invalidate_if(
462			[__end](_Base_const_iterator __it)
463			{ return __it != __end; });
464	_M_invalidate_locals();
465      }
466
467      void
468      _M_check_rehashed(size_type __prev_count)
469      {
470	if (__prev_count != this->bucket_count())
471	  _M_invalidate_locals();
472      }
473    };
474
475  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
476    inline void
477    swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
478	 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
479    { __x.swap(__y); }
480
481  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
482    inline bool
483    operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
484	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
485    { return __x._M_base() == __y._M_base(); }
486
487  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
488    inline bool
489    operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
490	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
491    { return !(__x == __y); }
492
493
494  /// Class std::unordered_multiset with safety/checking/debug instrumentation.
495  template<typename _Value,
496	   typename _Hash = std::hash<_Value>,
497	   typename _Pred = std::equal_to<_Value>,
498	   typename _Alloc = std::allocator<_Value> >
499    class unordered_multiset
500    : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
501      public __gnu_debug::_Safe_unordered_container<
502		unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
503    {
504      typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
505						 _Pred, _Alloc> _Base;
506      typedef __gnu_debug::_Safe_unordered_container<unordered_multiset>
507		_Safe_base;
508      typedef typename _Base::const_iterator _Base_const_iterator;
509      typedef typename _Base::iterator _Base_iterator;
510      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
511      typedef typename _Base::local_iterator _Base_local_iterator;
512
513      typedef __gnu_cxx::__alloc_traits<typename
514					_Base::allocator_type> _Alloc_traits;
515
516    public:
517      typedef typename _Base::size_type       size_type;
518      typedef typename _Base::hasher          hasher;
519      typedef typename _Base::key_equal       key_equal;
520      typedef typename _Base::allocator_type  allocator_type;
521
522      typedef typename _Base::key_type        key_type;
523      typedef typename _Base::value_type      value_type;
524
525      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
526					  unordered_multiset> iterator;
527      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
528					  unordered_multiset> const_iterator;
529      typedef __gnu_debug::_Safe_local_iterator<
530	_Base_local_iterator, unordered_multiset> local_iterator;
531      typedef __gnu_debug::_Safe_local_iterator<
532	_Base_const_local_iterator, unordered_multiset> const_local_iterator;
533
534      explicit
535      unordered_multiset(size_type __n = 10,
536			 const hasher& __hf = hasher(),
537			 const key_equal& __eql = key_equal(),
538			 const allocator_type& __a = allocator_type())
539      : _Base(__n, __hf, __eql, __a) { }
540
541      template<typename _InputIterator>
542        unordered_multiset(_InputIterator __first, _InputIterator __last,
543			   size_type __n = 0,
544			   const hasher& __hf = hasher(),
545			   const key_equal& __eql = key_equal(),
546			   const allocator_type& __a = allocator_type())
547	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
548								     __last)),
549		__gnu_debug::__base(__last), __n,
550		__hf, __eql, __a) { }
551
552      unordered_multiset(const unordered_multiset&) = default;
553
554      unordered_multiset(const _Base& __x)
555      : _Base(__x) { }
556
557      unordered_multiset(unordered_multiset&&) = default;
558
559      explicit
560      unordered_multiset(const allocator_type& __a)
561	: _Base(__a)
562      { }
563
564      unordered_multiset(const unordered_multiset& __uset,
565			 const allocator_type& __a)
566	: _Base(__uset._M_base(), __a)
567      { }
568
569      unordered_multiset(unordered_multiset&& __uset,
570			 const allocator_type& __a)
571	: _Base(std::move(__uset._M_base()), __a)
572      { }
573
574      unordered_multiset(initializer_list<value_type> __l,
575			 size_type __n = 0,
576			 const hasher& __hf = hasher(),
577			 const key_equal& __eql = key_equal(),
578			 const allocator_type& __a = allocator_type())
579      : _Base(__l, __n, __hf, __eql, __a) { }
580
581      ~unordered_multiset() noexcept { }
582
583      unordered_multiset&
584      operator=(const unordered_multiset& __x)
585      {
586	_M_base() = __x._M_base();
587	this->_M_invalidate_all();
588	return *this;
589      }
590
591      unordered_multiset&
592      operator=(unordered_multiset&& __x)
593      noexcept(_Alloc_traits::_S_nothrow_move())
594      {
595	__glibcxx_check_self_move_assign(__x);
596	bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
597	    || __x.get_allocator() == this->get_allocator();
598	_M_base() = std::move(__x._M_base());
599	if (__xfer_memory)
600	  this->_M_swap(__x);
601	else
602	  this->_M_invalidate_all();
603	__x._M_invalidate_all();
604	return *this;
605      }
606
607      unordered_multiset&
608      operator=(initializer_list<value_type> __l)
609      {
610	_M_base() = __l;
611	this->_M_invalidate_all();
612	return *this;
613      }
614
615      void
616      swap(unordered_multiset& __x)
617      noexcept(_Alloc_traits::_S_nothrow_swap())
618      {
619	if (!_Alloc_traits::_S_propagate_on_swap())
620	  __glibcxx_check_equal_allocs(__x);
621	_Base::swap(__x);
622	_Safe_base::_M_swap(__x);
623      }
624
625      void
626      clear() noexcept
627      {
628	_Base::clear();
629	this->_M_invalidate_all();
630      }
631
632      iterator
633      begin() noexcept
634      { return iterator(_Base::begin(), this); }
635
636      const_iterator
637      begin() const noexcept
638      { return const_iterator(_Base::begin(), this); }
639
640      iterator
641      end() noexcept
642      { return iterator(_Base::end(), this); }
643
644      const_iterator
645      end() const noexcept
646      { return const_iterator(_Base::end(), this); }
647
648      const_iterator
649      cbegin() const noexcept
650      { return const_iterator(_Base::begin(), this); }
651
652      const_iterator
653      cend() const noexcept
654      { return const_iterator(_Base::end(), this); }
655
656      // local versions
657      local_iterator
658      begin(size_type __b)
659      {
660	__glibcxx_check_bucket_index(__b);
661	return local_iterator(_Base::begin(__b), this);
662      }
663
664      local_iterator
665      end(size_type __b)
666      {
667	__glibcxx_check_bucket_index(__b);
668	return local_iterator(_Base::end(__b), this);
669      }
670
671      const_local_iterator
672      begin(size_type __b) const
673      {
674	__glibcxx_check_bucket_index(__b);
675	return const_local_iterator(_Base::begin(__b), this);
676      }
677
678      const_local_iterator
679      end(size_type __b) const
680      {
681	__glibcxx_check_bucket_index(__b);
682	return const_local_iterator(_Base::end(__b), this);
683      }
684
685      const_local_iterator
686      cbegin(size_type __b) const
687      {
688	__glibcxx_check_bucket_index(__b);
689	return const_local_iterator(_Base::cbegin(__b), this);
690      }
691
692      const_local_iterator
693      cend(size_type __b) const
694      {
695	__glibcxx_check_bucket_index(__b);
696	return const_local_iterator(_Base::cend(__b), this);
697      }
698
699      size_type
700      bucket_size(size_type __b) const
701      {
702	__glibcxx_check_bucket_index(__b);
703	return _Base::bucket_size(__b);
704      }
705
706      float
707      max_load_factor() const noexcept
708      { return _Base::max_load_factor(); }
709
710      void
711      max_load_factor(float __f)
712      {
713	__glibcxx_check_max_load_factor(__f);
714	_Base::max_load_factor(__f);
715      }
716
717      template<typename... _Args>
718	iterator
719	emplace(_Args&&... __args)
720	{
721	  size_type __bucket_count = this->bucket_count();
722	  _Base_iterator __it
723	    = _Base::emplace(std::forward<_Args>(__args)...);
724	  _M_check_rehashed(__bucket_count);
725	  return iterator(__it, this);
726	}
727
728      template<typename... _Args>
729	iterator
730	emplace_hint(const_iterator __hint, _Args&&... __args)
731	{
732	  __glibcxx_check_insert(__hint);
733	  size_type __bucket_count = this->bucket_count();
734	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
735					std::forward<_Args>(__args)...);
736	  _M_check_rehashed(__bucket_count);
737	  return iterator(__it, this);
738	}
739
740      iterator
741      insert(const value_type& __obj)
742      {
743	size_type __bucket_count = this->bucket_count();
744	_Base_iterator __it = _Base::insert(__obj);
745	_M_check_rehashed(__bucket_count);
746	return iterator(__it, this);
747      }
748
749      iterator
750      insert(const_iterator __hint, const value_type& __obj)
751      {
752	__glibcxx_check_insert(__hint);
753	size_type __bucket_count = this->bucket_count();
754	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
755	_M_check_rehashed(__bucket_count);
756	return iterator(__it, this);
757      }
758
759      iterator
760      insert(value_type&& __obj)
761      {
762	size_type __bucket_count = this->bucket_count();
763	_Base_iterator __it = _Base::insert(std::move(__obj));
764	_M_check_rehashed(__bucket_count);
765	return iterator(__it, this);
766      }
767
768      iterator
769      insert(const_iterator __hint, value_type&& __obj)
770      {
771	__glibcxx_check_insert(__hint);
772	size_type __bucket_count = this->bucket_count();
773	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
774	_M_check_rehashed(__bucket_count);
775	return iterator(__it, this);
776      }
777
778      void
779      insert(std::initializer_list<value_type> __l)
780      {
781	size_type __bucket_count = this->bucket_count();
782	_Base::insert(__l);
783	_M_check_rehashed(__bucket_count);
784      }
785
786      template<typename _InputIterator>
787	void
788	insert(_InputIterator __first, _InputIterator __last)
789	{
790	  __glibcxx_check_valid_range(__first, __last);
791	  size_type __bucket_count = this->bucket_count();
792	  _Base::insert(__gnu_debug::__base(__first),
793			__gnu_debug::__base(__last));
794	  _M_check_rehashed(__bucket_count);
795	}
796
797      iterator
798      find(const key_type& __key)
799      { return iterator(_Base::find(__key), this); }
800
801      const_iterator
802      find(const key_type& __key) const
803      { return const_iterator(_Base::find(__key), this); }
804
805      std::pair<iterator, iterator>
806      equal_range(const key_type& __key)
807      {
808	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
809	__pair_type __res = _Base::equal_range(__key);
810	return std::make_pair(iterator(__res.first, this),
811			      iterator(__res.second, this));
812      }
813
814      std::pair<const_iterator, const_iterator>
815      equal_range(const key_type& __key) const
816      {
817	std::pair<_Base_const_iterator, _Base_const_iterator>
818	  __res = _Base::equal_range(__key);
819	return std::make_pair(const_iterator(__res.first, this),
820			      const_iterator(__res.second, this));
821      }
822
823      size_type
824      erase(const key_type& __key)
825      {
826	size_type __ret(0);
827	std::pair<_Base_iterator, _Base_iterator> __pair =
828	  _Base::equal_range(__key);
829	for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
830	  {
831	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
832			    { return __it == __victim; });
833	    this->_M_invalidate_local_if(
834			    [__victim](_Base_const_local_iterator __it)
835			    { return __it._M_curr() == __victim._M_cur; });
836	    _Base::erase(__victim++);
837	    ++__ret;
838	  }
839	return __ret;
840      }
841
842      iterator
843      erase(const_iterator __it)
844      {
845	__glibcxx_check_erase(__it);
846	_Base_const_iterator __victim = __it.base();
847	this->_M_invalidate_if([__victim](_Base_const_iterator __it)
848			{ return __it == __victim; });
849	this->_M_invalidate_local_if(
850			[__victim](_Base_const_local_iterator __it)
851			{ return __it._M_curr() == __victim._M_cur; });
852	return iterator(_Base::erase(__it.base()), this);
853      }
854
855      iterator
856      erase(iterator __it)
857      { return erase(const_iterator(__it)); }
858
859      iterator
860      erase(const_iterator __first, const_iterator __last)
861      {
862	__glibcxx_check_erase_range(__first, __last);
863	for (_Base_const_iterator __tmp = __first.base();
864	     __tmp != __last.base(); ++__tmp)
865	  {
866	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
867				  _M_message(__gnu_debug::__msg_valid_range)
868				  ._M_iterator(__first, "first")
869				  ._M_iterator(__last, "last"));
870	    this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
871			    { return __it == __tmp; });
872	    this->_M_invalidate_local_if(
873			    [__tmp](_Base_const_local_iterator __it)
874			    { return __it._M_curr() == __tmp._M_cur; });
875	  }
876	return iterator(_Base::erase(__first.base(),
877				     __last.base()), this);
878      }
879
880      _Base&
881      _M_base() noexcept       { return *this; }
882
883      const _Base&
884      _M_base() const noexcept { return *this; }
885
886    private:
887      void
888      _M_invalidate_locals()
889      {
890	_Base_local_iterator __local_end = _Base::end(0);
891	this->_M_invalidate_local_if(
892			[__local_end](_Base_const_local_iterator __it)
893			{ return __it != __local_end; });
894      }
895
896      void
897      _M_invalidate_all()
898      {
899	_Base_iterator __end = _Base::end();
900	this->_M_invalidate_if([__end](_Base_const_iterator __it)
901			{ return __it != __end; });
902	_M_invalidate_locals();
903      }
904
905      void
906      _M_check_rehashed(size_type __prev_count)
907      {
908	if (__prev_count != this->bucket_count())
909	  _M_invalidate_locals();
910      }
911    };
912
913  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
914    inline void
915    swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
916	 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
917    { __x.swap(__y); }
918
919  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
920    inline bool
921    operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
922	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
923    { return __x._M_base() == __y._M_base(); }
924
925  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
926    inline bool
927    operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
928	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
929    { return !(__x == __y); }
930
931} // namespace __debug
932} // namespace std
933
934#endif // C++11
935
936#endif
937