1 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
3 // Copyright (C) 2009-2019 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)
302 noexcept(noexcept(__x.swap(__y)))
305 template<typename _Key, typename _Tp, typename _Hash,
306 typename _Pred, typename _Alloc>
308 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
309 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
310 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
312 template<typename _Key, typename _Tp, typename _Hash,
313 typename _Pred, typename _Alloc>
315 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
316 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
317 { return !(__x == __y); }
320 #undef _GLIBCXX_STD_BASE
321 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
322 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
324 /// Class std::unordered_multimap wrapper with performance instrumentation.
325 template<typename _Key, typename _Tp,
326 typename _Hash = std::hash<_Key>,
327 typename _Pred = std::equal_to<_Key>,
328 typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
329 class unordered_multimap
330 : public _GLIBCXX_STD_BASE,
331 public _Unordered_profile<unordered_multimap<_Key, _Tp,
332 _Hash, _Pred, _Alloc>,
335 typedef typename _GLIBCXX_STD_BASE _Base;
338 _M_base() noexcept { return *this; }
341 _M_base() const noexcept { return *this; }
344 typedef typename _Base::size_type size_type;
345 typedef typename _Base::hasher hasher;
346 typedef typename _Base::key_equal key_equal;
347 typedef typename _Base::allocator_type allocator_type;
348 typedef typename _Base::key_type key_type;
349 typedef typename _Base::value_type value_type;
350 typedef typename _Base::difference_type difference_type;
351 typedef typename _Base::reference reference;
352 typedef typename _Base::const_reference const_reference;
354 typedef typename _Base::iterator iterator;
355 typedef typename _Base::const_iterator const_iterator;
357 unordered_multimap() = default;
360 unordered_multimap(size_type __n,
361 const hasher& __hf = hasher(),
362 const key_equal& __eql = key_equal(),
363 const allocator_type& __a = allocator_type())
364 : _Base(__n, __hf, __eql, __a) { }
366 template<typename _InputIterator>
367 unordered_multimap(_InputIterator __f, _InputIterator __l,
369 const hasher& __hf = hasher(),
370 const key_equal& __eql = key_equal(),
371 const allocator_type& __a = allocator_type())
372 : _Base(__f, __l, __n, __hf, __eql, __a) { }
374 unordered_multimap(const unordered_multimap&) = default;
376 unordered_multimap(const _Base& __x)
379 unordered_multimap(unordered_multimap&&) = default;
382 unordered_multimap(const allocator_type& __a)
385 unordered_multimap(const unordered_multimap& __ummap,
386 const allocator_type& __a)
387 : _Base(__ummap._M_base(), __a) { }
389 unordered_multimap(unordered_multimap&& __ummap,
390 const allocator_type& __a)
391 : _Base(std::move(__ummap._M_base()), __a) { }
393 unordered_multimap(initializer_list<value_type> __l,
395 const hasher& __hf = hasher(),
396 const key_equal& __eql = key_equal(),
397 const allocator_type& __a = allocator_type())
398 : _Base(__l, __n, __hf, __eql, __a) { }
400 unordered_multimap(size_type __n, const allocator_type& __a)
401 : unordered_multimap(__n, hasher(), key_equal(), __a)
404 unordered_multimap(size_type __n, const hasher& __hf,
405 const allocator_type& __a)
406 : unordered_multimap(__n, __hf, key_equal(), __a)
409 template<typename _InputIterator>
410 unordered_multimap(_InputIterator __first, _InputIterator __last,
412 const allocator_type& __a)
413 : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
416 template<typename _InputIterator>
417 unordered_multimap(_InputIterator __first, _InputIterator __last,
418 size_type __n, const hasher& __hf,
419 const allocator_type& __a)
420 : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
423 unordered_multimap(initializer_list<value_type> __l,
425 const allocator_type& __a)
426 : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
429 unordered_multimap(initializer_list<value_type> __l,
430 size_type __n, const hasher& __hf,
431 const allocator_type& __a)
432 : unordered_multimap(__l, __n, __hf, key_equal(), __a)
436 operator=(const unordered_multimap&) = default;
439 operator=(unordered_multimap&&) = default;
442 operator=(initializer_list<value_type> __l)
444 this->_M_profile_destruct();
446 this->_M_profile_construct();
453 this->_M_profile_destruct();
455 this->_M_profile_construct();
458 template<typename... _Args>
460 emplace(_Args&&... __args)
462 size_type __old_size = _Base::bucket_count();
464 = _Base::emplace(std::forward<_Args>(__args)...);
465 this->_M_profile_resize(__old_size);
469 template<typename... _Args>
471 emplace_hint(const_iterator __it, _Args&&... __args)
473 size_type __old_size = _Base::bucket_count();
475 = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
476 this->_M_profile_resize(__old_size);
481 insert(std::initializer_list<value_type> __l)
483 size_type __old_size = _Base::bucket_count();
485 this->_M_profile_resize(__old_size);
489 insert(const value_type& __obj)
491 size_type __old_size = _Base::bucket_count();
492 iterator __res = _Base::insert(__obj);
493 this->_M_profile_resize(__old_size);
498 insert(const_iterator __iter, const value_type& __v)
500 size_type __old_size = _Base::bucket_count();
501 iterator __res = _Base::insert(__iter, __v);
502 this->_M_profile_resize(__old_size);
506 template<typename _Pair, typename = typename
507 std::enable_if<std::is_constructible<value_type,
508 _Pair&&>::value>::type>
510 insert(_Pair&& __obj)
512 size_type __old_size = _Base::bucket_count();
513 iterator __res = _Base::insert(std::forward<_Pair>(__obj));
514 this->_M_profile_resize(__old_size);
518 template<typename _Pair, typename = typename
519 std::enable_if<std::is_constructible<value_type,
520 _Pair&&>::value>::type>
522 insert(const_iterator __iter, _Pair&& __v)
524 size_type __old_size = _Base::bucket_count();
525 iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
526 this->_M_profile_resize(__old_size);
530 template<typename _InputIter>
532 insert(_InputIter __first, _InputIter __last)
534 size_type __old_size = _Base::bucket_count();
535 _Base::insert(__first, __last);
536 this->_M_profile_resize(__old_size);
540 swap(unordered_multimap& __x)
541 noexcept( noexcept(__x._M_base().swap(__x)) )
543 _Base::swap(__x._M_base());
548 rehash(size_type __n)
550 size_type __old_size = _Base::bucket_count();
552 this->_M_profile_resize(__old_size);
556 template<typename _Key, typename _Tp, typename _Hash,
557 typename _Pred, typename _Alloc>
559 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
560 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
561 noexcept(noexcept(__x.swap(__y)))
564 template<typename _Key, typename _Tp, typename _Hash,
565 typename _Pred, typename _Alloc>
567 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
568 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
569 { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
571 template<typename _Key, typename _Tp, typename _Hash,
572 typename _Pred, typename _Alloc>
574 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
575 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
576 { return !(__x == __y); }
578 } // namespace __profile
582 #undef _GLIBCXX_STD_BASE