xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/profile/unordered_map (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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