1*e4b17023SJohn Marino// Profiling unordered_set/unordered_multiset implementation -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino// 5*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino// terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino// any later version. 10*e4b17023SJohn Marino// 11*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino// GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License along 21*e4b17023SJohn Marino// with this library; see the file COPYING3. If not see 22*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 23*e4b17023SJohn Marino 24*e4b17023SJohn Marino/** @file profile/unordered_set 25*e4b17023SJohn Marino * This file is a GNU profile extension to the Standard C++ Library. 26*e4b17023SJohn Marino */ 27*e4b17023SJohn Marino 28*e4b17023SJohn Marino#ifndef _GLIBCXX_PROFILE_UNORDERED_SET 29*e4b17023SJohn Marino#define _GLIBCXX_PROFILE_UNORDERED_SET 1 30*e4b17023SJohn Marino 31*e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 32*e4b17023SJohn Marino# include <bits/c++0x_warning.h> 33*e4b17023SJohn Marino#else 34*e4b17023SJohn Marino# include <unordered_set> 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino#include <profile/base.h> 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc> 39*e4b17023SJohn Marino#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 40*e4b17023SJohn Marino 41*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 42*e4b17023SJohn Marino{ 43*e4b17023SJohn Marinonamespace __profile 44*e4b17023SJohn Marino{ 45*e4b17023SJohn Marino /** @brief Unordered_set wrapper with performance instrumentation. */ 46*e4b17023SJohn Marino template<typename _Key, 47*e4b17023SJohn Marino typename _Hash = std::hash<_Key>, 48*e4b17023SJohn Marino typename _Pred = std::equal_to<_Key>, 49*e4b17023SJohn Marino typename _Alloc = std::allocator<_Key> > 50*e4b17023SJohn Marino class unordered_set 51*e4b17023SJohn Marino : public _GLIBCXX_STD_BASE 52*e4b17023SJohn Marino { 53*e4b17023SJohn Marino typedef typename _GLIBCXX_STD_BASE _Base; 54*e4b17023SJohn Marino 55*e4b17023SJohn Marino public: 56*e4b17023SJohn Marino typedef typename _Base::size_type size_type; 57*e4b17023SJohn Marino typedef typename _Base::hasher hasher; 58*e4b17023SJohn Marino typedef typename _Base::key_equal key_equal; 59*e4b17023SJohn Marino typedef typename _Base::allocator_type allocator_type; 60*e4b17023SJohn Marino typedef typename _Base::key_type key_type; 61*e4b17023SJohn Marino typedef typename _Base::value_type value_type; 62*e4b17023SJohn Marino typedef typename _Base::difference_type difference_type; 63*e4b17023SJohn Marino typedef typename _Base::reference reference; 64*e4b17023SJohn Marino typedef typename _Base::const_reference const_reference; 65*e4b17023SJohn Marino 66*e4b17023SJohn Marino typedef typename _Base::iterator iterator; 67*e4b17023SJohn Marino typedef typename _Base::const_iterator const_iterator; 68*e4b17023SJohn Marino 69*e4b17023SJohn Marino explicit 70*e4b17023SJohn Marino unordered_set(size_type __n = 10, 71*e4b17023SJohn Marino const hasher& __hf = hasher(), 72*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 73*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 74*e4b17023SJohn Marino : _Base(__n, __hf, __eql, __a) 75*e4b17023SJohn Marino { 76*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 77*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 78*e4b17023SJohn Marino } 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino template<typename _InputIterator> 81*e4b17023SJohn Marino unordered_set(_InputIterator __f, _InputIterator __l, 82*e4b17023SJohn Marino size_type __n = 0, 83*e4b17023SJohn Marino const hasher& __hf = hasher(), 84*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 85*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 86*e4b17023SJohn Marino : _Base(__f, __l, __n, __hf, __eql, __a) 87*e4b17023SJohn Marino { 88*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 89*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 90*e4b17023SJohn Marino } 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino unordered_set(const unordered_set& __x) 93*e4b17023SJohn Marino : _Base(__x) 94*e4b17023SJohn Marino { 95*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 96*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 97*e4b17023SJohn Marino } 98*e4b17023SJohn Marino 99*e4b17023SJohn Marino unordered_set(const _Base& __x) 100*e4b17023SJohn Marino : _Base(__x) 101*e4b17023SJohn Marino { 102*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 103*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 104*e4b17023SJohn Marino } 105*e4b17023SJohn Marino 106*e4b17023SJohn Marino unordered_set(unordered_set&& __x) 107*e4b17023SJohn Marino : _Base(std::move(__x)) 108*e4b17023SJohn Marino { 109*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 110*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 111*e4b17023SJohn Marino } 112*e4b17023SJohn Marino 113*e4b17023SJohn Marino unordered_set(initializer_list<value_type> __l, 114*e4b17023SJohn Marino size_type __n = 0, 115*e4b17023SJohn Marino const hasher& __hf = hasher(), 116*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 117*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 118*e4b17023SJohn Marino : _Base(__l, __n, __hf, __eql, __a) { } 119*e4b17023SJohn Marino 120*e4b17023SJohn Marino unordered_set& 121*e4b17023SJohn Marino operator=(const unordered_set& __x) 122*e4b17023SJohn Marino { 123*e4b17023SJohn Marino *static_cast<_Base*>(this) = __x; 124*e4b17023SJohn Marino return *this; 125*e4b17023SJohn Marino } 126*e4b17023SJohn Marino 127*e4b17023SJohn Marino unordered_set& 128*e4b17023SJohn Marino operator=(unordered_set&& __x) 129*e4b17023SJohn Marino { 130*e4b17023SJohn Marino // NB: DR 1204. 131*e4b17023SJohn Marino // NB: DR 675. 132*e4b17023SJohn Marino this->clear(); 133*e4b17023SJohn Marino this->swap(__x); 134*e4b17023SJohn Marino return *this; 135*e4b17023SJohn Marino } 136*e4b17023SJohn Marino 137*e4b17023SJohn Marino unordered_set& 138*e4b17023SJohn Marino operator=(initializer_list<value_type> __l) 139*e4b17023SJohn Marino { 140*e4b17023SJohn Marino this->clear(); 141*e4b17023SJohn Marino this->insert(__l); 142*e4b17023SJohn Marino return *this; 143*e4b17023SJohn Marino } 144*e4b17023SJohn Marino 145*e4b17023SJohn Marino ~unordered_set() noexcept 146*e4b17023SJohn Marino { 147*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 148*e4b17023SJohn Marino _Base::size()); 149*e4b17023SJohn Marino _M_profile_destruct(); 150*e4b17023SJohn Marino } 151*e4b17023SJohn Marino 152*e4b17023SJohn Marino void 153*e4b17023SJohn Marino swap(unordered_set& __x) 154*e4b17023SJohn Marino { 155*e4b17023SJohn Marino _Base::swap(__x); 156*e4b17023SJohn Marino } 157*e4b17023SJohn Marino 158*e4b17023SJohn Marino void 159*e4b17023SJohn Marino clear() noexcept 160*e4b17023SJohn Marino { 161*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 162*e4b17023SJohn Marino _Base::size()); 163*e4b17023SJohn Marino _M_profile_destruct(); 164*e4b17023SJohn Marino _Base::clear(); 165*e4b17023SJohn Marino } 166*e4b17023SJohn Marino 167*e4b17023SJohn Marino template<typename... _Args> 168*e4b17023SJohn Marino std::pair<iterator, bool> 169*e4b17023SJohn Marino emplace(_Args&&... __args) 170*e4b17023SJohn Marino { 171*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 172*e4b17023SJohn Marino std::pair<iterator, bool> __res 173*e4b17023SJohn Marino = _Base::emplace(std::forward<_Args>(__args)...); 174*e4b17023SJohn Marino _M_profile_resize(__old_size); 175*e4b17023SJohn Marino return __res; 176*e4b17023SJohn Marino } 177*e4b17023SJohn Marino 178*e4b17023SJohn Marino template<typename... _Args> 179*e4b17023SJohn Marino iterator 180*e4b17023SJohn Marino emplace_hint(const_iterator __it, _Args&&... __args) 181*e4b17023SJohn Marino { 182*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 183*e4b17023SJohn Marino iterator __res 184*e4b17023SJohn Marino = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 185*e4b17023SJohn Marino _M_profile_resize(__old_size); 186*e4b17023SJohn Marino return __res; 187*e4b17023SJohn Marino } 188*e4b17023SJohn Marino 189*e4b17023SJohn Marino void 190*e4b17023SJohn Marino insert(std::initializer_list<value_type> __l) 191*e4b17023SJohn Marino { 192*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 193*e4b17023SJohn Marino _Base::insert(__l); 194*e4b17023SJohn Marino _M_profile_resize(__old_size); 195*e4b17023SJohn Marino } 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino std::pair<iterator, bool> 198*e4b17023SJohn Marino insert(const value_type& __obj) 199*e4b17023SJohn Marino { 200*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 201*e4b17023SJohn Marino std::pair<iterator, bool> __res = _Base::insert(__obj); 202*e4b17023SJohn Marino _M_profile_resize(__old_size); 203*e4b17023SJohn Marino return __res; 204*e4b17023SJohn Marino } 205*e4b17023SJohn Marino 206*e4b17023SJohn Marino iterator 207*e4b17023SJohn Marino insert(const_iterator __iter, const value_type& __v) 208*e4b17023SJohn Marino { 209*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 210*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, __v); 211*e4b17023SJohn Marino _M_profile_resize(__old_size); 212*e4b17023SJohn Marino return __res; 213*e4b17023SJohn Marino } 214*e4b17023SJohn Marino 215*e4b17023SJohn Marino std::pair<iterator, bool> 216*e4b17023SJohn Marino insert(value_type&& __obj) 217*e4b17023SJohn Marino { 218*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 219*e4b17023SJohn Marino std::pair<iterator, bool> __res = _Base::insert(std::move(__obj)); 220*e4b17023SJohn Marino _M_profile_resize(__old_size); 221*e4b17023SJohn Marino return __res; 222*e4b17023SJohn Marino } 223*e4b17023SJohn Marino 224*e4b17023SJohn Marino iterator 225*e4b17023SJohn Marino insert(const_iterator __iter, value_type&& __v) 226*e4b17023SJohn Marino { 227*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 228*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, std::move(__v)); 229*e4b17023SJohn Marino _M_profile_resize(__old_size); 230*e4b17023SJohn Marino return __res; 231*e4b17023SJohn Marino } 232*e4b17023SJohn Marino 233*e4b17023SJohn Marino template<typename _InputIter> 234*e4b17023SJohn Marino void 235*e4b17023SJohn Marino insert(_InputIter __first, _InputIter __last) 236*e4b17023SJohn Marino { 237*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 238*e4b17023SJohn Marino _Base::insert(__first, __last); 239*e4b17023SJohn Marino _M_profile_resize(__old_size); 240*e4b17023SJohn Marino } 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino void 243*e4b17023SJohn Marino insert(const value_type* __first, const value_type* __last) 244*e4b17023SJohn Marino { 245*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 246*e4b17023SJohn Marino _Base::insert(__first, __last); 247*e4b17023SJohn Marino _M_profile_resize(__old_size); 248*e4b17023SJohn Marino } 249*e4b17023SJohn Marino 250*e4b17023SJohn Marino void rehash(size_type __n) 251*e4b17023SJohn Marino { 252*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 253*e4b17023SJohn Marino _Base::rehash(__n); 254*e4b17023SJohn Marino _M_profile_resize(__old_size); 255*e4b17023SJohn Marino } 256*e4b17023SJohn Marino 257*e4b17023SJohn Marino private: 258*e4b17023SJohn Marino void 259*e4b17023SJohn Marino _M_profile_resize(size_type __old_size) 260*e4b17023SJohn Marino { 261*e4b17023SJohn Marino size_type __new_size = _Base::bucket_count(); 262*e4b17023SJohn Marino if (__old_size != __new_size) 263*e4b17023SJohn Marino __profcxx_hashtable_resize(this, __old_size, __new_size); 264*e4b17023SJohn Marino } 265*e4b17023SJohn Marino 266*e4b17023SJohn Marino void 267*e4b17023SJohn Marino _M_profile_destruct() 268*e4b17023SJohn Marino { 269*e4b17023SJohn Marino size_type __hops = 0, __lc = 0, __chain = 0; 270*e4b17023SJohn Marino iterator __it = this->begin(); 271*e4b17023SJohn Marino while (__it != this->end()) 272*e4b17023SJohn Marino { 273*e4b17023SJohn Marino size_type __bkt = this->bucket(*__it); 274*e4b17023SJohn Marino auto __lit = this->begin(__bkt); 275*e4b17023SJohn Marino auto __lend = this->end(__bkt); 276*e4b17023SJohn Marino for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) 277*e4b17023SJohn Marino ++__chain; 278*e4b17023SJohn Marino if (__chain) 279*e4b17023SJohn Marino { 280*e4b17023SJohn Marino ++__chain; 281*e4b17023SJohn Marino __lc = __lc > __chain ? __lc : __chain; 282*e4b17023SJohn Marino __hops += __chain * (__chain - 1) / 2; 283*e4b17023SJohn Marino __chain = 0; 284*e4b17023SJohn Marino } 285*e4b17023SJohn Marino } 286*e4b17023SJohn Marino __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops); 287*e4b17023SJohn Marino } 288*e4b17023SJohn Marino }; 289*e4b17023SJohn Marino 290*e4b17023SJohn Marino template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 291*e4b17023SJohn Marino inline void 292*e4b17023SJohn Marino swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, 293*e4b17023SJohn Marino unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) 294*e4b17023SJohn Marino { __x.swap(__y); } 295*e4b17023SJohn Marino 296*e4b17023SJohn Marino template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 297*e4b17023SJohn Marino inline bool 298*e4b17023SJohn Marino operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, 299*e4b17023SJohn Marino const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) 300*e4b17023SJohn Marino { return __x._M_equal(__y); } 301*e4b17023SJohn Marino 302*e4b17023SJohn Marino template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 303*e4b17023SJohn Marino inline bool 304*e4b17023SJohn Marino operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, 305*e4b17023SJohn Marino const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) 306*e4b17023SJohn Marino { return !(__x == __y); } 307*e4b17023SJohn Marino 308*e4b17023SJohn Marino#undef _GLIBCXX_BASE 309*e4b17023SJohn Marino#undef _GLIBCXX_STD_BASE 310*e4b17023SJohn Marino#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 311*e4b17023SJohn Marino#define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc> 312*e4b17023SJohn Marino 313*e4b17023SJohn Marino /** @brief Unordered_multiset wrapper with performance instrumentation. */ 314*e4b17023SJohn Marino template<typename _Value, 315*e4b17023SJohn Marino typename _Hash = std::hash<_Value>, 316*e4b17023SJohn Marino typename _Pred = std::equal_to<_Value>, 317*e4b17023SJohn Marino typename _Alloc = std::allocator<_Value> > 318*e4b17023SJohn Marino class unordered_multiset 319*e4b17023SJohn Marino : public _GLIBCXX_STD_BASE 320*e4b17023SJohn Marino { 321*e4b17023SJohn Marino typedef typename _GLIBCXX_STD_BASE _Base; 322*e4b17023SJohn Marino 323*e4b17023SJohn Marino public: 324*e4b17023SJohn Marino typedef typename _Base::size_type size_type; 325*e4b17023SJohn Marino typedef typename _Base::hasher hasher; 326*e4b17023SJohn Marino typedef typename _Base::key_equal key_equal; 327*e4b17023SJohn Marino typedef typename _Base::allocator_type allocator_type; 328*e4b17023SJohn Marino typedef typename _Base::key_type key_type; 329*e4b17023SJohn Marino typedef typename _Base::value_type value_type; 330*e4b17023SJohn Marino typedef typename _Base::difference_type difference_type; 331*e4b17023SJohn Marino typedef typename _Base::reference reference; 332*e4b17023SJohn Marino typedef typename _Base::const_reference const_reference; 333*e4b17023SJohn Marino 334*e4b17023SJohn Marino typedef typename _Base::iterator iterator; 335*e4b17023SJohn Marino typedef typename _Base::const_iterator const_iterator; 336*e4b17023SJohn Marino 337*e4b17023SJohn Marino explicit 338*e4b17023SJohn Marino unordered_multiset(size_type __n = 10, 339*e4b17023SJohn Marino const hasher& __hf = hasher(), 340*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 341*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 342*e4b17023SJohn Marino : _Base(__n, __hf, __eql, __a) 343*e4b17023SJohn Marino { 344*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 345*e4b17023SJohn Marino } 346*e4b17023SJohn Marino 347*e4b17023SJohn Marino template<typename _InputIterator> 348*e4b17023SJohn Marino unordered_multiset(_InputIterator __f, _InputIterator __l, 349*e4b17023SJohn Marino size_type __n = 0, 350*e4b17023SJohn Marino const hasher& __hf = hasher(), 351*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 352*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 353*e4b17023SJohn Marino : _Base(__f, __l, __n, __hf, __eql, __a) 354*e4b17023SJohn Marino { 355*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 356*e4b17023SJohn Marino } 357*e4b17023SJohn Marino 358*e4b17023SJohn Marino unordered_multiset(const unordered_multiset& __x) 359*e4b17023SJohn Marino : _Base(__x) 360*e4b17023SJohn Marino { 361*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 362*e4b17023SJohn Marino } 363*e4b17023SJohn Marino 364*e4b17023SJohn Marino unordered_multiset(const _Base& __x) 365*e4b17023SJohn Marino : _Base(__x) 366*e4b17023SJohn Marino { 367*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 368*e4b17023SJohn Marino } 369*e4b17023SJohn Marino 370*e4b17023SJohn Marino unordered_multiset(unordered_multiset&& __x) 371*e4b17023SJohn Marino : _Base(std::move(__x)) 372*e4b17023SJohn Marino { 373*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 374*e4b17023SJohn Marino } 375*e4b17023SJohn Marino 376*e4b17023SJohn Marino unordered_multiset(initializer_list<value_type> __l, 377*e4b17023SJohn Marino size_type __n = 0, 378*e4b17023SJohn Marino const hasher& __hf = hasher(), 379*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 380*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 381*e4b17023SJohn Marino : _Base(__l, __n, __hf, __eql, __a) { } 382*e4b17023SJohn Marino 383*e4b17023SJohn Marino unordered_multiset& 384*e4b17023SJohn Marino operator=(const unordered_multiset& __x) 385*e4b17023SJohn Marino { 386*e4b17023SJohn Marino *static_cast<_Base*>(this) = __x; 387*e4b17023SJohn Marino return *this; 388*e4b17023SJohn Marino } 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino unordered_multiset& 391*e4b17023SJohn Marino operator=(unordered_multiset&& __x) 392*e4b17023SJohn Marino { 393*e4b17023SJohn Marino // NB: DR 1204. 394*e4b17023SJohn Marino // NB: DR 675. 395*e4b17023SJohn Marino this->clear(); 396*e4b17023SJohn Marino this->swap(__x); 397*e4b17023SJohn Marino return *this; 398*e4b17023SJohn Marino } 399*e4b17023SJohn Marino 400*e4b17023SJohn Marino unordered_multiset& 401*e4b17023SJohn Marino operator=(initializer_list<value_type> __l) 402*e4b17023SJohn Marino { 403*e4b17023SJohn Marino this->clear(); 404*e4b17023SJohn Marino this->insert(__l); 405*e4b17023SJohn Marino return *this; 406*e4b17023SJohn Marino } 407*e4b17023SJohn Marino 408*e4b17023SJohn Marino ~unordered_multiset() noexcept 409*e4b17023SJohn Marino { 410*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 411*e4b17023SJohn Marino _Base::size()); 412*e4b17023SJohn Marino _M_profile_destruct(); 413*e4b17023SJohn Marino } 414*e4b17023SJohn Marino 415*e4b17023SJohn Marino void 416*e4b17023SJohn Marino swap(unordered_multiset& __x) 417*e4b17023SJohn Marino { 418*e4b17023SJohn Marino _Base::swap(__x); 419*e4b17023SJohn Marino } 420*e4b17023SJohn Marino 421*e4b17023SJohn Marino void 422*e4b17023SJohn Marino clear() noexcept 423*e4b17023SJohn Marino { 424*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 425*e4b17023SJohn Marino _Base::size()); 426*e4b17023SJohn Marino _M_profile_destruct(); 427*e4b17023SJohn Marino _Base::clear(); 428*e4b17023SJohn Marino } 429*e4b17023SJohn Marino 430*e4b17023SJohn Marino template<typename... _Args> 431*e4b17023SJohn Marino iterator 432*e4b17023SJohn Marino emplace(_Args&&... __args) 433*e4b17023SJohn Marino { 434*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 435*e4b17023SJohn Marino iterator __res = _Base::emplace(std::forward<_Args>(__args)...); 436*e4b17023SJohn Marino _M_profile_resize(__old_size); 437*e4b17023SJohn Marino return __res; 438*e4b17023SJohn Marino } 439*e4b17023SJohn Marino 440*e4b17023SJohn Marino template<typename... _Args> 441*e4b17023SJohn Marino iterator 442*e4b17023SJohn Marino emplace_hint(const_iterator __it, _Args&&... __args) 443*e4b17023SJohn Marino { 444*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 445*e4b17023SJohn Marino iterator __res 446*e4b17023SJohn Marino = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 447*e4b17023SJohn Marino _M_profile_resize(__old_size); 448*e4b17023SJohn Marino return __res; 449*e4b17023SJohn Marino } 450*e4b17023SJohn Marino 451*e4b17023SJohn Marino void 452*e4b17023SJohn Marino insert(std::initializer_list<value_type> __l) 453*e4b17023SJohn Marino { 454*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 455*e4b17023SJohn Marino _Base::insert(__l); 456*e4b17023SJohn Marino _M_profile_resize(__old_size); 457*e4b17023SJohn Marino } 458*e4b17023SJohn Marino 459*e4b17023SJohn Marino iterator 460*e4b17023SJohn Marino insert(const value_type& __obj) 461*e4b17023SJohn Marino { 462*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 463*e4b17023SJohn Marino iterator __res = _Base::insert(__obj); 464*e4b17023SJohn Marino _M_profile_resize(__old_size); 465*e4b17023SJohn Marino return __res; 466*e4b17023SJohn Marino } 467*e4b17023SJohn Marino 468*e4b17023SJohn Marino iterator 469*e4b17023SJohn Marino insert(const_iterator __iter, const value_type& __v) 470*e4b17023SJohn Marino { 471*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 472*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, __v); 473*e4b17023SJohn Marino _M_profile_resize(__old_size); 474*e4b17023SJohn Marino return __res; 475*e4b17023SJohn Marino } 476*e4b17023SJohn Marino 477*e4b17023SJohn Marino iterator 478*e4b17023SJohn Marino insert(value_type&& __obj) 479*e4b17023SJohn Marino { 480*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 481*e4b17023SJohn Marino iterator __res = _Base::insert(std::move(__obj)); 482*e4b17023SJohn Marino _M_profile_resize(__old_size); 483*e4b17023SJohn Marino return __res; 484*e4b17023SJohn Marino } 485*e4b17023SJohn Marino 486*e4b17023SJohn Marino iterator 487*e4b17023SJohn Marino insert(const_iterator __iter, value_type&& __v) 488*e4b17023SJohn Marino { 489*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 490*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, std::move(__v)); 491*e4b17023SJohn Marino _M_profile_resize(__old_size); 492*e4b17023SJohn Marino return __res; 493*e4b17023SJohn Marino } 494*e4b17023SJohn Marino 495*e4b17023SJohn Marino template<typename _InputIter> 496*e4b17023SJohn Marino void 497*e4b17023SJohn Marino insert(_InputIter __first, _InputIter __last) 498*e4b17023SJohn Marino { 499*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 500*e4b17023SJohn Marino _Base::insert(__first, __last); 501*e4b17023SJohn Marino _M_profile_resize(__old_size); 502*e4b17023SJohn Marino } 503*e4b17023SJohn Marino 504*e4b17023SJohn Marino void 505*e4b17023SJohn Marino insert(const value_type* __first, const value_type* __last) 506*e4b17023SJohn Marino { 507*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 508*e4b17023SJohn Marino _Base::insert(__first, __last); 509*e4b17023SJohn Marino _M_profile_resize(__old_size); 510*e4b17023SJohn Marino } 511*e4b17023SJohn Marino 512*e4b17023SJohn Marino void rehash(size_type __n) 513*e4b17023SJohn Marino { 514*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 515*e4b17023SJohn Marino _Base::rehash(__n); 516*e4b17023SJohn Marino _M_profile_resize(__old_size); 517*e4b17023SJohn Marino } 518*e4b17023SJohn Marino 519*e4b17023SJohn Marino private: 520*e4b17023SJohn Marino void 521*e4b17023SJohn Marino _M_profile_resize(size_type __old_size) 522*e4b17023SJohn Marino { 523*e4b17023SJohn Marino size_type __new_size = _Base::bucket_count(); 524*e4b17023SJohn Marino if (__old_size != __new_size) 525*e4b17023SJohn Marino __profcxx_hashtable_resize(this, __old_size, __new_size); 526*e4b17023SJohn Marino } 527*e4b17023SJohn Marino 528*e4b17023SJohn Marino void 529*e4b17023SJohn Marino _M_profile_destruct() 530*e4b17023SJohn Marino { 531*e4b17023SJohn Marino size_type __hops = 0, __lc = 0, __chain = 0; 532*e4b17023SJohn Marino iterator __it = this->begin(); 533*e4b17023SJohn Marino while (__it != this->end()) 534*e4b17023SJohn Marino { 535*e4b17023SJohn Marino size_type __bkt = this->bucket(*__it); 536*e4b17023SJohn Marino auto __lit = this->begin(__bkt); 537*e4b17023SJohn Marino auto __lend = this->end(__bkt); 538*e4b17023SJohn Marino for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) 539*e4b17023SJohn Marino ++__chain; 540*e4b17023SJohn Marino if (__chain) 541*e4b17023SJohn Marino { 542*e4b17023SJohn Marino ++__chain; 543*e4b17023SJohn Marino __lc = __lc > __chain ? __lc : __chain; 544*e4b17023SJohn Marino __hops += __chain * (__chain - 1) / 2; 545*e4b17023SJohn Marino __chain = 0; 546*e4b17023SJohn Marino } 547*e4b17023SJohn Marino } 548*e4b17023SJohn Marino __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops); 549*e4b17023SJohn Marino } 550*e4b17023SJohn Marino }; 551*e4b17023SJohn Marino 552*e4b17023SJohn Marino template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 553*e4b17023SJohn Marino inline void 554*e4b17023SJohn Marino swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 555*e4b17023SJohn Marino unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 556*e4b17023SJohn Marino { __x.swap(__y); } 557*e4b17023SJohn Marino 558*e4b17023SJohn Marino template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 559*e4b17023SJohn Marino inline bool 560*e4b17023SJohn Marino operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 561*e4b17023SJohn Marino const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 562*e4b17023SJohn Marino { return __x._M_equal(__y); } 563*e4b17023SJohn Marino 564*e4b17023SJohn Marino template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> 565*e4b17023SJohn Marino inline bool 566*e4b17023SJohn Marino operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, 567*e4b17023SJohn Marino const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) 568*e4b17023SJohn Marino { return !(__x == __y); } 569*e4b17023SJohn Marino 570*e4b17023SJohn Marino} // namespace __profile 571*e4b17023SJohn Marino} // namespace std 572*e4b17023SJohn Marino 573*e4b17023SJohn Marino#undef _GLIBCXX_BASE 574*e4b17023SJohn Marino#undef _GLIBCXX_STD_BASE 575*e4b17023SJohn Marino 576*e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 577*e4b17023SJohn Marino 578*e4b17023SJohn Marino#endif 579