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