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