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 #include <profile/base.h>
00038 
00039 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00040 # include <unordered_set>
00041 #else
00042 # include <c++0x_warning.h>
00043 #endif
00044 
00045 #include <initializer_list>
00046 
00047 #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
00048 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00049 
00050 namespace std
00051 {
00052 namespace __profile
00053 {
00054   /** @brief Unordered_set wrapper with performance instrumentation.  */
00055   template<typename _Key, 
00056        typename _Hash  = std::hash<_Key>,
00057        typename _Pred = std::equal_to<_Key>,
00058        typename _Alloc =  std::allocator<_Key> >
00059     class unordered_set
00060     : public _GLIBCXX_STD_BASE
00061     {
00062       typedef typename _GLIBCXX_STD_BASE _Base;
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 
00075       typedef typename _Base::iterator iterator;
00076       typedef typename _Base::const_iterator const_iterator;
00077 
00078       explicit
00079       unordered_set(size_type __n = 10,
00080             const hasher& __hf = hasher(),
00081             const key_equal& __eql = key_equal(),
00082             const allocator_type& __a = allocator_type())
00083       : _Base(__n, __hf, __eql, __a)
00084       {
00085         __profcxx_hashtable_construct(this, _Base::bucket_count());
00086         __profcxx_hashtable_construct2(this);
00087       }
00088 
00089       template<typename _InputIterator>
00090         unordered_set(_InputIterator __f, _InputIterator __l,
00091               size_type __n = 10,
00092               const hasher& __hf = hasher(),
00093               const key_equal& __eql = key_equal(),
00094               const allocator_type& __a = allocator_type())
00095       : _Base(__f, __l, __n, __hf, __eql, __a)
00096       {
00097         __profcxx_hashtable_construct(this, _Base::bucket_count());
00098         __profcxx_hashtable_construct2(this);
00099       }
00100 
00101       unordered_set(const _Base& __x)
00102       : _Base(__x) 
00103       { 
00104         __profcxx_hashtable_construct(this, _Base::bucket_count());
00105         __profcxx_hashtable_construct2(this);
00106       }
00107 
00108       unordered_set(unordered_set&& __x)
00109       : _Base(std::forward<_Base>(__x)) 
00110       { 
00111         __profcxx_hashtable_construct(this, _Base::bucket_count());
00112         __profcxx_hashtable_construct2(this);
00113       }
00114 
00115       unordered_set(initializer_list<value_type> __l,
00116             size_type __n = 10,
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_set&
00123       operator=(const unordered_set& __x)
00124       {
00125     *static_cast<_Base*>(this) = __x;
00126     return *this;
00127       }
00128 
00129       unordered_set&
00130       operator=(unordered_set&& __x)
00131       {
00132     // NB: DR 1204.
00133     // NB: DR 675.
00134     this->clear();
00135     this->swap(__x);
00136     return *this;
00137       }
00138 
00139       unordered_set&
00140       operator=(initializer_list<value_type> __l)
00141       {
00142     this->clear();
00143     this->insert(__l);
00144     return *this;
00145       }
00146 
00147       ~unordered_set()
00148       {
00149         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00150                                      _Base::size());
00151         _M_profile_destruct();
00152       }
00153 
00154       void
00155       swap(unordered_set& __x)
00156       {
00157         _Base::swap(__x);
00158       }
00159 
00160       void
00161       clear()
00162       {
00163         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00164                                      _Base::size());
00165         _M_profile_destruct();
00166         _Base::clear();
00167       }
00168 
00169       void
00170       insert(std::initializer_list<value_type> __l)
00171       { 
00172         size_type __old_size =  _Base::bucket_count();
00173         _Base::insert(__l); 
00174         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00175       }
00176 
00177       std::pair<iterator, bool>
00178       insert(const value_type& __obj)
00179       {
00180         size_type __old_size =  _Base::bucket_count();
00181         std::pair<iterator, bool> __res = _Base::insert(__obj);
00182         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00183         return __res;
00184       }
00185 
00186       iterator
00187       insert(iterator __iter, const value_type& __v)
00188       { 
00189         size_type __old_size = _Base::bucket_count(); 
00190         iterator res = _Base::insert(__iter, __v);
00191         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00192         return res;
00193       }
00194 
00195       const_iterator
00196       insert(const_iterator __iter, const value_type& __v)
00197       { 
00198         size_type __old_size = _Base::bucket_count(); 
00199         const_iterator res =_Base::insert(__iter, __v);
00200         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00201         return res;
00202       }
00203 
00204       template<typename _InputIter>
00205       void
00206       insert(_InputIter __first, _InputIter __last)
00207       {
00208         size_type __old_size = _Base::bucket_count(); 
00209         _Base::insert(__first, __last);
00210         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00211       }
00212 
00213       void
00214       insert(const value_type* __first, const value_type* __last)
00215       {
00216         size_type __old_size = _Base::bucket_count(); 
00217         _Base::insert(__first, __last);
00218         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00219       }
00220      
00221       void rehash(size_type __n)
00222       {
00223         size_type __old_size =  _Base::bucket_count();
00224         _Base::rehash(__n);
00225         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00226       }
00227 
00228     private:
00229       _Base&
00230       _M_base()       { return *this; }
00231 
00232       const _Base&
00233       _M_base() const { return *this; }
00234 
00235       void _M_profile_resize(size_type __old_size, size_type __new_size)
00236       {
00237         if (__old_size != __new_size)
00238         {
00239           __profcxx_hashtable_resize(this, __old_size, __new_size);
00240         }
00241       }
00242       void _M_profile_destruct()
00243       {
00244         size_type __hops = 0, __lc = 0, __chain = 0;
00245         for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
00246         {
00247           while (it._M_cur_node->_M_next) {
00248              __chain++;
00249              it++;
00250           }
00251           if (__chain) {
00252             __chain++;
00253             __lc = __lc > __chain ? __lc : __chain;
00254             __hops += __chain * (__chain - 1) / 2;
00255             __chain = 0;
00256           }
00257         }
00258         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
00259       }
00260 
00261    };
00262   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00263     inline void
00264     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00265      unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00266     { __x.swap(__y); }
00267 
00268 #undef _GLIBCXX_BASE
00269 #undef _GLIBCXX_STD_BASE
00270 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00271 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
00272 
00273   /** @brief Unordered_multiset wrapper with performance instrumentation.  */
00274   template<typename _Value,
00275        typename _Hash  = std::hash<_Value>,
00276        typename _Pred = std::equal_to<_Value>,
00277        typename _Alloc =  std::allocator<_Value> >
00278     class unordered_multiset
00279     : public _GLIBCXX_STD_BASE
00280     {
00281       typedef typename _GLIBCXX_STD_BASE _Base;
00282 
00283     public:
00284       typedef typename _Base::size_type       size_type;
00285       typedef typename _Base::hasher          hasher;
00286       typedef typename _Base::key_equal       key_equal;
00287       typedef typename _Base::allocator_type  allocator_type;
00288       typedef typename _Base::key_type        key_type;
00289       typedef typename _Base::value_type      value_type;
00290       typedef typename _Base::difference_type difference_type;
00291       typedef typename _Base::reference       reference;
00292       typedef typename _Base::const_reference const_reference;
00293 
00294       typedef typename _Base::iterator iterator;
00295       typedef typename _Base::const_iterator const_iterator;
00296 
00297       explicit
00298       unordered_multiset(size_type __n = 10,
00299             const hasher& __hf = hasher(),
00300             const key_equal& __eql = key_equal(),
00301             const allocator_type& __a = allocator_type())
00302       : _Base(__n, __hf, __eql, __a)
00303       {
00304         __profcxx_hashtable_construct(this, _Base::bucket_count());
00305       }
00306 
00307       template<typename _InputIterator>
00308         unordered_multiset(_InputIterator __f, _InputIterator __l,
00309               size_type __n = 10,
00310               const hasher& __hf = hasher(),
00311               const key_equal& __eql = key_equal(),
00312               const allocator_type& __a = allocator_type())
00313       : _Base(__f, __l, __n, __hf, __eql, __a)
00314       {
00315         __profcxx_hashtable_construct(this, _Base::bucket_count());
00316       }
00317 
00318       unordered_multiset(const _Base& __x)
00319       : _Base(__x)
00320       {
00321         __profcxx_hashtable_construct(this, _Base::bucket_count());
00322       }
00323 
00324       unordered_multiset(unordered_multiset&& __x)
00325       : _Base(std::forward<_Base>(__x))
00326       {
00327         __profcxx_hashtable_construct(this, _Base::bucket_count());
00328       }
00329 
00330       unordered_multiset(initializer_list<value_type> __l,
00331              size_type __n = 10,
00332              const hasher& __hf = hasher(),
00333              const key_equal& __eql = key_equal(),
00334              const allocator_type& __a = allocator_type())
00335       : _Base(__l, __n, __hf, __eql, __a) { }
00336 
00337       unordered_multiset&
00338       operator=(const unordered_multiset& __x)
00339       {
00340     *static_cast<_Base*>(this) = __x;
00341     return *this;
00342       }
00343 
00344       unordered_multiset&
00345       operator=(unordered_multiset&& __x)
00346       {
00347     // NB: DR 1204.
00348     // NB: DR 675.
00349     this->clear();
00350     this->swap(__x);
00351     return *this;
00352       }
00353 
00354       unordered_multiset&
00355       operator=(initializer_list<value_type> __l)
00356       {
00357     this->clear();
00358     this->insert(__l);
00359     return *this;
00360       }
00361 
00362       ~unordered_multiset()
00363       {
00364         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00365                                      _Base::size());
00366         _M_profile_destruct();
00367       }
00368 
00369       void
00370       swap(unordered_multiset& __x)
00371       {
00372         _Base::swap(__x);
00373       }
00374 
00375       void
00376       clear()
00377       {
00378         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00379                                      _Base::size());
00380         _M_profile_destruct();
00381         _Base::clear();
00382       }
00383 
00384       void
00385       insert(std::initializer_list<value_type> __l)
00386       { 
00387         size_type __old_size =  _Base::bucket_count();
00388         _Base::insert(__l); 
00389         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00390       }
00391 
00392       iterator
00393       insert(const value_type& __obj)
00394       {
00395         size_type __old_size =  _Base::bucket_count();
00396         iterator __res = _Base::insert(__obj);
00397         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00398         return __res;
00399       }
00400 
00401       iterator
00402       insert(iterator __iter, const value_type& __v)
00403       { 
00404         size_type __old_size = _Base::bucket_count(); 
00405         iterator res = _Base::insert(__iter, __v);
00406         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00407         return res;
00408       }
00409 
00410       const_iterator
00411       insert(const_iterator __iter, const value_type& __v)
00412       { 
00413         size_type __old_size = _Base::bucket_count(); 
00414         const_iterator res =_Base::insert(__iter, __v);
00415         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00416         return res;
00417       }
00418 
00419       template<typename _InputIter>
00420       void
00421       insert(_InputIter __first, _InputIter __last)
00422       {
00423         size_type __old_size = _Base::bucket_count(); 
00424         _Base::insert(__first, __last);
00425         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00426       }
00427 
00428       void
00429       insert(const value_type* __first, const value_type* __last)
00430       {
00431         size_type __old_size = _Base::bucket_count(); 
00432         _Base::insert(__first, __last);
00433         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00434       }
00435      
00436       void rehash(size_type __n)
00437       {
00438         size_type __old_size =  _Base::bucket_count();
00439         _Base::rehash(__n);
00440         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00441       }
00442 
00443     private:
00444       _Base&
00445       _M_base()       { return *this; }
00446 
00447       const _Base&
00448       _M_base() const { return *this; }
00449 
00450       void _M_profile_resize(size_type __old_size, size_type __new_size)
00451       {
00452         if (__old_size != __new_size)
00453         {
00454           __profcxx_hashtable_resize(this, __old_size, __new_size);
00455         }
00456       }
00457 
00458       void _M_profile_destruct()
00459       {
00460         size_type __hops = 0, __lc = 0, __chain = 0;
00461         for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
00462         {
00463           while (it._M_cur_node->_M_next) {
00464              __chain++;
00465              it++;
00466           }
00467           if (__chain) {
00468             __chain++;
00469             __lc = __lc > __chain ? __lc : __chain;
00470             __hops += __chain * (__chain - 1) / 2;
00471             __chain = 0;
00472           }
00473         }
00474         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
00475       }
00476 
00477    };
00478   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00479     inline void
00480     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00481      unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00482     { __x.swap(__y); }
00483 
00484 } // namespace __profile
00485 } // namespace std
00486 
00487 #undef _GLIBCXX_BASE
00488 #undef _GLIBCXX_STD_BASE
00489 
00490 #endif

Generated on 9 Feb 2010 for libstdc++ by  doxygen 1.6.1