libstdc++
profile/unordered_map
1 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
2 
3 // Copyright (C) 2009-2015 Free Software Foundation, Inc.
4 //
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)
9 // any later version.
10 //
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.
15 
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.
19 
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/>.
23 
24 /** @file profile/unordered_map
25  * This file is a GNU profile extension to the Standard C++ Library.
26  */
27 
28 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
29 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
30 
31 #if __cplusplus < 201103L
32 # include <bits/c++0x_warning.h>
33 #else
34 # include <unordered_map>
35 
36 #include <profile/base.h>
37 #include <profile/unordered_base.h>
38 
39 #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
40 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
41 
42 namespace std _GLIBCXX_VISIBILITY(default)
43 {
44 namespace __profile
45 {
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> > >
51  class unordered_map
52  : public _GLIBCXX_STD_BASE,
53  public _Unordered_profile<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
54  true>
55  {
56  typedef typename _GLIBCXX_STD_BASE _Base;
57 
58  _Base&
59  _M_base() noexcept { return *this; }
60 
61  const _Base&
62  _M_base() const noexcept { return *this; }
63 
64  public:
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;
75 
76  typedef typename _Base::iterator iterator;
77  typedef typename _Base::const_iterator const_iterator;
78 
79  unordered_map() = default;
80 
81  explicit
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) { }
87 
88  template<typename _InputIterator>
89  unordered_map(_InputIterator __f, _InputIterator __l,
90  size_type __n = 0,
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) { }
95 
96  unordered_map(const unordered_map&) = default;
97 
98  unordered_map(const _Base& __x)
99  : _Base(__x) { }
100 
101  unordered_map(unordered_map&&) = default;
102 
103  explicit
104  unordered_map(const allocator_type& __a)
105  : _Base(__a) { }
106 
107  unordered_map(const unordered_map& __umap,
108  const allocator_type& __a)
109  : _Base(__umap, __a) { }
110 
111  unordered_map(unordered_map&& __umap,
112  const allocator_type& __a)
113  : _Base(std::move(__umap._M_base()), __a) { }
114 
115  unordered_map(initializer_list<value_type> __l,
116  size_type __n = 0,
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) { }
121 
122  unordered_map&
123  operator=(const unordered_map&) = default;
124 
125  unordered_map&
126  operator=(unordered_map&&) = default;
127 
128  unordered_map&
129  operator=(initializer_list<value_type> __l)
130  {
131  this->_M_profile_destruct();
132  _M_base() = __l;
133  this->_M_profile_construct();
134  return *this;
135  }
136 
137  void
138  clear() noexcept
139  {
140  this->_M_profile_destruct();
141  _Base::clear();
142  this->_M_profile_construct();
143  }
144 
145  template<typename... _Args>
146  std::pair<iterator, bool>
147  emplace(_Args&&... __args)
148  {
149  size_type __old_size = _Base::bucket_count();
150  std::pair<iterator, bool> __res
151  = _Base::emplace(std::forward<_Args>(__args)...);
152  this->_M_profile_resize(__old_size);
153  return __res;
154  }
155 
156  template<typename... _Args>
157  iterator
158  emplace_hint(const_iterator __it, _Args&&... __args)
159  {
160  size_type __old_size = _Base::bucket_count();
161  iterator __res
162  = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
163  this->_M_profile_resize(__old_size);
164  return __res;
165  }
166 
167  void
168  insert(std::initializer_list<value_type> __l)
169  {
170  size_type __old_size = _Base::bucket_count();
171  _Base::insert(__l);
172  this->_M_profile_resize(__old_size);
173  }
174 
175  std::pair<iterator, bool>
176  insert(const value_type& __obj)
177  {
178  size_type __old_size = _Base::bucket_count();
179  std::pair<iterator, bool> __res = _Base::insert(__obj);
180  this->_M_profile_resize(__old_size);
181  return __res;
182  }
183 
184  iterator
185  insert(const_iterator __iter, const value_type& __v)
186  {
187  size_type __old_size = _Base::bucket_count();
188  iterator __res = _Base::insert(__iter, __v);
189  this->_M_profile_resize(__old_size);
190  return __res;
191  }
192 
193  template<typename _Pair, typename = typename
194  std::enable_if<std::is_constructible<value_type,
195  _Pair&&>::value>::type>
196  std::pair<iterator, bool>
197  insert(_Pair&& __obj)
198  {
199  size_type __old_size = _Base::bucket_count();
200  std::pair<iterator, bool> __res
201  = _Base::insert(std::forward<_Pair>(__obj));
202  this->_M_profile_resize(__old_size);
203  return __res;
204  }
205 
206  template<typename _Pair, typename = typename
207  std::enable_if<std::is_constructible<value_type,
208  _Pair&&>::value>::type>
209  iterator
210  insert(const_iterator __iter, _Pair&& __v)
211  {
212  size_type __old_size = _Base::bucket_count();
213  iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
214  this->_M_profile_resize(__old_size);
215  return __res;
216  }
217 
218  template<typename _InputIter>
219  void
220  insert(_InputIter __first, _InputIter __last)
221  {
222  size_type __old_size = _Base::bucket_count();
223  _Base::insert(__first, __last);
224  this->_M_profile_resize(__old_size);
225  }
226 
227  // operator[]
228  mapped_type&
229  operator[](const _Key& __k)
230  {
231  size_type __old_size = _Base::bucket_count();
232  mapped_type& __res = _M_base()[__k];
233  this->_M_profile_resize(__old_size);
234  return __res;
235  }
236 
237  mapped_type&
238  operator[](_Key&& __k)
239  {
240  size_type __old_size = _Base::bucket_count();
241  mapped_type& __res = _M_base()[std::move(__k)];
242  this->_M_profile_resize(__old_size);
243  return __res;
244  }
245 
246  void
247  swap(unordered_map& __x)
248  noexcept( noexcept(__x._M_base().swap(__x)) )
249  {
250  _Base::swap(__x._M_base());
251  this->_M_swap(__x);
252  }
253 
254  void rehash(size_type __n)
255  {
256  size_type __old_size = _Base::bucket_count();
257  _Base::rehash(__n);
258  this->_M_profile_resize(__old_size);
259  }
260  };
261 
262  template<typename _Key, typename _Tp, typename _Hash,
263  typename _Pred, typename _Alloc>
264  inline void
265  swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
266  unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
267  { __x.swap(__y); }
268 
269  template<typename _Key, typename _Tp, typename _Hash,
270  typename _Pred, typename _Alloc>
271  inline bool
272  operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
273  const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
274  { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
275 
276  template<typename _Key, typename _Tp, typename _Hash,
277  typename _Pred, typename _Alloc>
278  inline bool
279  operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
280  const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
281  { return !(__x == __y); }
282 
283 #undef _GLIBCXX_BASE
284 #undef _GLIBCXX_STD_BASE
285 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
286 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
287 
288  /// Class std::unordered_multimap wrapper with performance instrumentation.
289  template<typename _Key, typename _Tp,
290  typename _Hash = std::hash<_Key>,
291  typename _Pred = std::equal_to<_Key>,
292  typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
293  class unordered_multimap
294  : public _GLIBCXX_STD_BASE,
295  public _Unordered_profile<unordered_multimap<_Key, _Tp,
296  _Hash, _Pred, _Alloc>,
297  false>
298  {
299  typedef typename _GLIBCXX_STD_BASE _Base;
300 
301  _Base&
302  _M_base() noexcept { return *this; }
303 
304  const _Base&
305  _M_base() const noexcept { return *this; }
306 
307  public:
308  typedef typename _Base::size_type size_type;
309  typedef typename _Base::hasher hasher;
310  typedef typename _Base::key_equal key_equal;
311  typedef typename _Base::allocator_type allocator_type;
312  typedef typename _Base::key_type key_type;
313  typedef typename _Base::value_type value_type;
314  typedef typename _Base::difference_type difference_type;
315  typedef typename _Base::reference reference;
316  typedef typename _Base::const_reference const_reference;
317 
318  typedef typename _Base::iterator iterator;
319  typedef typename _Base::const_iterator const_iterator;
320 
321  unordered_multimap() = default;
322 
323  explicit
324  unordered_multimap(size_type __n,
325  const hasher& __hf = hasher(),
326  const key_equal& __eql = key_equal(),
327  const allocator_type& __a = allocator_type())
328  : _Base(__n, __hf, __eql, __a) { }
329 
330  template<typename _InputIterator>
331  unordered_multimap(_InputIterator __f, _InputIterator __l,
332  size_type __n = 0,
333  const hasher& __hf = hasher(),
334  const key_equal& __eql = key_equal(),
335  const allocator_type& __a = allocator_type())
336  : _Base(__f, __l, __n, __hf, __eql, __a) { }
337 
338  unordered_multimap(const unordered_multimap&) = default;
339 
340  unordered_multimap(const _Base& __x)
341  : _Base(__x) { }
342 
343  unordered_multimap(unordered_multimap&&) = default;
344 
345  explicit
346  unordered_multimap(const allocator_type& __a)
347  : _Base(__a) { }
348 
349  unordered_multimap(const unordered_multimap& __ummap,
350  const allocator_type& __a)
351  : _Base(__ummap._M_base(), __a) { }
352 
353  unordered_multimap(unordered_multimap&& __ummap,
354  const allocator_type& __a)
355  : _Base(std::move(__ummap._M_base()), __a) { }
356 
357  unordered_multimap(initializer_list<value_type> __l,
358  size_type __n = 0,
359  const hasher& __hf = hasher(),
360  const key_equal& __eql = key_equal(),
361  const allocator_type& __a = allocator_type())
362  : _Base(__l, __n, __hf, __eql, __a) { }
363 
364  unordered_multimap&
365  operator=(const unordered_multimap&) = default;
366 
367  unordered_multimap&
368  operator=(unordered_multimap&&) = default;
369 
370  unordered_multimap&
371  operator=(initializer_list<value_type> __l)
372  {
373  this->_M_profile_destruct();
374  _M_base() = __l;
375  this->_M_profile_construct();
376  return *this;
377  }
378 
379  void
380  clear() noexcept
381  {
382  this->_M_profile_destruct();
383  _Base::clear();
384  this->_M_profile_construct();
385  }
386 
387  template<typename... _Args>
388  iterator
389  emplace(_Args&&... __args)
390  {
391  size_type __old_size = _Base::bucket_count();
392  iterator __res
393  = _Base::emplace(std::forward<_Args>(__args)...);
394  this->_M_profile_resize(__old_size);
395  return __res;
396  }
397 
398  template<typename... _Args>
399  iterator
400  emplace_hint(const_iterator __it, _Args&&... __args)
401  {
402  size_type __old_size = _Base::bucket_count();
403  iterator __res
404  = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
405  this->_M_profile_resize(__old_size);
406  return __res;
407  }
408 
409  void
410  insert(std::initializer_list<value_type> __l)
411  {
412  size_type __old_size = _Base::bucket_count();
413  _Base::insert(__l);
414  this->_M_profile_resize(__old_size);
415  }
416 
417  iterator
418  insert(const value_type& __obj)
419  {
420  size_type __old_size = _Base::bucket_count();
421  iterator __res = _Base::insert(__obj);
422  this->_M_profile_resize(__old_size);
423  return __res;
424  }
425 
426  iterator
427  insert(const_iterator __iter, const value_type& __v)
428  {
429  size_type __old_size = _Base::bucket_count();
430  iterator __res = _Base::insert(__iter, __v);
431  this->_M_profile_resize(__old_size);
432  return __res;
433  }
434 
435  template<typename _Pair, typename = typename
436  std::enable_if<std::is_constructible<value_type,
437  _Pair&&>::value>::type>
438  iterator
439  insert(_Pair&& __obj)
440  {
441  size_type __old_size = _Base::bucket_count();
442  iterator __res = _Base::insert(std::forward<_Pair>(__obj));
443  this->_M_profile_resize(__old_size);
444  return __res;
445  }
446 
447  template<typename _Pair, typename = typename
448  std::enable_if<std::is_constructible<value_type,
449  _Pair&&>::value>::type>
450  iterator
451  insert(const_iterator __iter, _Pair&& __v)
452  {
453  size_type __old_size = _Base::bucket_count();
454  iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
455  this->_M_profile_resize(__old_size);
456  return __res;
457  }
458 
459  template<typename _InputIter>
460  void
461  insert(_InputIter __first, _InputIter __last)
462  {
463  size_type __old_size = _Base::bucket_count();
464  _Base::insert(__first, __last);
465  this->_M_profile_resize(__old_size);
466  }
467 
468  void
469  swap(unordered_multimap& __x)
470  noexcept( noexcept(__x._M_base().swap(__x)) )
471  {
472  _Base::swap(__x._M_base());
473  this->_M_swap(__x);
474  }
475 
476  void
477  rehash(size_type __n)
478  {
479  size_type __old_size = _Base::bucket_count();
480  _Base::rehash(__n);
481  this->_M_profile_resize(__old_size);
482  }
483  };
484 
485  template<typename _Key, typename _Tp, typename _Hash,
486  typename _Pred, typename _Alloc>
487  inline void
488  swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
489  unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
490  { __x.swap(__y); }
491 
492  template<typename _Key, typename _Tp, typename _Hash,
493  typename _Pred, typename _Alloc>
494  inline bool
495  operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
496  const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
497  { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
498 
499  template<typename _Key, typename _Tp, typename _Hash,
500  typename _Pred, typename _Alloc>
501  inline bool
502  operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
503  const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
504  { return !(__x == __y); }
505 
506 } // namespace __profile
507 } // namespace std
508 
509 #undef _GLIBCXX_BASE
510 #undef _GLIBCXX_STD_BASE
511 
512 #endif // C++11
513 
514 #endif