1 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
3 // Copyright (C) 2009-2015 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_map
25 * This file is a GNU profile extension to the Standard C++ Library.
28 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
29 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
31 #if __cplusplus < 201103L
32 # include <bits/c++0x_warning.h>
34 # include <unordered_map>
36 #include <profile/base.h>
37 #include <profile/unordered_base.h>
39 #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
40 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
42 namespace std _GLIBCXX_VISIBILITY(default)
46 /// Class std::unordered_map wrapper with performance instrumentation.
47 template<typename _Key, typename _Tp,
48 typename _Hash = std::hash<_Key>,
49 typename _Pred = std::equal_to<_Key>,
50 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
52 : public _GLIBCXX_STD_BASE,
53 public _Unordered_profile<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
56 typedef typename _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;
74 typedef typename _Base::mapped_type mapped_type;
76 typedef typename _Base::iterator iterator;
77 typedef typename _Base::const_iterator const_iterator;
79 unordered_map() = default;
82 unordered_map(size_type __n,
83 const hasher& __hf = hasher(),
84 const key_equal& __eql = key_equal(),
85 const allocator_type& __a = allocator_type())
86 : _Base(__n, __hf, __eql, __a) { }
88 template<typename _InputIterator>
89 unordered_map(_InputIterator __f, _InputIterator __l,
91 const hasher& __hf = hasher(),
92 const key_equal& __eql = key_equal(),
93 const allocator_type& __a = allocator_type())
94 : _Base(__f, __l, __n, __hf, __eql, __a) { }
96 unordered_map(const unordered_map&) = default;
98 unordered_map(const _Base& __x)
101 unordered_map(unordered_map&&) = default;
104 unordered_map(const allocator_type& __a)
107 unordered_map(const unordered_map& __umap,
108 const allocator_type& __a)
109 : _Base(__umap, __a) { }
111 unordered_map(unordered_map&& __umap,
112 const allocator_type& __a)
113 : _Base(std::move(__umap._M_base()), __a) { }
115 unordered_map(initializer_list<value_type> __l,
117 const hasher& __hf = hasher(),
118 const key_equal& __eql = key_equal(),
119 const allocator_type& __a = allocator_type())
120 : _Base(__l, __n, __hf, __eql, __a) { }
122 unordered_map(size_type __n, const allocator_type& __a)
123 : unordered_map(__n, hasher(), key_equal(), __a)
126 unordered_map(size_type __n, const hasher& __hf,
127 const allocator_type& __a)
128 : unordered_map(__n, __hf, key_equal(), __a)
131 template<typename _InputIterator>
132 unordered_map(_InputIterator __first, _InputIterator __last,
134 const allocator_type& __a)
135 : unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
138 template<typename _InputIterator>
139 unordered_map(_InputIterator __first, _InputIterator __last,
140 size_type __n, const hasher& __hf,
141 const allocator_type& __a)
142 : unordered_map(__first, __last, __n, __hf, key_equal(), __a)
145 unordered_map(initializer_list<value_type> __l,
147 const allocator_type& __a)
148 : unordered_map(__l, __n, hasher(), key_equal(), __a)
151 unordered_map(initializer_list<value_type> __l,
152 size_type __n, const hasher& __hf,
153 const allocator_type& __a)
154 : unordered_map(__l, __n, __hf, key_equal(), __a)
158 operator=(const unordered_map&) = default;
161 operator=(unordered_map&&) = default;
164 operator=(initializer_list<value_type> __l)
166 this->_M_profile_destruct();
168 this->_M_profile_construct();
175 this->_M_profile_destruct();
177 this->_M_profile_construct();
180 template<typename... _Args>
181 std::pair<iterator, bool>
182 emplace(_Args&&... __args)
184 size_type __old_size = _Base::bucket_count();
185 std::pair<iterator, bool> __res
186 = _Base::emplace(std::forward<_Args>(__args)...);
187 this->_M_profile_resize(__old_size);
191 template<typename... _Args>
193 emplace_hint(const_iterator __it, _Args&&... __args)
195 size_type __old_size = _Base::bucket_count();
197 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
198 this->_M_profile_resize(__old_size);
203 insert(std::initializer_list<value_type> __l)
205 size_type __old_size = _Base::bucket_count();
207 this->_M_profile_resize(__old_size);
210 std::pair<iterator, bool>
211 insert(const value_type& __obj)
213 size_type __old_size = _Base::bucket_count();
214 std::pair<iterator, bool> __res = _Base::insert(__obj);
215 this->_M_profile_resize(__old_size);
220 insert(const_iterator __iter, const value_type& __v)
222 size_type __old_size = _Base::bucket_count();
223 iterator __res = _Base::insert(__iter, __v);
224 this->_M_profile_resize(__old_size);
228 template<typename _Pair, typename = typename
229 std::enable_if<std::is_constructible<value_type,
230 _Pair&&>::value>::type>
231 std::pair<iterator, bool>
232 insert(_Pair&& __obj)
234 size_type __old_size = _Base::bucket_count();
235 std::pair<iterator, bool> __res
236 = _Base::insert(std::forward<_Pair>(__obj));
237 this->_M_profile_resize(__old_size);
241 template<typename _Pair, typename = typename
242 std::enable_if<std::is_constructible<value_type,
243 _Pair&&>::value>::type>
245 insert(const_iterator __iter, _Pair&& __v)
247 size_type __old_size = _Base::bucket_count();
248 iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
249 this->_M_profile_resize(__old_size);
253 template<typename _InputIter>
255 insert(_InputIter __first, _InputIter __last)
257 size_type __old_size = _Base::bucket_count();
258 _Base::insert(__first, __last);
259 this->_M_profile_resize(__old_size);
264 operator[](const _Key& __k)
266 size_type __old_size = _Base::bucket_count();
267 mapped_type& __res = _M_base()[__k];
268 this->_M_profile_resize(__old_size);
273 operator[](_Key&& __k)
275 size_type __old_size = _Base::bucket_count();
276 mapped_type& __res = _M_base()[std::move(__k)];
277 this->_M_profile_resize(__old_size);
282 swap(unordered_map& __x)
283 noexcept( noexcept(__x._M_base().swap(__x)) )
285 _Base::swap(__x._M_base());
289 void rehash(size_type __n)
291 size_type __old_size = _Base::bucket_count();
293 this->_M_profile_resize(__old_size);
297 template<typename _Key, typename _Tp, typename _Hash,
298 typename _Pred, typename _Alloc>
300 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
301 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
304 template<typename _Key, typename _Tp, typename _Hash,
305 typename _Pred, typename _Alloc>
307 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
308 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
309 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
311 template<typename _Key, typename _Tp, typename _Hash,
312 typename _Pred, typename _Alloc>
314 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
315 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
316 { return !(__x == __y); }
319 #undef _GLIBCXX_STD_BASE
320 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
321 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
323 /// Class std::unordered_multimap wrapper with performance instrumentation.
324 template<typename _Key, typename _Tp,
325 typename _Hash = std::hash<_Key>,
326 typename _Pred = std::equal_to<_Key>,
327 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
328 class unordered_multimap
329 : public _GLIBCXX_STD_BASE,
330 public _Unordered_profile<unordered_multimap<_Key, _Tp,
331 _Hash, _Pred, _Alloc>,
334 typedef typename _GLIBCXX_STD_BASE _Base;
337 _M_base() noexcept { return *this; }
340 _M_base() const noexcept { return *this; }
343 typedef typename _Base::size_type size_type;
344 typedef typename _Base::hasher hasher;
345 typedef typename _Base::key_equal key_equal;
346 typedef typename _Base::allocator_type allocator_type;
347 typedef typename _Base::key_type key_type;
348 typedef typename _Base::value_type value_type;
349 typedef typename _Base::difference_type difference_type;
350 typedef typename _Base::reference reference;
351 typedef typename _Base::const_reference const_reference;
353 typedef typename _Base::iterator iterator;
354 typedef typename _Base::const_iterator const_iterator;
356 unordered_multimap() = default;
359 unordered_multimap(size_type __n,
360 const hasher& __hf = hasher(),
361 const key_equal& __eql = key_equal(),
362 const allocator_type& __a = allocator_type())
363 : _Base(__n, __hf, __eql, __a) { }
365 template<typename _InputIterator>
366 unordered_multimap(_InputIterator __f, _InputIterator __l,
368 const hasher& __hf = hasher(),
369 const key_equal& __eql = key_equal(),
370 const allocator_type& __a = allocator_type())
371 : _Base(__f, __l, __n, __hf, __eql, __a) { }
373 unordered_multimap(const unordered_multimap&) = default;
375 unordered_multimap(const _Base& __x)
378 unordered_multimap(unordered_multimap&&) = default;
381 unordered_multimap(const allocator_type& __a)
384 unordered_multimap(const unordered_multimap& __ummap,
385 const allocator_type& __a)
386 : _Base(__ummap._M_base(), __a) { }
388 unordered_multimap(unordered_multimap&& __ummap,
389 const allocator_type& __a)
390 : _Base(std::move(__ummap._M_base()), __a) { }
392 unordered_multimap(initializer_list<value_type> __l,
394 const hasher& __hf = hasher(),
395 const key_equal& __eql = key_equal(),
396 const allocator_type& __a = allocator_type())
397 : _Base(__l, __n, __hf, __eql, __a) { }
399 unordered_multimap(size_type __n, const allocator_type& __a)
400 : unordered_multimap(__n, hasher(), key_equal(), __a)
403 unordered_multimap(size_type __n, const hasher& __hf,
404 const allocator_type& __a)
405 : unordered_multimap(__n, __hf, key_equal(), __a)
408 template<typename _InputIterator>
409 unordered_multimap(_InputIterator __first, _InputIterator __last,
411 const allocator_type& __a)
412 : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
415 template<typename _InputIterator>
416 unordered_multimap(_InputIterator __first, _InputIterator __last,
417 size_type __n, const hasher& __hf,
418 const allocator_type& __a)
419 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
422 unordered_multimap(initializer_list<value_type> __l,
424 const allocator_type& __a)
425 : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
428 unordered_multimap(initializer_list<value_type> __l,
429 size_type __n, const hasher& __hf,
430 const allocator_type& __a)
431 : unordered_multimap(__l, __n, __hf, key_equal(), __a)
435 operator=(const unordered_multimap&) = default;
438 operator=(unordered_multimap&&) = default;
441 operator=(initializer_list<value_type> __l)
443 this->_M_profile_destruct();
445 this->_M_profile_construct();
452 this->_M_profile_destruct();
454 this->_M_profile_construct();
457 template<typename... _Args>
459 emplace(_Args&&... __args)
461 size_type __old_size = _Base::bucket_count();
463 = _Base::emplace(std::forward<_Args>(__args)...);
464 this->_M_profile_resize(__old_size);
468 template<typename... _Args>
470 emplace_hint(const_iterator __it, _Args&&... __args)
472 size_type __old_size = _Base::bucket_count();
474 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
475 this->_M_profile_resize(__old_size);
480 insert(std::initializer_list<value_type> __l)
482 size_type __old_size = _Base::bucket_count();
484 this->_M_profile_resize(__old_size);
488 insert(const value_type& __obj)
490 size_type __old_size = _Base::bucket_count();
491 iterator __res = _Base::insert(__obj);
492 this->_M_profile_resize(__old_size);
497 insert(const_iterator __iter, const value_type& __v)
499 size_type __old_size = _Base::bucket_count();
500 iterator __res = _Base::insert(__iter, __v);
501 this->_M_profile_resize(__old_size);
505 template<typename _Pair, typename = typename
506 std::enable_if<std::is_constructible<value_type,
507 _Pair&&>::value>::type>
509 insert(_Pair&& __obj)
511 size_type __old_size = _Base::bucket_count();
512 iterator __res = _Base::insert(std::forward<_Pair>(__obj));
513 this->_M_profile_resize(__old_size);
517 template<typename _Pair, typename = typename
518 std::enable_if<std::is_constructible<value_type,
519 _Pair&&>::value>::type>
521 insert(const_iterator __iter, _Pair&& __v)
523 size_type __old_size = _Base::bucket_count();
524 iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
525 this->_M_profile_resize(__old_size);
529 template<typename _InputIter>
531 insert(_InputIter __first, _InputIter __last)
533 size_type __old_size = _Base::bucket_count();
534 _Base::insert(__first, __last);
535 this->_M_profile_resize(__old_size);
539 swap(unordered_multimap& __x)
540 noexcept( noexcept(__x._M_base().swap(__x)) )
542 _Base::swap(__x._M_base());
547 rehash(size_type __n)
549 size_type __old_size = _Base::bucket_count();
551 this->_M_profile_resize(__old_size);
555 template<typename _Key, typename _Tp, typename _Hash,
556 typename _Pred, typename _Alloc>
558 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
559 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
562 template<typename _Key, typename _Tp, typename _Hash,
563 typename _Pred, typename _Alloc>
565 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
566 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
567 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
569 template<typename _Key, typename _Tp, typename _Hash,
570 typename _Pred, typename _Alloc>
572 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
573 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
574 { return !(__x == __y); }
576 } // namespace __profile
580 #undef _GLIBCXX_STD_BASE