1*e4b17023SJohn Marino// Profiling unordered_map/unordered_multimap implementation -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2009, 2010, 2011, 2012 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_map 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_MAP 29*e4b17023SJohn Marino#define _GLIBCXX_PROFILE_UNORDERED_MAP 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_map> 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino#include <profile/base.h> 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#define _GLIBCXX_BASE unordered_map<_Key, _Tp, _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 /// Class std::unordered_map wrapper with performance instrumentation. 46*e4b17023SJohn Marino template<typename _Key, typename _Tp, 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_map 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 typedef typename _Base::mapped_type mapped_type; 66*e4b17023SJohn Marino 67*e4b17023SJohn Marino typedef typename _Base::iterator iterator; 68*e4b17023SJohn Marino typedef typename _Base::const_iterator const_iterator; 69*e4b17023SJohn Marino 70*e4b17023SJohn Marino explicit 71*e4b17023SJohn Marino unordered_map(size_type __n = 10, 72*e4b17023SJohn Marino const hasher& __hf = hasher(), 73*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 74*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 75*e4b17023SJohn Marino : _Base(__n, __hf, __eql, __a) 76*e4b17023SJohn Marino { 77*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 78*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 79*e4b17023SJohn Marino } 80*e4b17023SJohn Marino 81*e4b17023SJohn Marino template<typename _InputIterator> 82*e4b17023SJohn Marino unordered_map(_InputIterator __f, _InputIterator __l, 83*e4b17023SJohn Marino size_type __n = 0, 84*e4b17023SJohn Marino const hasher& __hf = hasher(), 85*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 86*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 87*e4b17023SJohn Marino : _Base(__f, __l, __n, __hf, __eql, __a) 88*e4b17023SJohn Marino { 89*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 90*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 91*e4b17023SJohn Marino } 92*e4b17023SJohn Marino 93*e4b17023SJohn Marino unordered_map(const unordered_map& __x) 94*e4b17023SJohn Marino : _Base(__x) 95*e4b17023SJohn Marino { 96*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 97*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 98*e4b17023SJohn Marino } 99*e4b17023SJohn Marino 100*e4b17023SJohn Marino unordered_map(const _Base& __x) 101*e4b17023SJohn Marino : _Base(__x) 102*e4b17023SJohn Marino { 103*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 104*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 105*e4b17023SJohn Marino } 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino unordered_map(unordered_map&& __x) 108*e4b17023SJohn Marino : _Base(std::move(__x)) 109*e4b17023SJohn Marino { 110*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 111*e4b17023SJohn Marino __profcxx_hashtable_construct2(this); 112*e4b17023SJohn Marino } 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino unordered_map(initializer_list<value_type> __l, 115*e4b17023SJohn Marino size_type __n = 0, 116*e4b17023SJohn Marino const hasher& __hf = hasher(), 117*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 118*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 119*e4b17023SJohn Marino : _Base(__l, __n, __hf, __eql, __a) { } 120*e4b17023SJohn Marino 121*e4b17023SJohn Marino unordered_map& 122*e4b17023SJohn Marino operator=(const unordered_map& __x) 123*e4b17023SJohn Marino { 124*e4b17023SJohn Marino *static_cast<_Base*>(this) = __x; 125*e4b17023SJohn Marino return *this; 126*e4b17023SJohn Marino } 127*e4b17023SJohn Marino 128*e4b17023SJohn Marino unordered_map& 129*e4b17023SJohn Marino operator=(unordered_map&& __x) 130*e4b17023SJohn Marino { 131*e4b17023SJohn Marino // NB: DR 1204. 132*e4b17023SJohn Marino // NB: DR 675. 133*e4b17023SJohn Marino this->clear(); 134*e4b17023SJohn Marino this->swap(__x); 135*e4b17023SJohn Marino return *this; 136*e4b17023SJohn Marino } 137*e4b17023SJohn Marino 138*e4b17023SJohn Marino unordered_map& 139*e4b17023SJohn Marino operator=(initializer_list<value_type> __l) 140*e4b17023SJohn Marino { 141*e4b17023SJohn Marino this->clear(); 142*e4b17023SJohn Marino this->insert(__l); 143*e4b17023SJohn Marino return *this; 144*e4b17023SJohn Marino } 145*e4b17023SJohn Marino 146*e4b17023SJohn Marino ~unordered_map() noexcept 147*e4b17023SJohn Marino { 148*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 149*e4b17023SJohn Marino _Base::size()); 150*e4b17023SJohn Marino _M_profile_destruct(); 151*e4b17023SJohn Marino } 152*e4b17023SJohn Marino 153*e4b17023SJohn Marino _Base& 154*e4b17023SJohn Marino _M_base() noexcept { return *this; } 155*e4b17023SJohn Marino 156*e4b17023SJohn Marino const _Base& 157*e4b17023SJohn Marino _M_base() const noexcept { return *this; } 158*e4b17023SJohn Marino 159*e4b17023SJohn Marino void 160*e4b17023SJohn Marino clear() noexcept 161*e4b17023SJohn Marino { 162*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 163*e4b17023SJohn Marino _Base::size()); 164*e4b17023SJohn Marino _M_profile_destruct(); 165*e4b17023SJohn Marino _Base::clear(); 166*e4b17023SJohn Marino } 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino template<typename... _Args> 169*e4b17023SJohn Marino std::pair<iterator, bool> 170*e4b17023SJohn Marino emplace(_Args&&... __args) 171*e4b17023SJohn Marino { 172*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 173*e4b17023SJohn Marino std::pair<iterator, bool> __res 174*e4b17023SJohn Marino = _Base::emplace(std::forward<_Args>(__args)...); 175*e4b17023SJohn Marino _M_profile_resize(__old_size); 176*e4b17023SJohn Marino return __res; 177*e4b17023SJohn Marino } 178*e4b17023SJohn Marino 179*e4b17023SJohn Marino template<typename... _Args> 180*e4b17023SJohn Marino iterator 181*e4b17023SJohn Marino emplace_hint(const_iterator __it, _Args&&... __args) 182*e4b17023SJohn Marino { 183*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 184*e4b17023SJohn Marino iterator __res 185*e4b17023SJohn Marino = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 186*e4b17023SJohn Marino _M_profile_resize(__old_size); 187*e4b17023SJohn Marino return __res; 188*e4b17023SJohn Marino } 189*e4b17023SJohn Marino 190*e4b17023SJohn Marino void 191*e4b17023SJohn Marino insert(std::initializer_list<value_type> __l) 192*e4b17023SJohn Marino { 193*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 194*e4b17023SJohn Marino _Base::insert(__l); 195*e4b17023SJohn Marino _M_profile_resize(__old_size); 196*e4b17023SJohn Marino } 197*e4b17023SJohn Marino 198*e4b17023SJohn Marino std::pair<iterator, bool> 199*e4b17023SJohn Marino insert(const value_type& __obj) 200*e4b17023SJohn Marino { 201*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 202*e4b17023SJohn Marino std::pair<iterator, bool> __res = _Base::insert(__obj); 203*e4b17023SJohn Marino _M_profile_resize(__old_size); 204*e4b17023SJohn Marino return __res; 205*e4b17023SJohn Marino } 206*e4b17023SJohn Marino 207*e4b17023SJohn Marino iterator 208*e4b17023SJohn Marino insert(const_iterator __iter, const value_type& __v) 209*e4b17023SJohn Marino { 210*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 211*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, __v); 212*e4b17023SJohn Marino _M_profile_resize(__old_size); 213*e4b17023SJohn Marino return __res; 214*e4b17023SJohn Marino } 215*e4b17023SJohn Marino 216*e4b17023SJohn Marino template<typename _Pair, typename = typename 217*e4b17023SJohn Marino std::enable_if<std::is_constructible<value_type, 218*e4b17023SJohn Marino _Pair&&>::value>::type> 219*e4b17023SJohn Marino std::pair<iterator, bool> 220*e4b17023SJohn Marino insert(_Pair&& __obj) 221*e4b17023SJohn Marino { 222*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 223*e4b17023SJohn Marino std::pair<iterator, bool> __res 224*e4b17023SJohn Marino = _Base::insert(std::forward<_Pair>(__obj)); 225*e4b17023SJohn Marino _M_profile_resize(__old_size); 226*e4b17023SJohn Marino return __res; 227*e4b17023SJohn Marino } 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino template<typename _Pair, typename = typename 230*e4b17023SJohn Marino std::enable_if<std::is_constructible<value_type, 231*e4b17023SJohn Marino _Pair&&>::value>::type> 232*e4b17023SJohn Marino iterator 233*e4b17023SJohn Marino insert(const_iterator __iter, _Pair&& __v) 234*e4b17023SJohn Marino { 235*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 236*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); 237*e4b17023SJohn Marino _M_profile_resize(__old_size); 238*e4b17023SJohn Marino return __res; 239*e4b17023SJohn Marino } 240*e4b17023SJohn Marino 241*e4b17023SJohn Marino template<typename _InputIter> 242*e4b17023SJohn Marino void 243*e4b17023SJohn Marino insert(_InputIter __first, _InputIter __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 251*e4b17023SJohn Marino insert(const value_type* __first, const value_type* __last) 252*e4b17023SJohn Marino { 253*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 254*e4b17023SJohn Marino _Base::insert(__first, __last); 255*e4b17023SJohn Marino _M_profile_resize(__old_size); 256*e4b17023SJohn Marino } 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino // operator[] 259*e4b17023SJohn Marino mapped_type& 260*e4b17023SJohn Marino operator[](const _Key& __k) 261*e4b17023SJohn Marino { 262*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 263*e4b17023SJohn Marino mapped_type& __res = _M_base()[__k]; 264*e4b17023SJohn Marino _M_profile_resize(__old_size); 265*e4b17023SJohn Marino return __res; 266*e4b17023SJohn Marino } 267*e4b17023SJohn Marino 268*e4b17023SJohn Marino mapped_type& 269*e4b17023SJohn Marino operator[](_Key&& __k) 270*e4b17023SJohn Marino { 271*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 272*e4b17023SJohn Marino mapped_type& __res = _M_base()[std::move(__k)]; 273*e4b17023SJohn Marino _M_profile_resize(__old_size); 274*e4b17023SJohn Marino return __res; 275*e4b17023SJohn Marino } 276*e4b17023SJohn Marino 277*e4b17023SJohn Marino void 278*e4b17023SJohn Marino swap(unordered_map& __x) 279*e4b17023SJohn Marino { _Base::swap(__x); } 280*e4b17023SJohn Marino 281*e4b17023SJohn Marino void rehash(size_type __n) 282*e4b17023SJohn Marino { 283*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 284*e4b17023SJohn Marino _Base::rehash(__n); 285*e4b17023SJohn Marino _M_profile_resize(__old_size); 286*e4b17023SJohn Marino } 287*e4b17023SJohn Marino 288*e4b17023SJohn Marino private: 289*e4b17023SJohn Marino void 290*e4b17023SJohn Marino _M_profile_resize(size_type __old_size) 291*e4b17023SJohn Marino { 292*e4b17023SJohn Marino size_type __new_size = _Base::bucket_count(); 293*e4b17023SJohn Marino if (__old_size != __new_size) 294*e4b17023SJohn Marino __profcxx_hashtable_resize(this, __old_size, __new_size); 295*e4b17023SJohn Marino } 296*e4b17023SJohn Marino 297*e4b17023SJohn Marino void 298*e4b17023SJohn Marino _M_profile_destruct() 299*e4b17023SJohn Marino { 300*e4b17023SJohn Marino size_type __hops = 0, __lc = 0, __chain = 0; 301*e4b17023SJohn Marino iterator __it = this->begin(); 302*e4b17023SJohn Marino while (__it != this->end()) 303*e4b17023SJohn Marino { 304*e4b17023SJohn Marino size_type __bkt = this->bucket(__it->first); 305*e4b17023SJohn Marino auto __lit = this->begin(__bkt); 306*e4b17023SJohn Marino auto __lend = this->end(__bkt); 307*e4b17023SJohn Marino for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) 308*e4b17023SJohn Marino ++__chain; 309*e4b17023SJohn Marino if (__chain) 310*e4b17023SJohn Marino { 311*e4b17023SJohn Marino ++__chain; 312*e4b17023SJohn Marino __lc = __lc > __chain ? __lc : __chain; 313*e4b17023SJohn Marino __hops += __chain * (__chain - 1) / 2; 314*e4b17023SJohn Marino __chain = 0; 315*e4b17023SJohn Marino } 316*e4b17023SJohn Marino } 317*e4b17023SJohn Marino __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops); 318*e4b17023SJohn Marino } 319*e4b17023SJohn Marino }; 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino template<typename _Key, typename _Tp, typename _Hash, 322*e4b17023SJohn Marino typename _Pred, typename _Alloc> 323*e4b17023SJohn Marino inline void 324*e4b17023SJohn Marino swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 325*e4b17023SJohn Marino unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 326*e4b17023SJohn Marino { __x.swap(__y); } 327*e4b17023SJohn Marino 328*e4b17023SJohn Marino template<typename _Key, typename _Tp, typename _Hash, 329*e4b17023SJohn Marino typename _Pred, typename _Alloc> 330*e4b17023SJohn Marino inline bool 331*e4b17023SJohn Marino operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 332*e4b17023SJohn Marino const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 333*e4b17023SJohn Marino { return __x._M_equal(__y); } 334*e4b17023SJohn Marino 335*e4b17023SJohn Marino template<typename _Key, typename _Tp, typename _Hash, 336*e4b17023SJohn Marino typename _Pred, typename _Alloc> 337*e4b17023SJohn Marino inline bool 338*e4b17023SJohn Marino operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 339*e4b17023SJohn Marino const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 340*e4b17023SJohn Marino { return !(__x == __y); } 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino#undef _GLIBCXX_BASE 343*e4b17023SJohn Marino#undef _GLIBCXX_STD_BASE 344*e4b17023SJohn Marino#define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> 345*e4b17023SJohn Marino#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE 346*e4b17023SJohn Marino 347*e4b17023SJohn Marino /// Class std::unordered_multimap wrapper with performance instrumentation. 348*e4b17023SJohn Marino template<typename _Key, typename _Tp, 349*e4b17023SJohn Marino typename _Hash = std::hash<_Key>, 350*e4b17023SJohn Marino typename _Pred = std::equal_to<_Key>, 351*e4b17023SJohn Marino typename _Alloc = std::allocator<_Key> > 352*e4b17023SJohn Marino class unordered_multimap 353*e4b17023SJohn Marino : public _GLIBCXX_STD_BASE 354*e4b17023SJohn Marino { 355*e4b17023SJohn Marino typedef typename _GLIBCXX_STD_BASE _Base; 356*e4b17023SJohn Marino 357*e4b17023SJohn Marino public: 358*e4b17023SJohn Marino typedef typename _Base::size_type size_type; 359*e4b17023SJohn Marino typedef typename _Base::hasher hasher; 360*e4b17023SJohn Marino typedef typename _Base::key_equal key_equal; 361*e4b17023SJohn Marino typedef typename _Base::allocator_type allocator_type; 362*e4b17023SJohn Marino typedef typename _Base::key_type key_type; 363*e4b17023SJohn Marino typedef typename _Base::value_type value_type; 364*e4b17023SJohn Marino typedef typename _Base::difference_type difference_type; 365*e4b17023SJohn Marino typedef typename _Base::reference reference; 366*e4b17023SJohn Marino typedef typename _Base::const_reference const_reference; 367*e4b17023SJohn Marino 368*e4b17023SJohn Marino typedef typename _Base::iterator iterator; 369*e4b17023SJohn Marino typedef typename _Base::const_iterator const_iterator; 370*e4b17023SJohn Marino 371*e4b17023SJohn Marino explicit 372*e4b17023SJohn Marino unordered_multimap(size_type __n = 10, 373*e4b17023SJohn Marino const hasher& __hf = hasher(), 374*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 375*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 376*e4b17023SJohn Marino : _Base(__n, __hf, __eql, __a) 377*e4b17023SJohn Marino { 378*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 379*e4b17023SJohn Marino } 380*e4b17023SJohn Marino template<typename _InputIterator> 381*e4b17023SJohn Marino unordered_multimap(_InputIterator __f, _InputIterator __l, 382*e4b17023SJohn Marino size_type __n = 0, 383*e4b17023SJohn Marino const hasher& __hf = hasher(), 384*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 385*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 386*e4b17023SJohn Marino : _Base(__f, __l, __n, __hf, __eql, __a) 387*e4b17023SJohn Marino { 388*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 389*e4b17023SJohn Marino } 390*e4b17023SJohn Marino 391*e4b17023SJohn Marino unordered_multimap(const unordered_multimap& __x) 392*e4b17023SJohn Marino : _Base(__x) 393*e4b17023SJohn Marino { 394*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 395*e4b17023SJohn Marino } 396*e4b17023SJohn Marino 397*e4b17023SJohn Marino unordered_multimap(const _Base& __x) 398*e4b17023SJohn Marino : _Base(__x) 399*e4b17023SJohn Marino { 400*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 401*e4b17023SJohn Marino } 402*e4b17023SJohn Marino 403*e4b17023SJohn Marino unordered_multimap(unordered_multimap&& __x) 404*e4b17023SJohn Marino : _Base(std::move(__x)) 405*e4b17023SJohn Marino { 406*e4b17023SJohn Marino __profcxx_hashtable_construct(this, _Base::bucket_count()); 407*e4b17023SJohn Marino } 408*e4b17023SJohn Marino 409*e4b17023SJohn Marino unordered_multimap(initializer_list<value_type> __l, 410*e4b17023SJohn Marino size_type __n = 0, 411*e4b17023SJohn Marino const hasher& __hf = hasher(), 412*e4b17023SJohn Marino const key_equal& __eql = key_equal(), 413*e4b17023SJohn Marino const allocator_type& __a = allocator_type()) 414*e4b17023SJohn Marino : _Base(__l, __n, __hf, __eql, __a) { } 415*e4b17023SJohn Marino 416*e4b17023SJohn Marino unordered_multimap& 417*e4b17023SJohn Marino operator=(const unordered_multimap& __x) 418*e4b17023SJohn Marino { 419*e4b17023SJohn Marino *static_cast<_Base*>(this) = __x; 420*e4b17023SJohn Marino return *this; 421*e4b17023SJohn Marino } 422*e4b17023SJohn Marino 423*e4b17023SJohn Marino unordered_multimap& 424*e4b17023SJohn Marino operator=(unordered_multimap&& __x) 425*e4b17023SJohn Marino { 426*e4b17023SJohn Marino // NB: DR 1204. 427*e4b17023SJohn Marino // NB: DR 675. 428*e4b17023SJohn Marino this->clear(); 429*e4b17023SJohn Marino this->swap(__x); 430*e4b17023SJohn Marino return *this; 431*e4b17023SJohn Marino } 432*e4b17023SJohn Marino 433*e4b17023SJohn Marino unordered_multimap& 434*e4b17023SJohn Marino operator=(initializer_list<value_type> __l) 435*e4b17023SJohn Marino { 436*e4b17023SJohn Marino this->clear(); 437*e4b17023SJohn Marino this->insert(__l); 438*e4b17023SJohn Marino return *this; 439*e4b17023SJohn Marino } 440*e4b17023SJohn Marino 441*e4b17023SJohn Marino ~unordered_multimap() noexcept 442*e4b17023SJohn Marino { 443*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 444*e4b17023SJohn Marino _Base::size()); 445*e4b17023SJohn Marino _M_profile_destruct(); 446*e4b17023SJohn Marino } 447*e4b17023SJohn Marino 448*e4b17023SJohn Marino void 449*e4b17023SJohn Marino clear() noexcept 450*e4b17023SJohn Marino { 451*e4b17023SJohn Marino __profcxx_hashtable_destruct(this, _Base::bucket_count(), 452*e4b17023SJohn Marino _Base::size()); 453*e4b17023SJohn Marino _M_profile_destruct(); 454*e4b17023SJohn Marino _Base::clear(); 455*e4b17023SJohn Marino } 456*e4b17023SJohn Marino 457*e4b17023SJohn Marino template<typename... _Args> 458*e4b17023SJohn Marino iterator 459*e4b17023SJohn Marino emplace(_Args&&... __args) 460*e4b17023SJohn Marino { 461*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 462*e4b17023SJohn Marino iterator __res 463*e4b17023SJohn Marino = _Base::emplace(std::forward<_Args>(__args)...); 464*e4b17023SJohn Marino _M_profile_resize(__old_size); 465*e4b17023SJohn Marino return __res; 466*e4b17023SJohn Marino } 467*e4b17023SJohn Marino 468*e4b17023SJohn Marino template<typename... _Args> 469*e4b17023SJohn Marino iterator 470*e4b17023SJohn Marino emplace_hint(const_iterator __it, _Args&&... __args) 471*e4b17023SJohn Marino { 472*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 473*e4b17023SJohn Marino iterator __res 474*e4b17023SJohn Marino = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); 475*e4b17023SJohn Marino _M_profile_resize(__old_size); 476*e4b17023SJohn Marino return __res; 477*e4b17023SJohn Marino } 478*e4b17023SJohn Marino 479*e4b17023SJohn Marino void 480*e4b17023SJohn Marino insert(std::initializer_list<value_type> __l) 481*e4b17023SJohn Marino { 482*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 483*e4b17023SJohn Marino _Base::insert(__l); 484*e4b17023SJohn Marino _M_profile_resize(__old_size); 485*e4b17023SJohn Marino } 486*e4b17023SJohn Marino 487*e4b17023SJohn Marino iterator 488*e4b17023SJohn Marino insert(const value_type& __obj) 489*e4b17023SJohn Marino { 490*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 491*e4b17023SJohn Marino iterator __res = _Base::insert(__obj); 492*e4b17023SJohn Marino _M_profile_resize(__old_size); 493*e4b17023SJohn Marino return __res; 494*e4b17023SJohn Marino } 495*e4b17023SJohn Marino 496*e4b17023SJohn Marino iterator 497*e4b17023SJohn Marino insert(const_iterator __iter, const value_type& __v) 498*e4b17023SJohn Marino { 499*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 500*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, __v); 501*e4b17023SJohn Marino _M_profile_resize(__old_size); 502*e4b17023SJohn Marino return __res; 503*e4b17023SJohn Marino } 504*e4b17023SJohn Marino 505*e4b17023SJohn Marino template<typename _Pair, typename = typename 506*e4b17023SJohn Marino std::enable_if<std::is_constructible<value_type, 507*e4b17023SJohn Marino _Pair&&>::value>::type> 508*e4b17023SJohn Marino iterator 509*e4b17023SJohn Marino insert(_Pair&& __obj) 510*e4b17023SJohn Marino { 511*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 512*e4b17023SJohn Marino iterator __res = _Base::insert(std::forward<_Pair>(__obj)); 513*e4b17023SJohn Marino _M_profile_resize(__old_size); 514*e4b17023SJohn Marino return __res; 515*e4b17023SJohn Marino } 516*e4b17023SJohn Marino 517*e4b17023SJohn Marino template<typename _Pair, typename = typename 518*e4b17023SJohn Marino std::enable_if<std::is_constructible<value_type, 519*e4b17023SJohn Marino _Pair&&>::value>::type> 520*e4b17023SJohn Marino iterator 521*e4b17023SJohn Marino insert(const_iterator __iter, _Pair&& __v) 522*e4b17023SJohn Marino { 523*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 524*e4b17023SJohn Marino iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); 525*e4b17023SJohn Marino _M_profile_resize(__old_size); 526*e4b17023SJohn Marino return __res; 527*e4b17023SJohn Marino } 528*e4b17023SJohn Marino 529*e4b17023SJohn Marino template<typename _InputIter> 530*e4b17023SJohn Marino void 531*e4b17023SJohn Marino insert(_InputIter __first, _InputIter __last) 532*e4b17023SJohn Marino { 533*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 534*e4b17023SJohn Marino _Base::insert(__first, __last); 535*e4b17023SJohn Marino _M_profile_resize(__old_size); 536*e4b17023SJohn Marino } 537*e4b17023SJohn Marino 538*e4b17023SJohn Marino void 539*e4b17023SJohn Marino insert(const value_type* __first, const value_type* __last) 540*e4b17023SJohn Marino { 541*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 542*e4b17023SJohn Marino _Base::insert(__first, __last); 543*e4b17023SJohn Marino _M_profile_resize(__old_size); 544*e4b17023SJohn Marino } 545*e4b17023SJohn Marino 546*e4b17023SJohn Marino void 547*e4b17023SJohn Marino swap(unordered_multimap& __x) 548*e4b17023SJohn Marino { _Base::swap(__x); } 549*e4b17023SJohn Marino 550*e4b17023SJohn Marino void rehash(size_type __n) 551*e4b17023SJohn Marino { 552*e4b17023SJohn Marino size_type __old_size = _Base::bucket_count(); 553*e4b17023SJohn Marino _Base::rehash(__n); 554*e4b17023SJohn Marino _M_profile_resize(__old_size); 555*e4b17023SJohn Marino } 556*e4b17023SJohn Marino 557*e4b17023SJohn Marino private: 558*e4b17023SJohn Marino void 559*e4b17023SJohn Marino _M_profile_resize(size_type __old_size) 560*e4b17023SJohn Marino { 561*e4b17023SJohn Marino size_type __new_size = _Base::bucket_count(); 562*e4b17023SJohn Marino if (__old_size != __new_size) 563*e4b17023SJohn Marino __profcxx_hashtable_resize(this, __old_size, __new_size); 564*e4b17023SJohn Marino } 565*e4b17023SJohn Marino 566*e4b17023SJohn Marino void 567*e4b17023SJohn Marino _M_profile_destruct() 568*e4b17023SJohn Marino { 569*e4b17023SJohn Marino size_type __hops = 0, __lc = 0, __chain = 0; 570*e4b17023SJohn Marino iterator __it = this->begin(); 571*e4b17023SJohn Marino while (__it != this->end()) 572*e4b17023SJohn Marino { 573*e4b17023SJohn Marino size_type __bkt = this->bucket(__it->first); 574*e4b17023SJohn Marino auto __lit = this->begin(__bkt); 575*e4b17023SJohn Marino auto __lend = this->end(__bkt); 576*e4b17023SJohn Marino for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) 577*e4b17023SJohn Marino ++__chain; 578*e4b17023SJohn Marino if (__chain) 579*e4b17023SJohn Marino { 580*e4b17023SJohn Marino ++__chain; 581*e4b17023SJohn Marino __lc = __lc > __chain ? __lc : __chain; 582*e4b17023SJohn Marino __hops += __chain * (__chain - 1) / 2; 583*e4b17023SJohn Marino __chain = 0; 584*e4b17023SJohn Marino } 585*e4b17023SJohn Marino } 586*e4b17023SJohn Marino __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops); 587*e4b17023SJohn Marino } 588*e4b17023SJohn Marino }; 589*e4b17023SJohn Marino 590*e4b17023SJohn Marino template<typename _Key, typename _Tp, typename _Hash, 591*e4b17023SJohn Marino typename _Pred, typename _Alloc> 592*e4b17023SJohn Marino inline void 593*e4b17023SJohn Marino swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 594*e4b17023SJohn Marino unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 595*e4b17023SJohn Marino { __x.swap(__y); } 596*e4b17023SJohn Marino 597*e4b17023SJohn Marino template<typename _Key, typename _Tp, typename _Hash, 598*e4b17023SJohn Marino typename _Pred, typename _Alloc> 599*e4b17023SJohn Marino inline bool 600*e4b17023SJohn Marino operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 601*e4b17023SJohn Marino const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 602*e4b17023SJohn Marino { return __x._M_equal(__y); } 603*e4b17023SJohn Marino 604*e4b17023SJohn Marino template<typename _Key, typename _Tp, typename _Hash, 605*e4b17023SJohn Marino typename _Pred, typename _Alloc> 606*e4b17023SJohn Marino inline bool 607*e4b17023SJohn Marino operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 608*e4b17023SJohn Marino const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) 609*e4b17023SJohn Marino { return !(__x == __y); } 610*e4b17023SJohn Marino 611*e4b17023SJohn Marino} // namespace __profile 612*e4b17023SJohn Marino} // namespace std 613*e4b17023SJohn Marino 614*e4b17023SJohn Marino#undef _GLIBCXX_BASE 615*e4b17023SJohn Marino#undef _GLIBCXX_STD_BASE 616*e4b17023SJohn Marino 617*e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 618*e4b17023SJohn Marino 619*e4b17023SJohn Marino#endif 620