2013-05-07 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / libstdc++-v3 / include / profile / unordered_map
blobac5fecc60fafc10f2c32eb108ecfca16a09f133d
1 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
3 // Copyright (C) 2009-2013 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.
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.
26  */
28 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
29 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
31 #if __cplusplus < 201103L
32 # include <bits/c++0x_warning.h>
33 #else
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)
44 namespace __profile
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;
58       _Base&
59       _M_base() noexcept       { return *this; }
61       const _Base&
62       _M_base() const noexcept { return *this; }
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;
76       typedef typename _Base::iterator iterator;
77       typedef typename _Base::const_iterator const_iterator;
79       explicit
80       unordered_map(size_type __n = 10,
81                     const hasher& __hf = hasher(),
82                     const key_equal& __eql = key_equal(),
83                     const allocator_type& __a = allocator_type())
84         : _Base(__n, __hf, __eql, __a)
85       { }
87       template<typename _InputIterator>
88         unordered_map(_InputIterator __f, _InputIterator __l,
89                       size_type __n = 0,
90                       const hasher& __hf = hasher(),
91                       const key_equal& __eql = key_equal(),
92                       const allocator_type& __a = allocator_type())
93           : _Base(__f, __l, __n, __hf, __eql, __a)
94         { }
96       unordered_map(const unordered_map&) = default;
98       unordered_map(const _Base& __x)
99         : _Base(__x)
100       { }
102       unordered_map(unordered_map&&) = default;
104       explicit
105       unordered_map(const allocator_type& __a)
106         : _Base(__a)
107       { }
109       unordered_map(const unordered_map& __umap,
110                     const allocator_type& __a)
111         : _Base(__umap, __a)
112       { }
114       unordered_map(unordered_map&& __umap,
115                     const allocator_type& __a)
116         : _Base(std::move(__umap._M_base()), __a)
117       { }
119       unordered_map(initializer_list<value_type> __l,
120                     size_type __n = 0,
121                     const hasher& __hf = hasher(),
122                     const key_equal& __eql = key_equal(),
123                     const allocator_type& __a = allocator_type())
124         : _Base(__l, __n, __hf, __eql, __a)
125       { }
127       unordered_map&
128       operator=(const unordered_map&) = default;
130       unordered_map&
131       operator=(unordered_map&&) = default;
133       unordered_map&
134       operator=(initializer_list<value_type> __l)
135       {
136         _M_base() = __l;
137         return *this;
138       }
140       void
141       clear() noexcept
142       {
143         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
144                                      _Base::size());
145         this->_M_profile_destruct();
146         _Base::clear();
147       }
149       template<typename... _Args>
150         std::pair<iterator, bool>
151         emplace(_Args&&... __args)
152         {
153           size_type __old_size = _Base::bucket_count();
154           std::pair<iterator, bool> __res
155             = _Base::emplace(std::forward<_Args>(__args)...);
156           _M_profile_resize(__old_size);
157           return __res;
158         }
160       template<typename... _Args>
161         iterator
162         emplace_hint(const_iterator __it, _Args&&... __args)
163         {
164           size_type __old_size = _Base::bucket_count();
165           iterator __res
166             = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
167           _M_profile_resize(__old_size);
168           return __res;
169         }
171       void
172       insert(std::initializer_list<value_type> __l)
173       { 
174         size_type __old_size = _Base::bucket_count(); 
175         _Base::insert(__l);
176         _M_profile_resize(__old_size); 
177       }
179       std::pair<iterator, bool>
180       insert(const value_type& __obj)
181       {
182         size_type __old_size = _Base::bucket_count();
183         std::pair<iterator, bool> __res = _Base::insert(__obj);
184         _M_profile_resize(__old_size); 
185         return __res;
186       }
188       iterator
189       insert(const_iterator __iter, const value_type& __v)
190       { 
191         size_type __old_size = _Base::bucket_count(); 
192         iterator __res = _Base::insert(__iter, __v);
193         _M_profile_resize(__old_size); 
194         return __res;
195       }
197       template<typename _Pair, typename = typename
198                std::enable_if<std::is_constructible<value_type,
199                                                     _Pair&&>::value>::type>
200         std::pair<iterator, bool>
201         insert(_Pair&& __obj)
202         {
203           size_type __old_size = _Base::bucket_count();
204           std::pair<iterator, bool> __res
205             = _Base::insert(std::forward<_Pair>(__obj));
206           _M_profile_resize(__old_size); 
207           return __res;
208         }
210       template<typename _Pair, typename = typename
211                std::enable_if<std::is_constructible<value_type,
212                                                     _Pair&&>::value>::type>
213         iterator
214         insert(const_iterator __iter, _Pair&& __v)
215         { 
216           size_type __old_size = _Base::bucket_count(); 
217           iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
218           _M_profile_resize(__old_size); 
219           return __res;
220         }
222       template<typename _InputIter>
223         void
224         insert(_InputIter __first, _InputIter __last)
225         {
226           size_type __old_size = _Base::bucket_count(); 
227           _Base::insert(__first, __last);
228           _M_profile_resize(__old_size); 
229         }
231       // operator[]
232       mapped_type&
233       operator[](const _Key& __k)
234       {
235         size_type __old_size = _Base::bucket_count();
236         mapped_type& __res = _M_base()[__k];
237         _M_profile_resize(__old_size); 
238         return __res;
239       }
241       mapped_type&
242       operator[](_Key&& __k)
243       {
244         size_type __old_size = _Base::bucket_count();
245         mapped_type& __res = _M_base()[std::move(__k)];
246         _M_profile_resize(__old_size); 
247         return __res;
248       }
250       void
251       swap(unordered_map& __x)
252       noexcept( noexcept(__x._M_base().swap(__x)) )
253       { _Base::swap(__x._M_base()); }
255       void rehash(size_type __n)
256       {
257         size_type __old_size = _Base::bucket_count();
258         _Base::rehash(__n);
259         _M_profile_resize(__old_size); 
260       }
262     private:
263       void
264       _M_profile_resize(size_type __old_size)
265       {
266         size_type __new_size = _Base::bucket_count();
267         if (__old_size != __new_size)
268           __profcxx_hashtable_resize(this, __old_size, __new_size);
269       }
270   };
272   template<typename _Key, typename _Tp, typename _Hash,
273            typename _Pred, typename _Alloc>
274     inline void
275     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
276          unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
277     { __x.swap(__y); }
279   template<typename _Key, typename _Tp, typename _Hash,
280            typename _Pred, typename _Alloc>
281     inline bool
282     operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
283                const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
284     { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
286   template<typename _Key, typename _Tp, typename _Hash,
287            typename _Pred, typename _Alloc>
288     inline bool
289     operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
290                const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
291     { return !(__x == __y); }
293 #undef _GLIBCXX_BASE
294 #undef _GLIBCXX_STD_BASE
295 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
296 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
298   /// Class std::unordered_multimap wrapper with performance instrumentation.
299   template<typename _Key, typename _Tp,
300            typename _Hash = std::hash<_Key>,
301            typename _Pred = std::equal_to<_Key>,
302            typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
303     class unordered_multimap
304     : public _GLIBCXX_STD_BASE,
305       public _Unordered_profile<unordered_multimap<_Key, _Tp,
306                                                    _Hash, _Pred, _Alloc>,
307                                 false>
308     {      
309       typedef typename _GLIBCXX_STD_BASE _Base;
311       _Base&
312       _M_base() noexcept       { return *this; }
314       const _Base&
315       _M_base() const noexcept { return *this; }
317     public:
318       typedef typename _Base::size_type       size_type;
319       typedef typename _Base::hasher          hasher;
320       typedef typename _Base::key_equal       key_equal;
321       typedef typename _Base::allocator_type  allocator_type;
322       typedef typename _Base::key_type        key_type;
323       typedef typename _Base::value_type      value_type;
324       typedef typename _Base::difference_type difference_type;
325       typedef typename _Base::reference       reference;
326       typedef typename _Base::const_reference const_reference;
328       typedef typename _Base::iterator iterator;
329       typedef typename _Base::const_iterator const_iterator;
331       explicit
332       unordered_multimap(size_type __n = 10,
333                          const hasher& __hf = hasher(),
334                          const key_equal& __eql = key_equal(),
335                          const allocator_type& __a = allocator_type())
336         : _Base(__n, __hf, __eql, __a)
337       { }
339       template<typename _InputIterator>
340         unordered_multimap(_InputIterator __f, _InputIterator __l,
341                            size_type __n = 0,
342                            const hasher& __hf = hasher(),
343                            const key_equal& __eql = key_equal(),
344                            const allocator_type& __a = allocator_type())
345           : _Base(__f, __l, __n, __hf, __eql, __a)
346       { }
348       unordered_multimap(const unordered_multimap&) = default;
350       unordered_multimap(const _Base& __x)
351         : _Base(__x)
352       { }
354       unordered_multimap(unordered_multimap&&) = default;
356       explicit
357       unordered_multimap(const allocator_type& __a)
358         : _Base(__a)
359       { }
361       unordered_multimap(const unordered_multimap& __ummap,
362                          const allocator_type& __a)
363         : _Base(__ummap._M_base(), __a)
364       { }
366       unordered_multimap(unordered_multimap&& __ummap,
367                          const allocator_type& __a)
368         : _Base(std::move(__ummap._M_base()), __a)
369       { }
371       unordered_multimap(initializer_list<value_type> __l,
372                          size_type __n = 0,
373                          const hasher& __hf = hasher(),
374                          const key_equal& __eql = key_equal(),
375                          const allocator_type& __a = allocator_type())
376       : _Base(__l, __n, __hf, __eql, __a)
377       { }
379       unordered_multimap&
380       operator=(const unordered_multimap&) = default;
382       unordered_multimap&
383       operator=(unordered_multimap&&) = default;
385       unordered_multimap&
386       operator=(initializer_list<value_type> __l)
387       {
388         _M_base() = __l;
389         return *this;
390       }
392       void
393       clear() noexcept
394       {
395         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
396                                      _Base::size());
397         this->_M_profile_destruct();
398         _Base::clear();
399       }
401       template<typename... _Args>
402         iterator
403         emplace(_Args&&... __args)
404         {
405           size_type __old_size = _Base::bucket_count();
406           iterator __res
407             = _Base::emplace(std::forward<_Args>(__args)...);
408           _M_profile_resize(__old_size);
409           return __res;
410         }
412       template<typename... _Args>
413         iterator
414         emplace_hint(const_iterator __it, _Args&&... __args)
415         {
416           size_type __old_size = _Base::bucket_count();
417           iterator __res
418             = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
419           _M_profile_resize(__old_size);
420           return __res;
421         }
423       void
424       insert(std::initializer_list<value_type> __l)
425       { 
426         size_type __old_size = _Base::bucket_count();
427         _Base::insert(__l);
428         _M_profile_resize(__old_size);
429       }
431       iterator
432       insert(const value_type& __obj)
433       {
434         size_type __old_size = _Base::bucket_count();
435         iterator __res = _Base::insert(__obj);
436         _M_profile_resize(__old_size); 
437         return __res;
438       }
440       iterator
441       insert(const_iterator __iter, const value_type& __v)
442       { 
443         size_type __old_size = _Base::bucket_count(); 
444         iterator __res = _Base::insert(__iter, __v);
445         _M_profile_resize(__old_size); 
446         return __res;
447       }
449       template<typename _Pair, typename = typename
450                std::enable_if<std::is_constructible<value_type,
451                                                     _Pair&&>::value>::type>
452         iterator
453         insert(_Pair&& __obj)
454         {
455           size_type __old_size = _Base::bucket_count();
456           iterator __res = _Base::insert(std::forward<_Pair>(__obj));
457           _M_profile_resize(__old_size); 
458           return __res;
459         }
461       template<typename _Pair, typename = typename
462                std::enable_if<std::is_constructible<value_type,
463                                                     _Pair&&>::value>::type>
464         iterator
465         insert(const_iterator __iter, _Pair&& __v)
466         {
467           size_type __old_size = _Base::bucket_count(); 
468           iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
469           _M_profile_resize(__old_size); 
470           return __res;
471         }
473       template<typename _InputIter>
474         void
475         insert(_InputIter __first, _InputIter __last)
476         {
477           size_type __old_size = _Base::bucket_count(); 
478           _Base::insert(__first, __last);
479           _M_profile_resize(__old_size); 
480         }
482       void
483       swap(unordered_multimap& __x)
484       noexcept( noexcept(__x._M_base().swap(__x)) )
485       { _Base::swap(__x._M_base()); }
487       void
488       rehash(size_type __n)
489       {
490         size_type __old_size = _Base::bucket_count();
491         _Base::rehash(__n);
492         _M_profile_resize(__old_size); 
493       }
495     private:
496       void
497       _M_profile_resize(size_type __old_size)
498       {
499         size_type __new_size = _Base::bucket_count();
500         if (__old_size != __new_size)
501           __profcxx_hashtable_resize(this, __old_size, __new_size);
502       }
503   };
505   template<typename _Key, typename _Tp, typename _Hash,
506            typename _Pred, typename _Alloc>
507     inline void
508     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
509          unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
510     { __x.swap(__y); }
512   template<typename _Key, typename _Tp, typename _Hash,
513            typename _Pred, typename _Alloc>
514     inline bool
515     operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
516                const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
517     { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
519   template<typename _Key, typename _Tp, typename _Hash,
520            typename _Pred, typename _Alloc>
521     inline bool
522     operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
523                const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
524     { return !(__x == __y); }
526 } // namespace __profile
527 } // namespace std
529 #undef _GLIBCXX_BASE
530 #undef _GLIBCXX_STD_BASE
532 #endif // C++11
534 #endif