1 // Profiling unordered_set/unordered_multiset implementation -*- C++ -*-
3 // Copyright (C) 2009-2014 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License along
21 // with this library; see the file COPYING3. If not see
22 // <http://www.gnu.org/licenses/>.
24 /** @file profile/unordered_set
25 * This file is a GNU profile extension to the Standard C++ Library.
28 #ifndef _GLIBCXX_PROFILE_UNORDERED_SET
29 #define _GLIBCXX_PROFILE_UNORDERED_SET 1
31 #if __cplusplus < 201103L
32 # include <bits/c++0x_warning.h>
34 # include <unordered_set>
36 #include <profile/base.h>
37 #include <profile/unordered_base.h>
39 #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
40 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
42 namespace std _GLIBCXX_VISIBILITY(default)
46 /** @brief Unordered_set wrapper with performance instrumentation. */
47 template<typename _Key,
48 typename _Hash = std::hash<_Key>,
49 typename _Pred = std::equal_to<_Key>,
50 typename _Alloc = std::allocator<_Key> >
52 : public _GLIBCXX_STD_BASE,
53 public _Unordered_profile<unordered_set<_Key, _Hash, _Pred, _Alloc>,
56 typedef _GLIBCXX_STD_BASE _Base;
59 _M_base() noexcept { return *this; }
62 _M_base() const noexcept { return *this; }
65 typedef typename _Base::size_type size_type;
66 typedef typename _Base::hasher hasher;
67 typedef typename _Base::key_equal key_equal;
68 typedef typename _Base::allocator_type allocator_type;
69 typedef typename _Base::key_type key_type;
70 typedef typename _Base::value_type value_type;
71 typedef typename _Base::difference_type difference_type;
72 typedef typename _Base::reference reference;
73 typedef typename _Base::const_reference const_reference;
75 typedef typename _Base::iterator iterator;
76 typedef typename _Base::const_iterator const_iterator;
79 unordered_set(size_type __n = 10,
80 const hasher& __hf = hasher(),
81 const key_equal& __eql = key_equal(),
82 const allocator_type& __a = allocator_type())
83 : _Base(__n, __hf, __eql, __a)
86 template<typename _InputIterator>
87 unordered_set(_InputIterator __f, _InputIterator __l,
89 const hasher& __hf = hasher(),
90 const key_equal& __eql = key_equal(),
91 const allocator_type& __a = allocator_type())
92 : _Base(__f, __l, __n, __hf, __eql, __a)
95 unordered_set(const unordered_set&) = default;
97 unordered_set(const _Base& __x)
101 unordered_set(unordered_set&&) = default;
104 unordered_set(const allocator_type& __a)
108 unordered_set(const unordered_set& __uset,
109 const allocator_type& __a)
110 : _Base(__uset._M_base(), __a)
113 unordered_set(unordered_set&& __uset,
114 const allocator_type& __a)
115 : _Base(std::move(__uset._M_base()), __a)
118 unordered_set(initializer_list<value_type> __l,
120 const hasher& __hf = hasher(),
121 const key_equal& __eql = key_equal(),
122 const allocator_type& __a = allocator_type())
123 : _Base(__l, __n, __hf, __eql, __a)
127 operator=(const unordered_set&) = default;
130 operator=(unordered_set&&) = default;
133 operator=(initializer_list<value_type> __l)
140 swap(unordered_set& __x)
141 noexcept( noexcept(__x._M_base().swap(__x)) )
142 { _Base::swap(__x); }
147 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
149 this->_M_profile_destruct();
153 template<typename... _Args>
154 std::pair<iterator, bool>
155 emplace(_Args&&... __args)
157 size_type __old_size = _Base::bucket_count();
158 std::pair<iterator, bool> __res
159 = _Base::emplace(std::forward<_Args>(__args)...);
160 _M_profile_resize(__old_size);
164 template<typename... _Args>
166 emplace_hint(const_iterator __it, _Args&&... __args)
168 size_type __old_size = _Base::bucket_count();
170 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
171 _M_profile_resize(__old_size);
176 insert(std::initializer_list<value_type> __l)
178 size_type __old_size = _Base::bucket_count();
180 _M_profile_resize(__old_size);
183 std::pair<iterator, bool>
184 insert(const value_type& __obj)
186 size_type __old_size = _Base::bucket_count();
187 std::pair<iterator, bool> __res = _Base::insert(__obj);
188 _M_profile_resize(__old_size);
193 insert(const_iterator __iter, const value_type& __v)
195 size_type __old_size = _Base::bucket_count();
196 iterator __res = _Base::insert(__iter, __v);
197 _M_profile_resize(__old_size);
201 std::pair<iterator, bool>
202 insert(value_type&& __obj)
204 size_type __old_size = _Base::bucket_count();
205 std::pair<iterator, bool> __res = _Base::insert(std::move(__obj));
206 _M_profile_resize(__old_size);
211 insert(const_iterator __iter, value_type&& __v)
213 size_type __old_size = _Base::bucket_count();
214 iterator __res = _Base::insert(__iter, std::move(__v));
215 _M_profile_resize(__old_size);
219 template<typename _InputIter>
221 insert(_InputIter __first, _InputIter __last)
223 size_type __old_size = _Base::bucket_count();
224 _Base::insert(__first, __last);
225 _M_profile_resize(__old_size);
229 rehash(size_type __n)
231 size_type __old_size = _Base::bucket_count();
233 _M_profile_resize(__old_size);
238 _M_profile_resize(size_type __old_size)
240 size_type __new_size = _Base::bucket_count();
241 if (__old_size != __new_size)
242 __profcxx_hashtable_resize(this, __old_size, __new_size);
246 template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
248 swap(unordered_set<_Key, _Hash, _Pred, _Alloc>& __x,
249 unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
252 template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
254 operator==(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x,
255 const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
256 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
258 template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
260 operator!=(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x,
261 const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
262 { return !(__x == __y); }
265 #undef _GLIBCXX_STD_BASE
266 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
267 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
269 /** @brief Unordered_multiset wrapper with performance instrumentation. */
270 template<typename _Value,
271 typename _Hash = std::hash<_Value>,
272 typename _Pred = std::equal_to<_Value>,
273 typename _Alloc = std::allocator<_Value> >
274 class unordered_multiset
275 : public _GLIBCXX_STD_BASE,
276 public _Unordered_profile<unordered_multiset<_Value,
277 _Hash, _Pred, _Alloc>,
280 typedef _GLIBCXX_STD_BASE _Base;
283 _M_base() noexcept { return *this; }
286 _M_base() const noexcept { return *this; }
289 typedef typename _Base::size_type size_type;
290 typedef typename _Base::hasher hasher;
291 typedef typename _Base::key_equal key_equal;
292 typedef typename _Base::allocator_type allocator_type;
293 typedef typename _Base::key_type key_type;
294 typedef typename _Base::value_type value_type;
295 typedef typename _Base::difference_type difference_type;
296 typedef typename _Base::reference reference;
297 typedef typename _Base::const_reference const_reference;
299 typedef typename _Base::iterator iterator;
300 typedef typename _Base::const_iterator const_iterator;
303 unordered_multiset(size_type __n = 10,
304 const hasher& __hf = hasher(),
305 const key_equal& __eql = key_equal(),
306 const allocator_type& __a = allocator_type())
307 : _Base(__n, __hf, __eql, __a)
310 template<typename _InputIterator>
311 unordered_multiset(_InputIterator __f, _InputIterator __l,
313 const hasher& __hf = hasher(),
314 const key_equal& __eql = key_equal(),
315 const allocator_type& __a = allocator_type())
316 : _Base(__f, __l, __n, __hf, __eql, __a)
319 unordered_multiset(const unordered_multiset&) = default;
321 unordered_multiset(const _Base& __x)
325 unordered_multiset(unordered_multiset&&) = default;
328 unordered_multiset(const allocator_type& __a)
332 unordered_multiset(const unordered_multiset& __umset,
333 const allocator_type& __a)
334 : _Base(__umset._M_base(), __a)
337 unordered_multiset(unordered_multiset&& __umset,
338 const allocator_type& __a)
339 : _Base(std::move(__umset._M_base()), __a)
342 unordered_multiset(initializer_list<value_type> __l,
344 const hasher& __hf = hasher(),
345 const key_equal& __eql = key_equal(),
346 const allocator_type& __a = allocator_type())
347 : _Base(__l, __n, __hf, __eql, __a)
351 operator=(const unordered_multiset&) = default;
354 operator=(unordered_multiset&&) = default;
357 operator=(initializer_list<value_type> __l)
364 swap(unordered_multiset& __x)
365 noexcept( noexcept(__x._M_base().swap(__x)) )
366 { _Base::swap(__x); }
371 __profcxx_hashtable_destruct(this, _Base::bucket_count(),
373 this->_M_profile_destruct();
377 template<typename... _Args>
379 emplace(_Args&&... __args)
381 size_type __old_size = _Base::bucket_count();
382 iterator __res = _Base::emplace(std::forward<_Args>(__args)...);
383 _M_profile_resize(__old_size);
387 template<typename... _Args>
389 emplace_hint(const_iterator __it, _Args&&... __args)
391 size_type __old_size = _Base::bucket_count();
393 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
394 _M_profile_resize(__old_size);
399 insert(std::initializer_list<value_type> __l)
401 size_type __old_size = _Base::bucket_count();
403 _M_profile_resize(__old_size);
407 insert(const value_type& __obj)
409 size_type __old_size = _Base::bucket_count();
410 iterator __res = _Base::insert(__obj);
411 _M_profile_resize(__old_size);
416 insert(const_iterator __iter, const value_type& __v)
418 size_type __old_size = _Base::bucket_count();
419 iterator __res = _Base::insert(__iter, __v);
420 _M_profile_resize(__old_size);
425 insert(value_type&& __obj)
427 size_type __old_size = _Base::bucket_count();
428 iterator __res = _Base::insert(std::move(__obj));
429 _M_profile_resize(__old_size);
434 insert(const_iterator __iter, value_type&& __v)
436 size_type __old_size = _Base::bucket_count();
437 iterator __res = _Base::insert(__iter, std::move(__v));
438 _M_profile_resize(__old_size);
442 template<typename _InputIter>
444 insert(_InputIter __first, _InputIter __last)
446 size_type __old_size = _Base::bucket_count();
447 _Base::insert(__first, __last);
448 _M_profile_resize(__old_size);
452 rehash(size_type __n)
454 size_type __old_size = _Base::bucket_count();
456 _M_profile_resize(__old_size);
461 _M_profile_resize(size_type __old_size)
463 size_type __new_size = _Base::bucket_count();
464 if (__old_size != __new_size)
465 __profcxx_hashtable_resize(this, __old_size, __new_size);
469 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
471 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
472 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
475 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
477 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
478 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
479 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
481 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
483 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
484 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
485 { return !(__x == __y); }
487 } // namespace __profile
491 #undef _GLIBCXX_STD_BASE