libstdc++

unordered_map

Go to the documentation of this file.
00001 // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2009-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License along
00021 // with this library; see the file COPYING3.  If not see
00022 // <http://www.gnu.org/licenses/>.
00023 
00024 /** @file profile/unordered_map
00025  *  This file is a GNU profile extension to the Standard C++ Library.
00026  */
00027 
00028 #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
00029 #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
00030 
00031 #if __cplusplus < 201103L
00032 # include <bits/c++0x_warning.h>
00033 #else
00034 # include <unordered_map>
00035 
00036 #include <profile/base.h>
00037 #include <profile/unordered_base.h>
00038 
00039 #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
00040 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
00041 
00042 namespace std _GLIBCXX_VISIBILITY(default)
00043 {
00044 namespace __profile
00045 {
00046   /// Class std::unordered_map wrapper with performance instrumentation.
00047   template<typename _Key, typename _Tp,
00048            typename _Hash = std::hash<_Key>,
00049            typename _Pred = std::equal_to<_Key>,
00050            typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
00051     class unordered_map
00052     : public _GLIBCXX_STD_BASE,
00053       public _Unordered_profile<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
00054                                 true>
00055     {
00056       typedef typename _GLIBCXX_STD_BASE _Base;
00057 
00058       _Base&
00059       _M_base() noexcept        { return *this; }
00060 
00061       const _Base&
00062       _M_base() const noexcept  { return *this; }
00063 
00064     public:
00065       typedef typename _Base::size_type         size_type;
00066       typedef typename _Base::hasher            hasher;
00067       typedef typename _Base::key_equal         key_equal;
00068       typedef typename _Base::allocator_type    allocator_type;
00069       typedef typename _Base::key_type          key_type;
00070       typedef typename _Base::value_type        value_type;
00071       typedef typename _Base::difference_type   difference_type;
00072       typedef typename _Base::reference         reference;
00073       typedef typename _Base::const_reference   const_reference;
00074       typedef typename _Base::mapped_type       mapped_type;
00075 
00076       typedef typename _Base::iterator          iterator;
00077       typedef typename _Base::const_iterator    const_iterator;
00078 
00079       unordered_map() = default;
00080 
00081       explicit
00082       unordered_map(size_type __n,
00083                     const hasher& __hf = hasher(),
00084                     const key_equal& __eql = key_equal(),
00085                     const allocator_type& __a = allocator_type())
00086       : _Base(__n, __hf, __eql, __a) { }
00087 
00088       template<typename _InputIterator>
00089         unordered_map(_InputIterator __f, _InputIterator __l,
00090                       size_type __n = 0,
00091                       const hasher& __hf = hasher(),
00092                       const key_equal& __eql = key_equal(),
00093                       const allocator_type& __a = allocator_type())
00094         : _Base(__f, __l, __n, __hf, __eql, __a) { }
00095 
00096       unordered_map(const unordered_map&) = default;
00097 
00098       unordered_map(const _Base& __x)
00099       : _Base(__x) { }
00100 
00101       unordered_map(unordered_map&&) = default;
00102 
00103       explicit
00104       unordered_map(const allocator_type& __a)
00105       : _Base(__a) { }
00106 
00107       unordered_map(const unordered_map& __umap,
00108                     const allocator_type& __a)
00109       : _Base(__umap, __a) { }
00110 
00111       unordered_map(unordered_map&& __umap,
00112                     const allocator_type& __a)
00113       : _Base(std::move(__umap._M_base()), __a) { }
00114 
00115       unordered_map(initializer_list<value_type> __l,
00116                     size_type __n = 0,
00117                     const hasher& __hf = hasher(),
00118                     const key_equal& __eql = key_equal(),
00119                     const allocator_type& __a = allocator_type())
00120       : _Base(__l, __n, __hf, __eql, __a) { }
00121 
00122       unordered_map&
00123       operator=(const unordered_map&) = default;
00124 
00125       unordered_map&
00126       operator=(unordered_map&&) = default;
00127 
00128       unordered_map&
00129       operator=(initializer_list<value_type> __l)
00130       {
00131         this->_M_profile_destruct();
00132         _M_base() = __l;
00133         this->_M_profile_construct();
00134         return *this;
00135       }
00136 
00137       void
00138       clear() noexcept
00139       {
00140         this->_M_profile_destruct();
00141         _Base::clear();
00142         this->_M_profile_construct();
00143       }
00144 
00145       template<typename... _Args>
00146         std::pair<iterator, bool>
00147         emplace(_Args&&... __args)
00148         {
00149           size_type __old_size = _Base::bucket_count();
00150           std::pair<iterator, bool> __res
00151             = _Base::emplace(std::forward<_Args>(__args)...);
00152           this->_M_profile_resize(__old_size);
00153           return __res;
00154         }
00155 
00156       template<typename... _Args>
00157         iterator
00158         emplace_hint(const_iterator __it, _Args&&... __args)
00159         {
00160           size_type __old_size = _Base::bucket_count();
00161           iterator __res
00162             = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
00163           this->_M_profile_resize(__old_size);
00164           return __res;
00165         }
00166 
00167       void
00168       insert(std::initializer_list<value_type> __l)
00169       {
00170         size_type __old_size = _Base::bucket_count();
00171         _Base::insert(__l);
00172         this->_M_profile_resize(__old_size);
00173       }
00174 
00175       std::pair<iterator, bool>
00176       insert(const value_type& __obj)
00177       {
00178         size_type __old_size = _Base::bucket_count();
00179         std::pair<iterator, bool> __res = _Base::insert(__obj);
00180         this->_M_profile_resize(__old_size);
00181         return __res;
00182       }
00183 
00184       iterator
00185       insert(const_iterator __iter, const value_type& __v)
00186       {
00187         size_type __old_size = _Base::bucket_count();
00188         iterator __res = _Base::insert(__iter, __v);
00189         this->_M_profile_resize(__old_size);
00190         return __res;
00191       }
00192 
00193       template<typename _Pair, typename = typename
00194                std::enable_if<std::is_constructible<value_type,
00195                                                     _Pair&&>::value>::type>
00196         std::pair<iterator, bool>
00197         insert(_Pair&& __obj)
00198         {
00199           size_type __old_size = _Base::bucket_count();
00200           std::pair<iterator, bool> __res
00201             = _Base::insert(std::forward<_Pair>(__obj));
00202           this->_M_profile_resize(__old_size);
00203           return __res;
00204         }
00205 
00206       template<typename _Pair, typename = typename
00207                std::enable_if<std::is_constructible<value_type,
00208                                                     _Pair&&>::value>::type>
00209         iterator
00210         insert(const_iterator __iter, _Pair&& __v)
00211         {
00212           size_type __old_size = _Base::bucket_count();
00213           iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
00214           this->_M_profile_resize(__old_size);
00215           return __res;
00216         }
00217 
00218       template<typename _InputIter>
00219         void
00220         insert(_InputIter __first, _InputIter __last)
00221         {
00222           size_type __old_size = _Base::bucket_count();
00223           _Base::insert(__first, __last);
00224           this->_M_profile_resize(__old_size);
00225         }
00226 
00227       // operator[]
00228       mapped_type&
00229       operator[](const _Key& __k)
00230       {
00231         size_type __old_size = _Base::bucket_count();
00232         mapped_type& __res = _M_base()[__k];
00233         this->_M_profile_resize(__old_size);
00234         return __res;
00235       }
00236 
00237       mapped_type&
00238       operator[](_Key&& __k)
00239       {
00240         size_type __old_size = _Base::bucket_count();
00241         mapped_type& __res = _M_base()[std::move(__k)];
00242         this->_M_profile_resize(__old_size);
00243         return __res;
00244       }
00245 
00246       void
00247       swap(unordered_map& __x)
00248       noexcept( noexcept(__x._M_base().swap(__x)) )
00249       {
00250         _Base::swap(__x._M_base());
00251         this->_M_swap(__x);
00252       }
00253 
00254       void rehash(size_type __n)
00255       {
00256         size_type __old_size = _Base::bucket_count();
00257         _Base::rehash(__n);
00258         this->_M_profile_resize(__old_size);
00259       }
00260   };
00261 
00262   template<typename _Key, typename _Tp, typename _Hash,
00263            typename _Pred, typename _Alloc>
00264     inline void
00265     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00266          unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00267     { __x.swap(__y); }
00268 
00269   template<typename _Key, typename _Tp, typename _Hash,
00270            typename _Pred, typename _Alloc>
00271     inline bool
00272     operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00273                const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00274     { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
00275 
00276   template<typename _Key, typename _Tp, typename _Hash,
00277            typename _Pred, typename _Alloc>
00278     inline bool
00279     operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00280                const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00281     { return !(__x == __y); }
00282 
00283 #undef _GLIBCXX_BASE
00284 #undef _GLIBCXX_STD_BASE
00285 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
00286 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
00287 
00288   /// Class std::unordered_multimap wrapper with performance instrumentation.
00289   template<typename _Key, typename _Tp,
00290            typename _Hash = std::hash<_Key>,
00291            typename _Pred = std::equal_to<_Key>,
00292            typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
00293     class unordered_multimap
00294     : public _GLIBCXX_STD_BASE,
00295       public _Unordered_profile<unordered_multimap<_Key, _Tp,
00296                                                    _Hash, _Pred, _Alloc>,
00297                                 false>
00298     {
00299       typedef typename _GLIBCXX_STD_BASE _Base;
00300 
00301       _Base&
00302       _M_base() noexcept        { return *this; }
00303 
00304       const _Base&
00305       _M_base() const noexcept  { return *this; }
00306 
00307     public:
00308       typedef typename _Base::size_type         size_type;
00309       typedef typename _Base::hasher            hasher;
00310       typedef typename _Base::key_equal         key_equal;
00311       typedef typename _Base::allocator_type    allocator_type;
00312       typedef typename _Base::key_type          key_type;
00313       typedef typename _Base::value_type        value_type;
00314       typedef typename _Base::difference_type   difference_type;
00315       typedef typename _Base::reference         reference;
00316       typedef typename _Base::const_reference   const_reference;
00317 
00318       typedef typename _Base::iterator          iterator;
00319       typedef typename _Base::const_iterator    const_iterator;
00320 
00321       unordered_multimap() = default;
00322 
00323       explicit
00324       unordered_multimap(size_type __n,
00325                          const hasher& __hf = hasher(),
00326                          const key_equal& __eql = key_equal(),
00327                          const allocator_type& __a = allocator_type())
00328       : _Base(__n, __hf, __eql, __a) { }
00329 
00330       template<typename _InputIterator>
00331         unordered_multimap(_InputIterator __f, _InputIterator __l,
00332                            size_type __n = 0,
00333                            const hasher& __hf = hasher(),
00334                            const key_equal& __eql = key_equal(),
00335                            const allocator_type& __a = allocator_type())
00336         : _Base(__f, __l, __n, __hf, __eql, __a) { }
00337 
00338       unordered_multimap(const unordered_multimap&) = default;
00339 
00340       unordered_multimap(const _Base& __x)
00341       : _Base(__x) { }
00342 
00343       unordered_multimap(unordered_multimap&&) = default;
00344 
00345       explicit
00346       unordered_multimap(const allocator_type& __a)
00347       : _Base(__a) { }
00348 
00349       unordered_multimap(const unordered_multimap& __ummap,
00350                          const allocator_type& __a)
00351       : _Base(__ummap._M_base(), __a) { }
00352 
00353       unordered_multimap(unordered_multimap&& __ummap,
00354                          const allocator_type& __a)
00355       : _Base(std::move(__ummap._M_base()), __a) { }
00356 
00357       unordered_multimap(initializer_list<value_type> __l,
00358                          size_type __n = 0,
00359                          const hasher& __hf = hasher(),
00360                          const key_equal& __eql = key_equal(),
00361                          const allocator_type& __a = allocator_type())
00362       : _Base(__l, __n, __hf, __eql, __a) { }
00363 
00364       unordered_multimap&
00365       operator=(const unordered_multimap&) = default;
00366 
00367       unordered_multimap&
00368       operator=(unordered_multimap&&) = default;
00369 
00370       unordered_multimap&
00371       operator=(initializer_list<value_type> __l)
00372       {
00373         this->_M_profile_destruct();
00374         _M_base() = __l;
00375         this->_M_profile_construct();
00376         return *this;
00377       }
00378 
00379       void
00380       clear() noexcept
00381       {
00382         this->_M_profile_destruct();
00383         _Base::clear();
00384         this->_M_profile_construct();
00385       }
00386 
00387       template<typename... _Args>
00388         iterator
00389         emplace(_Args&&... __args)
00390         {
00391           size_type __old_size = _Base::bucket_count();
00392           iterator __res
00393             = _Base::emplace(std::forward<_Args>(__args)...);
00394           this->_M_profile_resize(__old_size);
00395           return __res;
00396         }
00397 
00398       template<typename... _Args>
00399         iterator
00400         emplace_hint(const_iterator __it, _Args&&... __args)
00401         {
00402           size_type __old_size = _Base::bucket_count();
00403           iterator __res
00404             = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
00405           this->_M_profile_resize(__old_size);
00406           return __res;
00407         }
00408 
00409       void
00410       insert(std::initializer_list<value_type> __l)
00411       {
00412         size_type __old_size = _Base::bucket_count();
00413         _Base::insert(__l);
00414         this->_M_profile_resize(__old_size);
00415       }
00416 
00417       iterator
00418       insert(const value_type& __obj)
00419       {
00420         size_type __old_size = _Base::bucket_count();
00421         iterator __res = _Base::insert(__obj);
00422         this->_M_profile_resize(__old_size);
00423         return __res;
00424       }
00425 
00426       iterator
00427       insert(const_iterator __iter, const value_type& __v)
00428       {
00429         size_type __old_size = _Base::bucket_count();
00430         iterator __res = _Base::insert(__iter, __v);
00431         this->_M_profile_resize(__old_size);
00432         return __res;
00433       }
00434 
00435       template<typename _Pair, typename = typename
00436                std::enable_if<std::is_constructible<value_type,
00437                                                     _Pair&&>::value>::type>
00438         iterator
00439         insert(_Pair&& __obj)
00440         {
00441           size_type __old_size = _Base::bucket_count();
00442           iterator __res = _Base::insert(std::forward<_Pair>(__obj));
00443           this->_M_profile_resize(__old_size);
00444           return __res;
00445         }
00446 
00447       template<typename _Pair, typename = typename
00448                std::enable_if<std::is_constructible<value_type,
00449                                                     _Pair&&>::value>::type>
00450         iterator
00451         insert(const_iterator __iter, _Pair&& __v)
00452         {
00453           size_type __old_size = _Base::bucket_count();
00454           iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
00455           this->_M_profile_resize(__old_size);
00456           return __res;
00457         }
00458 
00459       template<typename _InputIter>
00460         void
00461         insert(_InputIter __first, _InputIter __last)
00462         {
00463           size_type __old_size = _Base::bucket_count();
00464           _Base::insert(__first, __last);
00465           this->_M_profile_resize(__old_size);
00466         }
00467 
00468       void
00469       swap(unordered_multimap& __x)
00470       noexcept( noexcept(__x._M_base().swap(__x)) )
00471       {
00472         _Base::swap(__x._M_base());
00473         this->_M_swap(__x);
00474       }
00475 
00476       void
00477       rehash(size_type __n)
00478       {
00479         size_type __old_size = _Base::bucket_count();
00480         _Base::rehash(__n);
00481         this->_M_profile_resize(__old_size);
00482       }
00483   };
00484 
00485   template<typename _Key, typename _Tp, typename _Hash,
00486            typename _Pred, typename _Alloc>
00487     inline void
00488     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00489          unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00490     { __x.swap(__y); }
00491 
00492   template<typename _Key, typename _Tp, typename _Hash,
00493            typename _Pred, typename _Alloc>
00494     inline bool
00495     operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00496                const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00497     { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
00498 
00499   template<typename _Key, typename _Tp, typename _Hash,
00500            typename _Pred, typename _Alloc>
00501     inline bool
00502     operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00503                const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00504     { return !(__x == __y); }
00505 
00506 } // namespace __profile
00507 } // namespace std
00508 
00509 #undef _GLIBCXX_BASE
00510 #undef _GLIBCXX_STD_BASE
00511 
00512 #endif // C++11
00513 
00514 #endif