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