xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/debug/unordered_set (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino// Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
2e4b17023SJohn Marino
3*5ce9237cSJohn Marino// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013
4e4b17023SJohn Marino// Free Software Foundation, Inc.
5e4b17023SJohn Marino//
6e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library.  This library is free
7e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the
8e4b17023SJohn Marino// terms of the GNU General Public License as published by the
9e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option)
10e4b17023SJohn Marino// any later version.
11e4b17023SJohn Marino
12e4b17023SJohn Marino// This library is distributed in the hope that it will be useful,
13e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of
14e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15e4b17023SJohn Marino// GNU General Public License for more details.
16e4b17023SJohn Marino
17e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional
18e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version
19e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation.
20e4b17023SJohn Marino
21e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and
22e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program;
23e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24e4b17023SJohn Marino// <http://www.gnu.org/licenses/>.
25e4b17023SJohn Marino
26e4b17023SJohn Marino/** @file debug/unordered_set
27e4b17023SJohn Marino *  This file is a GNU debug extension to the Standard C++ Library.
28e4b17023SJohn Marino */
29e4b17023SJohn Marino
30e4b17023SJohn Marino#ifndef _GLIBCXX_DEBUG_UNORDERED_SET
31e4b17023SJohn Marino#define _GLIBCXX_DEBUG_UNORDERED_SET 1
32e4b17023SJohn Marino
33e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__
34e4b17023SJohn Marino# include <bits/c++0x_warning.h>
35e4b17023SJohn Marino#else
36e4b17023SJohn Marino# include <unordered_set>
37e4b17023SJohn Marino
38e4b17023SJohn Marino#include <debug/safe_unordered_container.h>
39e4b17023SJohn Marino#include <debug/safe_iterator.h>
40e4b17023SJohn Marino#include <debug/safe_local_iterator.h>
41e4b17023SJohn Marino
42e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default)
43e4b17023SJohn Marino{
44e4b17023SJohn Marinonamespace __debug
45e4b17023SJohn Marino{
46e4b17023SJohn Marino  /// Class std::unordered_set with safety/checking/debug instrumentation.
47e4b17023SJohn Marino  template<typename _Value,
48e4b17023SJohn Marino	   typename _Hash = std::hash<_Value>,
49e4b17023SJohn Marino	   typename _Pred = std::equal_to<_Value>,
50e4b17023SJohn Marino	   typename _Alloc = std::allocator<_Value> >
51e4b17023SJohn Marino    class unordered_set
52e4b17023SJohn Marino    : public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
53e4b17023SJohn Marino      public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
54e4b17023SJohn Marino						       _Pred, _Alloc> >
55e4b17023SJohn Marino    {
56e4b17023SJohn Marino      typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
57e4b17023SJohn Marino					    _Pred, _Alloc> _Base;
58e4b17023SJohn Marino      typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
59e4b17023SJohn Marino      typedef typename _Base::const_iterator _Base_const_iterator;
60e4b17023SJohn Marino      typedef typename _Base::iterator _Base_iterator;
61e4b17023SJohn Marino      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
62e4b17023SJohn Marino      typedef typename _Base::local_iterator _Base_local_iterator;
63e4b17023SJohn Marino
64e4b17023SJohn Marino    public:
65e4b17023SJohn Marino      typedef typename _Base::size_type       size_type;
66e4b17023SJohn Marino      typedef typename _Base::hasher          hasher;
67e4b17023SJohn Marino      typedef typename _Base::key_equal       key_equal;
68e4b17023SJohn Marino      typedef typename _Base::allocator_type  allocator_type;
69e4b17023SJohn Marino
70e4b17023SJohn Marino      typedef typename _Base::key_type        key_type;
71e4b17023SJohn Marino      typedef typename _Base::value_type      value_type;
72e4b17023SJohn Marino
73e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
74e4b17023SJohn Marino					  unordered_set> iterator;
75e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
76e4b17023SJohn Marino					  unordered_set> const_iterator;
77e4b17023SJohn Marino      typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
78e4b17023SJohn Marino					  unordered_set> local_iterator;
79e4b17023SJohn Marino      typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
80e4b17023SJohn Marino					  unordered_set> const_local_iterator;
81e4b17023SJohn Marino
82e4b17023SJohn Marino      explicit
83e4b17023SJohn Marino      unordered_set(size_type __n = 10,
84e4b17023SJohn Marino		    const hasher& __hf = hasher(),
85e4b17023SJohn Marino		    const key_equal& __eql = key_equal(),
86e4b17023SJohn Marino		    const allocator_type& __a = allocator_type())
87e4b17023SJohn Marino      : _Base(__n, __hf, __eql, __a) { }
88e4b17023SJohn Marino
89e4b17023SJohn Marino      template<typename _InputIterator>
90e4b17023SJohn Marino        unordered_set(_InputIterator __first, _InputIterator __last,
91e4b17023SJohn Marino		      size_type __n = 0,
92e4b17023SJohn Marino		      const hasher& __hf = hasher(),
93e4b17023SJohn Marino		      const key_equal& __eql = key_equal(),
94e4b17023SJohn Marino		      const allocator_type& __a = allocator_type())
95e4b17023SJohn Marino	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
96e4b17023SJohn Marino								     __last)),
97e4b17023SJohn Marino		__gnu_debug::__base(__last), __n,
98e4b17023SJohn Marino		__hf, __eql, __a) { }
99e4b17023SJohn Marino
100*5ce9237cSJohn Marino      unordered_set(const unordered_set& __x) = default;
101e4b17023SJohn Marino
102e4b17023SJohn Marino      unordered_set(const _Base& __x)
103e4b17023SJohn Marino      : _Base(__x) { }
104e4b17023SJohn Marino
105*5ce9237cSJohn Marino      unordered_set(unordered_set&& __x) = default;
106e4b17023SJohn Marino
107e4b17023SJohn Marino      unordered_set(initializer_list<value_type> __l,
108e4b17023SJohn Marino		    size_type __n = 0,
109e4b17023SJohn Marino		    const hasher& __hf = hasher(),
110e4b17023SJohn Marino		    const key_equal& __eql = key_equal(),
111e4b17023SJohn Marino		    const allocator_type& __a = allocator_type())
112e4b17023SJohn Marino      : _Base(__l, __n, __hf, __eql, __a) { }
113e4b17023SJohn Marino
114e4b17023SJohn Marino      ~unordered_set() noexcept { }
115e4b17023SJohn Marino
116e4b17023SJohn Marino      unordered_set&
117e4b17023SJohn Marino      operator=(const unordered_set& __x)
118e4b17023SJohn Marino      {
119e4b17023SJohn Marino	*static_cast<_Base*>(this) = __x;
120e4b17023SJohn Marino	this->_M_invalidate_all();
121e4b17023SJohn Marino	return *this;
122e4b17023SJohn Marino      }
123e4b17023SJohn Marino
124e4b17023SJohn Marino      unordered_set&
125e4b17023SJohn Marino      operator=(unordered_set&& __x)
126e4b17023SJohn Marino      {
127e4b17023SJohn Marino	// NB: DR 1204.
128e4b17023SJohn Marino	// NB: DR 675.
129e4b17023SJohn Marino	clear();
130e4b17023SJohn Marino	swap(__x);
131e4b17023SJohn Marino	return *this;
132e4b17023SJohn Marino      }
133e4b17023SJohn Marino
134e4b17023SJohn Marino      unordered_set&
135e4b17023SJohn Marino      operator=(initializer_list<value_type> __l)
136e4b17023SJohn Marino      {
137e4b17023SJohn Marino	this->clear();
138e4b17023SJohn Marino	this->insert(__l);
139e4b17023SJohn Marino	return *this;
140e4b17023SJohn Marino      }
141e4b17023SJohn Marino
142e4b17023SJohn Marino      void
143e4b17023SJohn Marino      swap(unordered_set& __x)
144e4b17023SJohn Marino      {
145e4b17023SJohn Marino	_Base::swap(__x);
146e4b17023SJohn Marino	_Safe_base::_M_swap(__x);
147e4b17023SJohn Marino      }
148e4b17023SJohn Marino
149e4b17023SJohn Marino      void
150e4b17023SJohn Marino      clear() noexcept
151e4b17023SJohn Marino      {
152e4b17023SJohn Marino	_Base::clear();
153e4b17023SJohn Marino	this->_M_invalidate_all();
154e4b17023SJohn Marino      }
155e4b17023SJohn Marino
156e4b17023SJohn Marino      iterator
157e4b17023SJohn Marino      begin() noexcept
158e4b17023SJohn Marino      { return iterator(_Base::begin(), this); }
159e4b17023SJohn Marino
160e4b17023SJohn Marino      const_iterator
161e4b17023SJohn Marino      begin() const noexcept
162e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
163e4b17023SJohn Marino
164e4b17023SJohn Marino      iterator
165e4b17023SJohn Marino      end() noexcept
166e4b17023SJohn Marino      { return iterator(_Base::end(), this); }
167e4b17023SJohn Marino
168e4b17023SJohn Marino      const_iterator
169e4b17023SJohn Marino      end() const noexcept
170e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
171e4b17023SJohn Marino
172e4b17023SJohn Marino      const_iterator
173e4b17023SJohn Marino      cbegin() const noexcept
174e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
175e4b17023SJohn Marino
176e4b17023SJohn Marino      const_iterator
177e4b17023SJohn Marino      cend() const noexcept
178e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
179e4b17023SJohn Marino
180e4b17023SJohn Marino      // local versions
181e4b17023SJohn Marino      local_iterator
182e4b17023SJohn Marino      begin(size_type __b)
183e4b17023SJohn Marino      { return local_iterator(_Base::begin(__b), __b, this); }
184e4b17023SJohn Marino
185e4b17023SJohn Marino      local_iterator
186e4b17023SJohn Marino      end(size_type __b)
187e4b17023SJohn Marino      { return local_iterator(_Base::end(__b), __b, this); }
188e4b17023SJohn Marino
189e4b17023SJohn Marino      const_local_iterator
190e4b17023SJohn Marino      begin(size_type __b) const
191e4b17023SJohn Marino      { return const_local_iterator(_Base::begin(__b), __b, this); }
192e4b17023SJohn Marino
193e4b17023SJohn Marino      const_local_iterator
194e4b17023SJohn Marino      end(size_type __b) const
195e4b17023SJohn Marino      { return const_local_iterator(_Base::end(__b), __b, this); }
196e4b17023SJohn Marino
197e4b17023SJohn Marino      const_local_iterator
198e4b17023SJohn Marino      cbegin(size_type __b) const
199e4b17023SJohn Marino      { return const_local_iterator(_Base::cbegin(__b), __b, this); }
200e4b17023SJohn Marino
201e4b17023SJohn Marino      const_local_iterator
202e4b17023SJohn Marino      cend(size_type __b) const
203e4b17023SJohn Marino      { return const_local_iterator(_Base::cend(__b), __b, this); }
204e4b17023SJohn Marino
205e4b17023SJohn Marino      template<typename... _Args>
206e4b17023SJohn Marino	std::pair<iterator, bool>
207e4b17023SJohn Marino	emplace(_Args&&... __args)
208e4b17023SJohn Marino	{
209e4b17023SJohn Marino	  size_type __bucket_count = this->bucket_count();
210e4b17023SJohn Marino	  std::pair<_Base_iterator, bool> __res
211e4b17023SJohn Marino	    = _Base::emplace(std::forward<_Args>(__args)...);
212e4b17023SJohn Marino	  _M_check_rehashed(__bucket_count);
213e4b17023SJohn Marino	  return std::make_pair(iterator(__res.first, this), __res.second);
214e4b17023SJohn Marino	}
215e4b17023SJohn Marino
216e4b17023SJohn Marino      template<typename... _Args>
217e4b17023SJohn Marino	iterator
218e4b17023SJohn Marino	emplace_hint(const_iterator __hint, _Args&&... __args)
219e4b17023SJohn Marino	{
220e4b17023SJohn Marino	  __glibcxx_check_insert(__hint);
221e4b17023SJohn Marino	  size_type __bucket_count = this->bucket_count();
222e4b17023SJohn Marino	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
223e4b17023SJohn Marino					std::forward<_Args>(__args)...);
224e4b17023SJohn Marino	  _M_check_rehashed(__bucket_count);
225e4b17023SJohn Marino	  return iterator(__it, this);
226e4b17023SJohn Marino	}
227e4b17023SJohn Marino
228e4b17023SJohn Marino      std::pair<iterator, bool>
229e4b17023SJohn Marino      insert(const value_type& __obj)
230e4b17023SJohn Marino      {
231e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
232e4b17023SJohn Marino	typedef std::pair<_Base_iterator, bool> __pair_type;
233e4b17023SJohn Marino	  __pair_type __res = _Base::insert(__obj);
234e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
235e4b17023SJohn Marino	return std::make_pair(iterator(__res.first, this), __res.second);
236e4b17023SJohn Marino      }
237e4b17023SJohn Marino
238e4b17023SJohn Marino      iterator
239e4b17023SJohn Marino      insert(const_iterator __hint, const value_type& __obj)
240e4b17023SJohn Marino      {
241e4b17023SJohn Marino	__glibcxx_check_insert(__hint);
242e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
243e4b17023SJohn Marino	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
244e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
245e4b17023SJohn Marino	return iterator(__it, this);
246e4b17023SJohn Marino      }
247e4b17023SJohn Marino
248e4b17023SJohn Marino      std::pair<iterator, bool>
249e4b17023SJohn Marino      insert(value_type&& __obj)
250e4b17023SJohn Marino      {
251e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
252e4b17023SJohn Marino	typedef std::pair<typename _Base::iterator, bool> __pair_type;
253e4b17023SJohn Marino	  __pair_type __res = _Base::insert(std::move(__obj));
254e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
255e4b17023SJohn Marino	return std::make_pair(iterator(__res.first, this), __res.second);
256e4b17023SJohn Marino      }
257e4b17023SJohn Marino
258e4b17023SJohn Marino      iterator
259e4b17023SJohn Marino      insert(const_iterator __hint, value_type&& __obj)
260e4b17023SJohn Marino      {
261e4b17023SJohn Marino	__glibcxx_check_insert(__hint);
262e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
263e4b17023SJohn Marino	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
264e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
265e4b17023SJohn Marino	return iterator(__it, this);
266e4b17023SJohn Marino      }
267e4b17023SJohn Marino
268e4b17023SJohn Marino      void
269e4b17023SJohn Marino      insert(std::initializer_list<value_type> __l)
270e4b17023SJohn Marino      {
271e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
272e4b17023SJohn Marino	_Base::insert(__l);
273e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
274e4b17023SJohn Marino      }
275e4b17023SJohn Marino
276e4b17023SJohn Marino      template<typename _InputIterator>
277e4b17023SJohn Marino	void
278e4b17023SJohn Marino	insert(_InputIterator __first, _InputIterator __last)
279e4b17023SJohn Marino	{
280e4b17023SJohn Marino	  __glibcxx_check_valid_range(__first, __last);
281e4b17023SJohn Marino	  size_type __bucket_count = this->bucket_count();
282e4b17023SJohn Marino	  _Base::insert(__gnu_debug::__base(__first),
283e4b17023SJohn Marino			__gnu_debug::__base(__last));
284e4b17023SJohn Marino	  _M_check_rehashed(__bucket_count);
285e4b17023SJohn Marino	}
286e4b17023SJohn Marino
287e4b17023SJohn Marino      iterator
288e4b17023SJohn Marino      find(const key_type& __key)
289e4b17023SJohn Marino      { return iterator(_Base::find(__key), this); }
290e4b17023SJohn Marino
291e4b17023SJohn Marino      const_iterator
292e4b17023SJohn Marino      find(const key_type& __key) const
293e4b17023SJohn Marino      { return const_iterator(_Base::find(__key), this); }
294e4b17023SJohn Marino
295e4b17023SJohn Marino      std::pair<iterator, iterator>
296e4b17023SJohn Marino      equal_range(const key_type& __key)
297e4b17023SJohn Marino      {
298e4b17023SJohn Marino	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
299e4b17023SJohn Marino	__pair_type __res = _Base::equal_range(__key);
300e4b17023SJohn Marino	return std::make_pair(iterator(__res.first, this),
301e4b17023SJohn Marino			      iterator(__res.second, this));
302e4b17023SJohn Marino      }
303e4b17023SJohn Marino
304e4b17023SJohn Marino      std::pair<const_iterator, const_iterator>
305e4b17023SJohn Marino      equal_range(const key_type& __key) const
306e4b17023SJohn Marino      {
307e4b17023SJohn Marino	std::pair<_Base_const_iterator, _Base_const_iterator>
308e4b17023SJohn Marino	  __res = _Base::equal_range(__key);
309e4b17023SJohn Marino	return std::make_pair(const_iterator(__res.first, this),
310e4b17023SJohn Marino			      const_iterator(__res.second, this));
311e4b17023SJohn Marino      }
312e4b17023SJohn Marino
313e4b17023SJohn Marino      size_type
314e4b17023SJohn Marino      erase(const key_type& __key)
315e4b17023SJohn Marino      {
316e4b17023SJohn Marino	size_type __ret(0);
317e4b17023SJohn Marino	_Base_iterator __victim(_Base::find(__key));
318e4b17023SJohn Marino	if (__victim != _Base::end())
319e4b17023SJohn Marino	  {
320e4b17023SJohn Marino	    this->_M_invalidate_if(
321e4b17023SJohn Marino			    [__victim](_Base_const_iterator __it)
322e4b17023SJohn Marino			    { return __it == __victim; });
323e4b17023SJohn Marino	    _Base_local_iterator __local_victim = _S_to_local(__victim);
324e4b17023SJohn Marino	    this->_M_invalidate_local_if(
325e4b17023SJohn Marino			    [__local_victim](_Base_const_local_iterator __it)
326e4b17023SJohn Marino			    { return __it == __local_victim; });
327e4b17023SJohn Marino	    size_type __bucket_count = this->bucket_count();
328e4b17023SJohn Marino	    _Base::erase(__victim);
329e4b17023SJohn Marino	    _M_check_rehashed(__bucket_count);
330e4b17023SJohn Marino	    __ret = 1;
331e4b17023SJohn Marino	  }
332e4b17023SJohn Marino	return __ret;
333e4b17023SJohn Marino      }
334e4b17023SJohn Marino
335e4b17023SJohn Marino      iterator
336e4b17023SJohn Marino      erase(const_iterator __it)
337e4b17023SJohn Marino      {
338e4b17023SJohn Marino	__glibcxx_check_erase(__it);
339e4b17023SJohn Marino	_Base_const_iterator __victim = __it.base();
340e4b17023SJohn Marino	this->_M_invalidate_if(
341e4b17023SJohn Marino			[__victim](_Base_const_iterator __it)
342e4b17023SJohn Marino			{ return __it == __victim; });
343e4b17023SJohn Marino	_Base_const_local_iterator __local_victim = _S_to_local(__victim);
344e4b17023SJohn Marino	this->_M_invalidate_local_if(
345e4b17023SJohn Marino			[__local_victim](_Base_const_local_iterator __it)
346e4b17023SJohn Marino			{ return __it == __local_victim; });
347e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
348e4b17023SJohn Marino	_Base_iterator __next = _Base::erase(__it.base());
349e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
350e4b17023SJohn Marino	return iterator(__next, this);
351e4b17023SJohn Marino      }
352e4b17023SJohn Marino
353e4b17023SJohn Marino      iterator
354e4b17023SJohn Marino      erase(iterator __it)
355e4b17023SJohn Marino      { return erase(const_iterator(__it)); }
356e4b17023SJohn Marino
357e4b17023SJohn Marino      iterator
358e4b17023SJohn Marino      erase(const_iterator __first, const_iterator __last)
359e4b17023SJohn Marino      {
360e4b17023SJohn Marino	__glibcxx_check_erase_range(__first, __last);
361e4b17023SJohn Marino	for (_Base_const_iterator __tmp = __first.base();
362e4b17023SJohn Marino	     __tmp != __last.base(); ++__tmp)
363e4b17023SJohn Marino	  {
364e4b17023SJohn Marino	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
365e4b17023SJohn Marino				  _M_message(__gnu_debug::__msg_valid_range)
366e4b17023SJohn Marino				  ._M_iterator(__first, "first")
367e4b17023SJohn Marino				  ._M_iterator(__last, "last"));
368e4b17023SJohn Marino	    this->_M_invalidate_if(
369e4b17023SJohn Marino			    [__tmp](_Base_const_iterator __it)
370e4b17023SJohn Marino			    { return __it == __tmp; });
371e4b17023SJohn Marino	    _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
372e4b17023SJohn Marino	    this->_M_invalidate_local_if(
373e4b17023SJohn Marino			    [__local_tmp](_Base_const_local_iterator __it)
374e4b17023SJohn Marino			    { return __it == __local_tmp; });
375e4b17023SJohn Marino	  }
376e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
377e4b17023SJohn Marino	_Base_iterator __next = _Base::erase(__first.base(),
378e4b17023SJohn Marino					     __last.base());
379e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
380e4b17023SJohn Marino	return iterator(__next, this);
381e4b17023SJohn Marino      }
382e4b17023SJohn Marino
383e4b17023SJohn Marino      _Base&
384e4b17023SJohn Marino      _M_base() noexcept       { return *this; }
385e4b17023SJohn Marino
386e4b17023SJohn Marino      const _Base&
387e4b17023SJohn Marino      _M_base() const noexcept { return *this; }
388e4b17023SJohn Marino
389e4b17023SJohn Marino    private:
390e4b17023SJohn Marino      void
391e4b17023SJohn Marino      _M_invalidate_locals()
392e4b17023SJohn Marino      {
393e4b17023SJohn Marino	_Base_local_iterator __local_end = _Base::end(0);
394e4b17023SJohn Marino	this->_M_invalidate_local_if(
395e4b17023SJohn Marino			[__local_end](_Base_const_local_iterator __it)
396e4b17023SJohn Marino			{ return __it != __local_end; });
397e4b17023SJohn Marino      }
398e4b17023SJohn Marino
399e4b17023SJohn Marino      void
400e4b17023SJohn Marino      _M_invalidate_all()
401e4b17023SJohn Marino      {
402e4b17023SJohn Marino	_Base_iterator __end = _Base::end();
403e4b17023SJohn Marino	this->_M_invalidate_if(
404e4b17023SJohn Marino			[__end](_Base_const_iterator __it)
405e4b17023SJohn Marino			{ return __it != __end; });
406e4b17023SJohn Marino	_M_invalidate_locals();
407e4b17023SJohn Marino      }
408e4b17023SJohn Marino
409e4b17023SJohn Marino      void
410e4b17023SJohn Marino      _M_check_rehashed(size_type __prev_count)
411e4b17023SJohn Marino      {
412e4b17023SJohn Marino	if (__prev_count != this->bucket_count())
413e4b17023SJohn Marino	  _M_invalidate_locals();
414e4b17023SJohn Marino      }
415e4b17023SJohn Marino
416e4b17023SJohn Marino      static _Base_local_iterator
417e4b17023SJohn Marino      _S_to_local(_Base_iterator __it)
418e4b17023SJohn Marino      {
419e4b17023SJohn Marino        // The returned local iterator will not be incremented so we don't
420e4b17023SJohn Marino	// need to compute __it's node bucket
421e4b17023SJohn Marino	return _Base_local_iterator(__it._M_cur, 0, 0);
422e4b17023SJohn Marino      }
423e4b17023SJohn Marino
424e4b17023SJohn Marino      static _Base_const_local_iterator
425e4b17023SJohn Marino      _S_to_local(_Base_const_iterator __it)
426e4b17023SJohn Marino      {
427e4b17023SJohn Marino        // The returned local iterator will not be incremented so we don't
428e4b17023SJohn Marino	// need to compute __it's node bucket
429e4b17023SJohn Marino	return _Base_const_local_iterator(__it._M_cur, 0, 0);
430e4b17023SJohn Marino      }
431e4b17023SJohn Marino    };
432e4b17023SJohn Marino
433e4b17023SJohn Marino  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
434e4b17023SJohn Marino    inline void
435e4b17023SJohn Marino    swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
436e4b17023SJohn Marino	 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
437e4b17023SJohn Marino    { __x.swap(__y); }
438e4b17023SJohn Marino
439e4b17023SJohn Marino  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
440e4b17023SJohn Marino    inline bool
441e4b17023SJohn Marino    operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
442e4b17023SJohn Marino	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
443e4b17023SJohn Marino    { return __x._M_equal(__y); }
444e4b17023SJohn Marino
445e4b17023SJohn Marino  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
446e4b17023SJohn Marino    inline bool
447e4b17023SJohn Marino    operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
448e4b17023SJohn Marino	       const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
449e4b17023SJohn Marino    { return !(__x == __y); }
450e4b17023SJohn Marino
451e4b17023SJohn Marino
452e4b17023SJohn Marino  /// Class std::unordered_multiset with safety/checking/debug instrumentation.
453e4b17023SJohn Marino  template<typename _Value,
454e4b17023SJohn Marino	   typename _Hash = std::hash<_Value>,
455e4b17023SJohn Marino	   typename _Pred = std::equal_to<_Value>,
456e4b17023SJohn Marino	   typename _Alloc = std::allocator<_Value> >
457e4b17023SJohn Marino    class unordered_multiset
458e4b17023SJohn Marino    : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
459e4b17023SJohn Marino      public __gnu_debug::_Safe_unordered_container<
460e4b17023SJohn Marino		unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
461e4b17023SJohn Marino    {
462e4b17023SJohn Marino      typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
463e4b17023SJohn Marino						 _Pred, _Alloc> _Base;
464e4b17023SJohn Marino      typedef __gnu_debug::_Safe_unordered_container<unordered_multiset>
465e4b17023SJohn Marino		_Safe_base;
466e4b17023SJohn Marino      typedef typename _Base::const_iterator _Base_const_iterator;
467e4b17023SJohn Marino      typedef typename _Base::iterator _Base_iterator;
468e4b17023SJohn Marino      typedef typename _Base::const_local_iterator _Base_const_local_iterator;
469e4b17023SJohn Marino      typedef typename _Base::local_iterator _Base_local_iterator;
470e4b17023SJohn Marino
471e4b17023SJohn Marino    public:
472e4b17023SJohn Marino      typedef typename _Base::size_type       size_type;
473e4b17023SJohn Marino      typedef typename _Base::hasher          hasher;
474e4b17023SJohn Marino      typedef typename _Base::key_equal       key_equal;
475e4b17023SJohn Marino      typedef typename _Base::allocator_type  allocator_type;
476e4b17023SJohn Marino
477e4b17023SJohn Marino      typedef typename _Base::key_type        key_type;
478e4b17023SJohn Marino      typedef typename _Base::value_type      value_type;
479e4b17023SJohn Marino
480e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_iterator,
481e4b17023SJohn Marino					  unordered_multiset> iterator;
482e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
483e4b17023SJohn Marino					  unordered_multiset> const_iterator;
484e4b17023SJohn Marino      typedef __gnu_debug::_Safe_local_iterator<
485e4b17023SJohn Marino	_Base_local_iterator, unordered_multiset> local_iterator;
486e4b17023SJohn Marino      typedef __gnu_debug::_Safe_local_iterator<
487e4b17023SJohn Marino	_Base_const_local_iterator, unordered_multiset> const_local_iterator;
488e4b17023SJohn Marino
489e4b17023SJohn Marino      explicit
490e4b17023SJohn Marino      unordered_multiset(size_type __n = 10,
491e4b17023SJohn Marino			 const hasher& __hf = hasher(),
492e4b17023SJohn Marino			 const key_equal& __eql = key_equal(),
493e4b17023SJohn Marino			 const allocator_type& __a = allocator_type())
494e4b17023SJohn Marino      : _Base(__n, __hf, __eql, __a) { }
495e4b17023SJohn Marino
496e4b17023SJohn Marino      template<typename _InputIterator>
497e4b17023SJohn Marino        unordered_multiset(_InputIterator __first, _InputIterator __last,
498e4b17023SJohn Marino			   size_type __n = 0,
499e4b17023SJohn Marino			   const hasher& __hf = hasher(),
500e4b17023SJohn Marino			   const key_equal& __eql = key_equal(),
501e4b17023SJohn Marino			   const allocator_type& __a = allocator_type())
502e4b17023SJohn Marino	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
503e4b17023SJohn Marino								     __last)),
504e4b17023SJohn Marino		__gnu_debug::__base(__last), __n,
505e4b17023SJohn Marino		__hf, __eql, __a) { }
506e4b17023SJohn Marino
507*5ce9237cSJohn Marino      unordered_multiset(const unordered_multiset& __x) = default;
508e4b17023SJohn Marino
509e4b17023SJohn Marino      unordered_multiset(const _Base& __x)
510e4b17023SJohn Marino      : _Base(__x) { }
511e4b17023SJohn Marino
512*5ce9237cSJohn Marino      unordered_multiset(unordered_multiset&& __x) = default;
513e4b17023SJohn Marino
514e4b17023SJohn Marino      unordered_multiset(initializer_list<value_type> __l,
515e4b17023SJohn Marino			 size_type __n = 0,
516e4b17023SJohn Marino			 const hasher& __hf = hasher(),
517e4b17023SJohn Marino			 const key_equal& __eql = key_equal(),
518e4b17023SJohn Marino			 const allocator_type& __a = allocator_type())
519e4b17023SJohn Marino      : _Base(__l, __n, __hf, __eql, __a) { }
520e4b17023SJohn Marino
521e4b17023SJohn Marino      ~unordered_multiset() noexcept { }
522e4b17023SJohn Marino
523e4b17023SJohn Marino      unordered_multiset&
524e4b17023SJohn Marino      operator=(const unordered_multiset& __x)
525e4b17023SJohn Marino      {
526e4b17023SJohn Marino	*static_cast<_Base*>(this) = __x;
527e4b17023SJohn Marino	this->_M_invalidate_all();
528e4b17023SJohn Marino	return *this;
529e4b17023SJohn Marino      }
530e4b17023SJohn Marino
531e4b17023SJohn Marino      unordered_multiset&
532e4b17023SJohn Marino      operator=(unordered_multiset&& __x)
533e4b17023SJohn Marino      {
534e4b17023SJohn Marino	// NB: DR 1204.
535e4b17023SJohn Marino        // NB: DR 675.
536e4b17023SJohn Marino	clear();
537e4b17023SJohn Marino	swap(__x);
538e4b17023SJohn Marino	return *this;
539e4b17023SJohn Marino      }
540e4b17023SJohn Marino
541e4b17023SJohn Marino      unordered_multiset&
542e4b17023SJohn Marino      operator=(initializer_list<value_type> __l)
543e4b17023SJohn Marino      {
544e4b17023SJohn Marino	this->clear();
545e4b17023SJohn Marino	this->insert(__l);
546e4b17023SJohn Marino	return *this;
547e4b17023SJohn Marino      }
548e4b17023SJohn Marino
549e4b17023SJohn Marino      void
550e4b17023SJohn Marino      swap(unordered_multiset& __x)
551e4b17023SJohn Marino      {
552e4b17023SJohn Marino	_Base::swap(__x);
553e4b17023SJohn Marino	_Safe_base::_M_swap(__x);
554e4b17023SJohn Marino      }
555e4b17023SJohn Marino
556e4b17023SJohn Marino      void
557e4b17023SJohn Marino      clear() noexcept
558e4b17023SJohn Marino      {
559e4b17023SJohn Marino	_Base::clear();
560e4b17023SJohn Marino	this->_M_invalidate_all();
561e4b17023SJohn Marino      }
562e4b17023SJohn Marino
563e4b17023SJohn Marino      iterator
564e4b17023SJohn Marino      begin() noexcept
565e4b17023SJohn Marino      { return iterator(_Base::begin(), this); }
566e4b17023SJohn Marino
567e4b17023SJohn Marino      const_iterator
568e4b17023SJohn Marino      begin() const noexcept
569e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
570e4b17023SJohn Marino
571e4b17023SJohn Marino      iterator
572e4b17023SJohn Marino      end() noexcept
573e4b17023SJohn Marino      { return iterator(_Base::end(), this); }
574e4b17023SJohn Marino
575e4b17023SJohn Marino      const_iterator
576e4b17023SJohn Marino      end() const noexcept
577e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
578e4b17023SJohn Marino
579e4b17023SJohn Marino      const_iterator
580e4b17023SJohn Marino      cbegin() const noexcept
581e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
582e4b17023SJohn Marino
583e4b17023SJohn Marino      const_iterator
584e4b17023SJohn Marino      cend() const noexcept
585e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
586e4b17023SJohn Marino
587e4b17023SJohn Marino      // local versions
588e4b17023SJohn Marino      local_iterator
589e4b17023SJohn Marino      begin(size_type __b)
590e4b17023SJohn Marino      { return local_iterator(_Base::begin(__b), __b, this); }
591e4b17023SJohn Marino
592e4b17023SJohn Marino      local_iterator
593e4b17023SJohn Marino      end(size_type __b)
594e4b17023SJohn Marino      { return local_iterator(_Base::end(__b), __b, this); }
595e4b17023SJohn Marino
596e4b17023SJohn Marino      const_local_iterator
597e4b17023SJohn Marino      begin(size_type __b) const
598e4b17023SJohn Marino      { return const_local_iterator(_Base::begin(__b), __b, this); }
599e4b17023SJohn Marino
600e4b17023SJohn Marino      const_local_iterator
601e4b17023SJohn Marino      end(size_type __b) const
602e4b17023SJohn Marino      { return const_local_iterator(_Base::end(__b), __b, this); }
603e4b17023SJohn Marino
604e4b17023SJohn Marino      const_local_iterator
605e4b17023SJohn Marino      cbegin(size_type __b) const
606e4b17023SJohn Marino      { return const_local_iterator(_Base::cbegin(__b), __b, this); }
607e4b17023SJohn Marino
608e4b17023SJohn Marino      const_local_iterator
609e4b17023SJohn Marino      cend(size_type __b) const
610e4b17023SJohn Marino      { return const_local_iterator(_Base::cend(__b), __b, this); }
611e4b17023SJohn Marino
612e4b17023SJohn Marino      template<typename... _Args>
613e4b17023SJohn Marino	iterator
614e4b17023SJohn Marino	emplace(_Args&&... __args)
615e4b17023SJohn Marino	{
616e4b17023SJohn Marino	  size_type __bucket_count = this->bucket_count();
617e4b17023SJohn Marino	  _Base_iterator __it
618e4b17023SJohn Marino	    = _Base::emplace(std::forward<_Args>(__args)...);
619e4b17023SJohn Marino	  _M_check_rehashed(__bucket_count);
620e4b17023SJohn Marino	  return iterator(__it, this);
621e4b17023SJohn Marino	}
622e4b17023SJohn Marino
623e4b17023SJohn Marino      template<typename... _Args>
624e4b17023SJohn Marino	iterator
625e4b17023SJohn Marino	emplace_hint(const_iterator __hint, _Args&&... __args)
626e4b17023SJohn Marino	{
627e4b17023SJohn Marino	  __glibcxx_check_insert(__hint);
628e4b17023SJohn Marino	  size_type __bucket_count = this->bucket_count();
629e4b17023SJohn Marino	  _Base_iterator __it = _Base::emplace_hint(__hint.base(),
630e4b17023SJohn Marino					std::forward<_Args>(__args)...);
631e4b17023SJohn Marino	  _M_check_rehashed(__bucket_count);
632e4b17023SJohn Marino	  return iterator(__it, this);
633e4b17023SJohn Marino	}
634e4b17023SJohn Marino
635e4b17023SJohn Marino      iterator
636e4b17023SJohn Marino      insert(const value_type& __obj)
637e4b17023SJohn Marino      {
638e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
639e4b17023SJohn Marino	_Base_iterator __it = _Base::insert(__obj);
640e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
641e4b17023SJohn Marino	return iterator(__it, this);
642e4b17023SJohn Marino      }
643e4b17023SJohn Marino
644e4b17023SJohn Marino      iterator
645e4b17023SJohn Marino      insert(const_iterator __hint, const value_type& __obj)
646e4b17023SJohn Marino      {
647e4b17023SJohn Marino	__glibcxx_check_insert(__hint);
648e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
649e4b17023SJohn Marino	_Base_iterator __it = _Base::insert(__hint.base(), __obj);
650e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
651e4b17023SJohn Marino	return iterator(__it, this);
652e4b17023SJohn Marino      }
653e4b17023SJohn Marino
654e4b17023SJohn Marino      iterator
655e4b17023SJohn Marino      insert(value_type&& __obj)
656e4b17023SJohn Marino      {
657e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
658e4b17023SJohn Marino	_Base_iterator __it = _Base::insert(std::move(__obj));
659e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
660e4b17023SJohn Marino	return iterator(__it, this);
661e4b17023SJohn Marino      }
662e4b17023SJohn Marino
663e4b17023SJohn Marino      iterator
664e4b17023SJohn Marino      insert(const_iterator __hint, value_type&& __obj)
665e4b17023SJohn Marino      {
666e4b17023SJohn Marino	__glibcxx_check_insert(__hint);
667e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
668e4b17023SJohn Marino	_Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
669e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
670e4b17023SJohn Marino	return iterator(__it, this);
671e4b17023SJohn Marino      }
672e4b17023SJohn Marino
673e4b17023SJohn Marino      void
674e4b17023SJohn Marino      insert(std::initializer_list<value_type> __l)
675e4b17023SJohn Marino      {
676e4b17023SJohn Marino	size_type __bucket_count = this->bucket_count();
677e4b17023SJohn Marino	_Base::insert(__l);
678e4b17023SJohn Marino	_M_check_rehashed(__bucket_count);
679e4b17023SJohn Marino      }
680e4b17023SJohn Marino
681e4b17023SJohn Marino      template<typename _InputIterator>
682e4b17023SJohn Marino	void
683e4b17023SJohn Marino	insert(_InputIterator __first, _InputIterator __last)
684e4b17023SJohn Marino	{
685e4b17023SJohn Marino	  __glibcxx_check_valid_range(__first, __last);
686e4b17023SJohn Marino	  size_type __bucket_count = this->bucket_count();
687e4b17023SJohn Marino	  _Base::insert(__gnu_debug::__base(__first),
688e4b17023SJohn Marino			__gnu_debug::__base(__last));
689e4b17023SJohn Marino	  _M_check_rehashed(__bucket_count);
690e4b17023SJohn Marino	}
691e4b17023SJohn Marino
692e4b17023SJohn Marino      iterator
693e4b17023SJohn Marino      find(const key_type& __key)
694e4b17023SJohn Marino      { return iterator(_Base::find(__key), this); }
695e4b17023SJohn Marino
696e4b17023SJohn Marino      const_iterator
697e4b17023SJohn Marino      find(const key_type& __key) const
698e4b17023SJohn Marino      { return const_iterator(_Base::find(__key), this); }
699e4b17023SJohn Marino
700e4b17023SJohn Marino      std::pair<iterator, iterator>
701e4b17023SJohn Marino      equal_range(const key_type& __key)
702e4b17023SJohn Marino      {
703e4b17023SJohn Marino	typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
704e4b17023SJohn Marino	__pair_type __res = _Base::equal_range(__key);
705e4b17023SJohn Marino	return std::make_pair(iterator(__res.first, this),
706e4b17023SJohn Marino			      iterator(__res.second, this));
707e4b17023SJohn Marino      }
708e4b17023SJohn Marino
709e4b17023SJohn Marino      std::pair<const_iterator, const_iterator>
710e4b17023SJohn Marino      equal_range(const key_type& __key) const
711e4b17023SJohn Marino      {
712e4b17023SJohn Marino	std::pair<_Base_const_iterator, _Base_const_iterator>
713e4b17023SJohn Marino	  __res = _Base::equal_range(__key);
714e4b17023SJohn Marino	return std::make_pair(const_iterator(__res.first, this),
715e4b17023SJohn Marino			      const_iterator(__res.second, this));
716e4b17023SJohn Marino      }
717e4b17023SJohn Marino
718e4b17023SJohn Marino      size_type
719e4b17023SJohn Marino      erase(const key_type& __key)
720e4b17023SJohn Marino      {
721e4b17023SJohn Marino	size_type __ret(0);
722e4b17023SJohn Marino	std::pair<_Base_iterator, _Base_iterator> __pair =
723e4b17023SJohn Marino	  _Base::equal_range(__key);
724e4b17023SJohn Marino	for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
725e4b17023SJohn Marino	  {
726e4b17023SJohn Marino	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
727e4b17023SJohn Marino			    { return __it == __victim; });
728e4b17023SJohn Marino	    _Base_local_iterator __local_victim = _S_to_local(__victim);
729e4b17023SJohn Marino	    this->_M_invalidate_local_if(
730e4b17023SJohn Marino			    [__local_victim](_Base_const_local_iterator __it)
731e4b17023SJohn Marino			    { return __it == __local_victim; });
732e4b17023SJohn Marino	    _Base::erase(__victim++);
733e4b17023SJohn Marino	    ++__ret;
734e4b17023SJohn Marino	  }
735e4b17023SJohn Marino	return __ret;
736e4b17023SJohn Marino      }
737e4b17023SJohn Marino
738e4b17023SJohn Marino      iterator
739e4b17023SJohn Marino      erase(const_iterator __it)
740e4b17023SJohn Marino      {
741e4b17023SJohn Marino	__glibcxx_check_erase(__it);
742e4b17023SJohn Marino	_Base_const_iterator __victim = __it.base();
743e4b17023SJohn Marino	this->_M_invalidate_if([__victim](_Base_const_iterator __it)
744e4b17023SJohn Marino			{ return __it == __victim; });
745e4b17023SJohn Marino	_Base_const_local_iterator __local_victim = _S_to_local(__victim);
746e4b17023SJohn Marino	this->_M_invalidate_local_if(
747e4b17023SJohn Marino			[__local_victim](_Base_const_local_iterator __it)
748e4b17023SJohn Marino			{ return __it == __local_victim; });
749e4b17023SJohn Marino	return iterator(_Base::erase(__it.base()), this);
750e4b17023SJohn Marino      }
751e4b17023SJohn Marino
752e4b17023SJohn Marino      iterator
753e4b17023SJohn Marino      erase(iterator __it)
754e4b17023SJohn Marino      { return erase(const_iterator(__it)); }
755e4b17023SJohn Marino
756e4b17023SJohn Marino      iterator
757e4b17023SJohn Marino      erase(const_iterator __first, const_iterator __last)
758e4b17023SJohn Marino      {
759e4b17023SJohn Marino	__glibcxx_check_erase_range(__first, __last);
760e4b17023SJohn Marino	for (_Base_const_iterator __tmp = __first.base();
761e4b17023SJohn Marino	     __tmp != __last.base(); ++__tmp)
762e4b17023SJohn Marino	  {
763e4b17023SJohn Marino	    _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
764e4b17023SJohn Marino				  _M_message(__gnu_debug::__msg_valid_range)
765e4b17023SJohn Marino				  ._M_iterator(__first, "first")
766e4b17023SJohn Marino				  ._M_iterator(__last, "last"));
767e4b17023SJohn Marino	    this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
768e4b17023SJohn Marino			    { return __it == __tmp; });
769e4b17023SJohn Marino	    _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
770e4b17023SJohn Marino	    this->_M_invalidate_local_if(
771e4b17023SJohn Marino			    [__local_tmp](_Base_const_local_iterator __it)
772e4b17023SJohn Marino			    { return __it == __local_tmp; });
773e4b17023SJohn Marino	  }
774e4b17023SJohn Marino	return iterator(_Base::erase(__first.base(),
775e4b17023SJohn Marino				     __last.base()), this);
776e4b17023SJohn Marino      }
777e4b17023SJohn Marino
778e4b17023SJohn Marino      _Base&
779e4b17023SJohn Marino      _M_base() noexcept       { return *this; }
780e4b17023SJohn Marino
781e4b17023SJohn Marino      const _Base&
782e4b17023SJohn Marino      _M_base() const noexcept { return *this; }
783e4b17023SJohn Marino
784e4b17023SJohn Marino    private:
785e4b17023SJohn Marino      void
786e4b17023SJohn Marino      _M_invalidate_locals()
787e4b17023SJohn Marino      {
788e4b17023SJohn Marino	_Base_local_iterator __local_end = _Base::end(0);
789e4b17023SJohn Marino	this->_M_invalidate_local_if(
790e4b17023SJohn Marino			[__local_end](_Base_const_local_iterator __it)
791e4b17023SJohn Marino			{ return __it != __local_end; });
792e4b17023SJohn Marino      }
793e4b17023SJohn Marino
794e4b17023SJohn Marino      void
795e4b17023SJohn Marino      _M_invalidate_all()
796e4b17023SJohn Marino      {
797e4b17023SJohn Marino	_Base_iterator __end = _Base::end();
798e4b17023SJohn Marino	this->_M_invalidate_if([__end](_Base_const_iterator __it)
799e4b17023SJohn Marino			{ return __it != __end; });
800e4b17023SJohn Marino	_M_invalidate_locals();
801e4b17023SJohn Marino      }
802e4b17023SJohn Marino
803e4b17023SJohn Marino      void
804e4b17023SJohn Marino      _M_check_rehashed(size_type __prev_count)
805e4b17023SJohn Marino      {
806e4b17023SJohn Marino	if (__prev_count != this->bucket_count())
807e4b17023SJohn Marino	  _M_invalidate_locals();
808e4b17023SJohn Marino      }
809e4b17023SJohn Marino
810e4b17023SJohn Marino      static _Base_local_iterator
811e4b17023SJohn Marino      _S_to_local(_Base_iterator __it)
812e4b17023SJohn Marino      {
813e4b17023SJohn Marino        // The returned local iterator will not be incremented so we don't
814e4b17023SJohn Marino	// need to compute __it's node bucket
815e4b17023SJohn Marino	return _Base_local_iterator(__it._M_cur, 0, 0);
816e4b17023SJohn Marino      }
817e4b17023SJohn Marino
818e4b17023SJohn Marino      static _Base_const_local_iterator
819e4b17023SJohn Marino      _S_to_local(_Base_const_iterator __it)
820e4b17023SJohn Marino      {
821e4b17023SJohn Marino        // The returned local iterator will not be incremented so we don't
822e4b17023SJohn Marino	// need to compute __it's node bucket
823e4b17023SJohn Marino	return _Base_const_local_iterator(__it._M_cur, 0, 0);
824e4b17023SJohn Marino      }
825e4b17023SJohn Marino    };
826e4b17023SJohn Marino
827e4b17023SJohn Marino  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
828e4b17023SJohn Marino    inline void
829e4b17023SJohn Marino    swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
830e4b17023SJohn Marino	 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
831e4b17023SJohn Marino    { __x.swap(__y); }
832e4b17023SJohn Marino
833e4b17023SJohn Marino  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
834e4b17023SJohn Marino    inline bool
835e4b17023SJohn Marino    operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
836e4b17023SJohn Marino	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
837e4b17023SJohn Marino    { return __x._M_equal(__y); }
838e4b17023SJohn Marino
839e4b17023SJohn Marino  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
840e4b17023SJohn Marino    inline bool
841e4b17023SJohn Marino    operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
842e4b17023SJohn Marino	       const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
843e4b17023SJohn Marino    { return !(__x == __y); }
844e4b17023SJohn Marino
845e4b17023SJohn Marino} // namespace __debug
846e4b17023SJohn Marino} // namespace std
847e4b17023SJohn Marino
848e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__
849e4b17023SJohn Marino
850e4b17023SJohn Marino#endif
851