# profile/unordered_set

Go to the documentation of this file.

    00001 // Profiling unordered_set/unordered_multiset implementation -*- C++ -*-
    00002
    00003 // Copyright (C) 2009, 2010 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 2, 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 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file profile/unordered_set
    00031  *  This file is a GNU profile extension to the Standard C++ Library.
    00032  */
    00033
    00034 #ifndef _GLIBCXX_PROFILE_UNORDERED_SET
    00035 #define _GLIBCXX_PROFILE_UNORDERED_SET 1
    00036
    00037 #ifndef __GXX_EXPERIMENTAL_CXX0X__
    00038 # include <bits/c++0x_warning.h>
    00039 #else
    00040 # include <unordered_set>
    00041
    00042 #include <profile/base.h>
    00043
    00044 #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
    00045 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
    00046
    00047 namespace std
    00048 {
    00049 namespace __profile
    00050 {
    00051   /** @brief Unordered_set wrapper with performance instrumentation.  */
    00052   template<typename _Key,
    00053        typename _Hash  = std::hash<_Key>,
    00054        typename _Pred = std::equal_to<_Key>,
    00055        typename _Alloc =  std::allocator<_Key> >
    00056     class unordered_set
    00057     : public _GLIBCXX_STD_BASE
    00058     {
    00059       typedef typename _GLIBCXX_STD_BASE _Base;
    00060
    00061     public:
    00062       typedef typename _Base::size_type       size_type;
    00063       typedef typename _Base::hasher          hasher;
    00064       typedef typename _Base::key_equal       key_equal;
    00065       typedef typename _Base::allocator_type  allocator_type;
    00066       typedef typename _Base::key_type        key_type;
    00067       typedef typename _Base::value_type      value_type;
    00068       typedef typename _Base::difference_type difference_type;
    00069       typedef typename _Base::reference       reference;
    00070       typedef typename _Base::const_reference const_reference;
    00071
    00072       typedef typename _Base::iterator iterator;
    00073       typedef typename _Base::const_iterator const_iterator;
    00074
    00075       explicit
    00076       unordered_set(size_type __n = 10,
    00077             const hasher& __hf = hasher(),
    00078             const key_equal& __eql = key_equal(),
    00079             const allocator_type& __a = allocator_type())
    00080       : _Base(__n, __hf, __eql, __a)
    00081       {
    00082         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00083         __profcxx_hashtable_construct2(this);
    00084       }
    00085
    00086       template<typename _InputIterator>
    00087         unordered_set(_InputIterator __f, _InputIterator __l,
    00088               size_type __n = 10,
    00089               const hasher& __hf = hasher(),
    00090               const key_equal& __eql = key_equal(),
    00091               const allocator_type& __a = allocator_type())
    00092       : _Base(__f, __l, __n, __hf, __eql, __a)
    00093       {
    00094         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00095         __profcxx_hashtable_construct2(this);
    00096       }
    00097
    00098       unordered_set(const _Base& __x)
    00099       : _Base(__x)
    00100       {
    00101         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00102         __profcxx_hashtable_construct2(this);
    00103       }
    00104
    00105       unordered_set(unordered_set&& __x)
    00106       : _Base(std::forward<_Base>(__x))
    00107       {
    00108         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00109         __profcxx_hashtable_construct2(this);
    00110       }
    00111
    00112       unordered_set(initializer_list<value_type> __l,
    00113             size_type __n = 10,
    00114             const hasher& __hf = hasher(),
    00115             const key_equal& __eql = key_equal(),
    00116             const allocator_type& __a = allocator_type())
    00117       : _Base(__l, __n, __hf, __eql, __a) { }
    00118
    00119       unordered_set&
    00120       operator=(const unordered_set& __x)
    00121       {
    00122     *static_cast<_Base*>(this) = __x;
    00123     return *this;
    00124       }
    00125
    00126       unordered_set&
    00127       operator=(unordered_set&& __x)
    00128       {
    00129     // NB: DR 1204.
    00130     // NB: DR 675.
    00131     this->clear();
    00132     this->swap(__x);
    00133     return *this;
    00134       }
    00135
    00136       unordered_set&
    00137       operator=(initializer_list<value_type> __l)
    00138       {
    00139     this->clear();
    00140     this->insert(__l);
    00141     return *this;
    00142       }
    00143
    00144       ~unordered_set()
    00145       {
    00146         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
    00147                                      _Base::size());
    00148         _M_profile_destruct();
    00149       }
    00150
    00151       void
    00152       swap(unordered_set& __x)
    00153       {
    00154         _Base::swap(__x);
    00155       }
    00156
    00157       void
    00158       clear()
    00159       {
    00160         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
    00161                                      _Base::size());
    00162         _M_profile_destruct();
    00163         _Base::clear();
    00164       }
    00165
    00166       void
    00167       insert(std::initializer_list<value_type> __l)
    00168       {
    00169         size_type __old_size =  _Base::bucket_count();
    00170         _Base::insert(__l);
    00171         _M_profile_resize(__old_size,  _Base::bucket_count());
    00172       }
    00173
    00174       std::pair<iterator, bool>
    00175       insert(const value_type& __obj)
    00176       {
    00177         size_type __old_size =  _Base::bucket_count();
    00178         std::pair<iterator, bool> __res = _Base::insert(__obj);
    00179         _M_profile_resize(__old_size,  _Base::bucket_count());
    00180         return __res;
    00181       }
    00182
    00183       iterator
    00184       insert(const_iterator __iter, const value_type& __v)
    00185       {
    00186         size_type __old_size = _Base::bucket_count();
    00187         iterator __res = _Base::insert(__iter, __v);
    00188         _M_profile_resize(__old_size, _Base::bucket_count());
    00189         return __res;
    00190       }
    00191
    00192       template<typename _InputIter>
    00193         void
    00194         insert(_InputIter __first, _InputIter __last)
    00195         {
    00196       size_type __old_size = _Base::bucket_count();
    00197       _Base::insert(__first, __last);
    00198       _M_profile_resize(__old_size,  _Base::bucket_count());
    00199     }
    00200
    00201       void
    00202       insert(const value_type* __first, const value_type* __last)
    00203       {
    00204         size_type __old_size = _Base::bucket_count();
    00205         _Base::insert(__first, __last);
    00206         _M_profile_resize(__old_size,  _Base::bucket_count());
    00207       }
    00208
    00209       void rehash(size_type __n)
    00210       {
    00211         size_type __old_size =  _Base::bucket_count();
    00212         _Base::rehash(__n);
    00213         _M_profile_resize(__old_size,  _Base::bucket_count());
    00214       }
    00215
    00216     private:
    00217       _Base&
    00218       _M_base()       { return *this; }
    00219
    00220       const _Base&
    00221       _M_base() const { return *this; }
    00222
    00223       void
    00224       _M_profile_resize(size_type __old_size, size_type __new_size)
    00225       {
    00226         if (__old_size != __new_size)
    00227       __profcxx_hashtable_resize(this, __old_size, __new_size);
    00228       }
    00229
    00230       void
    00231       _M_profile_destruct()
    00232       {
    00233         size_type __hops = 0, __lc = 0, __chain = 0;
    00234         for (iterator __it = _M_base().begin(); __it != _M_base().end();
    00235          ++__it)
    00236         {
    00237           while (__it._M_cur_node->_M_next)
    00238         {
    00239           ++__chain;
    00240           ++__it;
    00241         }
    00242
    00243           if (__chain)
    00244         {
    00245           ++__chain;
    00246           __lc = __lc > __chain ? __lc : __chain;
    00247           __hops += __chain * (__chain - 1) / 2;
    00248           __chain = 0;
    00249         }
    00250         }
    00251         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
    00252       }
    00253
    00254    };
    00255
    00256   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    00257     inline void
    00258     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
    00259      unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
    00260     { __x.swap(__y); }
    00261
    00262   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    00263     inline bool
    00264     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
    00265            const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
    00266     { return __x._M_equal(__y); }
    00267
    00268   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    00269     inline bool
    00270     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
    00271            const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
    00272     { return !(__x == __y); }
    00273
    00274 #undef _GLIBCXX_BASE
    00275 #undef _GLIBCXX_STD_BASE
    00276 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
    00277 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
    00278
    00279   /** @brief Unordered_multiset wrapper with performance instrumentation.  */
    00280   template<typename _Value,
    00281        typename _Hash  = std::hash<_Value>,
    00282        typename _Pred = std::equal_to<_Value>,
    00283        typename _Alloc =  std::allocator<_Value> >
    00284     class unordered_multiset
    00285     : public _GLIBCXX_STD_BASE
    00286     {
    00287       typedef typename _GLIBCXX_STD_BASE _Base;
    00288
    00289     public:
    00290       typedef typename _Base::size_type       size_type;
    00291       typedef typename _Base::hasher          hasher;
    00292       typedef typename _Base::key_equal       key_equal;
    00293       typedef typename _Base::allocator_type  allocator_type;
    00294       typedef typename _Base::key_type        key_type;
    00295       typedef typename _Base::value_type      value_type;
    00296       typedef typename _Base::difference_type difference_type;
    00297       typedef typename _Base::reference       reference;
    00298       typedef typename _Base::const_reference const_reference;
    00299
    00300       typedef typename _Base::iterator iterator;
    00301       typedef typename _Base::const_iterator const_iterator;
    00302
    00303       explicit
    00304       unordered_multiset(size_type __n = 10,
    00305             const hasher& __hf = hasher(),
    00306             const key_equal& __eql = key_equal(),
    00307             const allocator_type& __a = allocator_type())
    00308       : _Base(__n, __hf, __eql, __a)
    00309       {
    00310         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00311       }
    00312
    00313       template<typename _InputIterator>
    00314         unordered_multiset(_InputIterator __f, _InputIterator __l,
    00315               size_type __n = 10,
    00316               const hasher& __hf = hasher(),
    00317               const key_equal& __eql = key_equal(),
    00318               const allocator_type& __a = allocator_type())
    00319       : _Base(__f, __l, __n, __hf, __eql, __a)
    00320       {
    00321         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00322       }
    00323
    00324       unordered_multiset(const _Base& __x)
    00325       : _Base(__x)
    00326       {
    00327         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00328       }
    00329
    00330       unordered_multiset(unordered_multiset&& __x)
    00331       : _Base(std::forward<_Base>(__x))
    00332       {
    00333         __profcxx_hashtable_construct(this, _Base::bucket_count());
    00334       }
    00335
    00336       unordered_multiset(initializer_list<value_type> __l,
    00337              size_type __n = 10,
    00338              const hasher& __hf = hasher(),
    00339              const key_equal& __eql = key_equal(),
    00340              const allocator_type& __a = allocator_type())
    00341       : _Base(__l, __n, __hf, __eql, __a) { }
    00342
    00343       unordered_multiset&
    00344       operator=(const unordered_multiset& __x)
    00345       {
    00346     *static_cast<_Base*>(this) = __x;
    00347     return *this;
    00348       }
    00349
    00350       unordered_multiset&
    00351       operator=(unordered_multiset&& __x)
    00352       {
    00353     // NB: DR 1204.
    00354     // NB: DR 675.
    00355     this->clear();
    00356     this->swap(__x);
    00357     return *this;
    00358       }
    00359
    00360       unordered_multiset&
    00361       operator=(initializer_list<value_type> __l)
    00362       {
    00363     this->clear();
    00364     this->insert(__l);
    00365     return *this;
    00366       }
    00367
    00368       ~unordered_multiset()
    00369       {
    00370         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
    00371                                      _Base::size());
    00372         _M_profile_destruct();
    00373       }
    00374
    00375       void
    00376       swap(unordered_multiset& __x)
    00377       {
    00378         _Base::swap(__x);
    00379       }
    00380
    00381       void
    00382       clear()
    00383       {
    00384         __profcxx_hashtable_destruct(this, _Base::bucket_count(),
    00385                                      _Base::size());
    00386         _M_profile_destruct();
    00387         _Base::clear();
    00388       }
    00389
    00390       void
    00391       insert(std::initializer_list<value_type> __l)
    00392       {
    00393         size_type __old_size =  _Base::bucket_count();
    00394         _Base::insert(__l);
    00395         _M_profile_resize(__old_size,  _Base::bucket_count());
    00396       }
    00397
    00398       iterator
    00399       insert(const value_type& __obj)
    00400       {
    00401         size_type __old_size =  _Base::bucket_count();
    00402         iterator __res = _Base::insert(__obj);
    00403         _M_profile_resize(__old_size,  _Base::bucket_count());
    00404         return __res;
    00405       }
    00406
    00407       iterator
    00408       insert(const_iterator __iter, const value_type& __v)
    00409       {
    00410         size_type __old_size = _Base::bucket_count();
    00411         iterator __res = _Base::insert(__iter, __v);
    00412         _M_profile_resize(__old_size, _Base::bucket_count());
    00413         return __res;
    00414       }
    00415
    00416       template<typename _InputIter>
    00417         void
    00418         insert(_InputIter __first, _InputIter __last)
    00419         {
    00420       size_type __old_size = _Base::bucket_count();
    00421       _Base::insert(__first, __last);
    00422       _M_profile_resize(__old_size,  _Base::bucket_count());
    00423     }
    00424
    00425       void
    00426       insert(const value_type* __first, const value_type* __last)
    00427       {
    00428         size_type __old_size = _Base::bucket_count();
    00429         _Base::insert(__first, __last);
    00430         _M_profile_resize(__old_size,  _Base::bucket_count());
    00431       }
    00432
    00433       void rehash(size_type __n)
    00434       {
    00435         size_type __old_size =  _Base::bucket_count();
    00436         _Base::rehash(__n);
    00437         _M_profile_resize(__old_size,  _Base::bucket_count());
    00438       }
    00439
    00440     private:
    00441       _Base&
    00442       _M_base()       { return *this; }
    00443
    00444       const _Base&
    00445       _M_base() const { return *this; }
    00446
    00447       void
    00448       _M_profile_resize(size_type __old_size, size_type __new_size)
    00449       {
    00450         if (__old_size != __new_size)
    00451           __profcxx_hashtable_resize(this, __old_size, __new_size);
    00452       }
    00453
    00454       void
    00455       _M_profile_destruct()
    00456       {
    00457         size_type __hops = 0, __lc = 0, __chain = 0;
    00458         for (iterator __it = _M_base().begin(); __it != _M_base().end();
    00459          ++__it)
    00460         {
    00461           while (__it._M_cur_node->_M_next)
    00462         {
    00463              ++__chain;
    00464              ++__it;
    00465         }
    00466
    00467           if (__chain)
    00468         {
    00469           ++__chain;
    00470           __lc = __lc > __chain ? __lc : __chain;
    00471           __hops += __chain * (__chain - 1) / 2;
    00472           __chain = 0;
    00473         }
    00474         }
    00475         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
    00476       }
    00477
    00478    };
    00479
    00480   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    00481     inline void
    00482     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
    00483      unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
    00484     { __x.swap(__y); }
    00485
    00486   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    00487     inline bool
    00488     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
    00489            const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
    00490     { return __x._M_equal(__y); }
    00491
    00492   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
    00493     inline bool
    00494     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
    00495            const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
    00496     { return !(__x == __y); }
    00497
    00498 } // namespace __profile
    00499 } // namespace std
    00500
    00501 #undef _GLIBCXX_BASE
    00502 #undef _GLIBCXX_STD_BASE
    00503
    00504 #endif // __GXX_EXPERIMENTAL_CXX0X__
    00505
    00506 #endif