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