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 <bits/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(const_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       template<typename _InputIter>
00196         void
00197         insert(_InputIter __first, _InputIter __last)
00198         {
00199       size_type __old_size = _Base::bucket_count(); 
00200       _Base::insert(__first, __last);
00201       _M_profile_resize(__old_size,  _Base::bucket_count()); 
00202     }
00203 
00204       void
00205       insert(const value_type* __first, const value_type* __last)
00206       {
00207         size_type __old_size = _Base::bucket_count(); 
00208         _Base::insert(__first, __last);
00209         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00210       }
00211      
00212       void rehash(size_type __n)
00213       {
00214         size_type __old_size =  _Base::bucket_count();
00215         _Base::rehash(__n);
00216         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00217       }
00218 
00219     private:
00220       _Base&
00221       _M_base()       { return *this; }
00222 
00223       const _Base&
00224       _M_base() const { return *this; }
00225 
00226       void
00227       _M_profile_resize(size_type __old_size, size_type __new_size)
00228       {
00229         if (__old_size != __new_size)
00230       __profcxx_hashtable_resize(this, __old_size, __new_size);
00231       }
00232 
00233       void
00234       _M_profile_destruct()
00235       {
00236         size_type __hops = 0, __lc = 0, __chain = 0;
00237         for (iterator __it = _M_base().begin(); __it != _M_base().end();
00238          ++__it)
00239         {
00240           while (__it._M_cur_node->_M_next)
00241         {
00242           ++__chain;
00243           ++__it;
00244         }
00245 
00246           if (__chain)
00247         {
00248           ++__chain;
00249           __lc = __lc > __chain ? __lc : __chain;
00250           __hops += __chain * (__chain - 1) / 2;
00251           __chain = 0;
00252         }
00253         }
00254         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
00255       }
00256 
00257    };
00258 
00259   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00260     inline void
00261     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00262      unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00263     { __x.swap(__y); }
00264 
00265 #undef _GLIBCXX_BASE
00266 #undef _GLIBCXX_STD_BASE
00267 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
00268 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
00269 
00270   /** @brief Unordered_multiset wrapper with performance instrumentation.  */
00271   template<typename _Value,
00272        typename _Hash  = std::hash<_Value>,
00273        typename _Pred = std::equal_to<_Value>,
00274        typename _Alloc =  std::allocator<_Value> >
00275     class unordered_multiset
00276     : public _GLIBCXX_STD_BASE
00277     {
00278       typedef typename _GLIBCXX_STD_BASE _Base;
00279 
00280     public:
00281       typedef typename _Base::size_type       size_type;
00282       typedef typename _Base::hasher          hasher;
00283       typedef typename _Base::key_equal       key_equal;
00284       typedef typename _Base::allocator_type  allocator_type;
00285       typedef typename _Base::key_type        key_type;
00286       typedef typename _Base::value_type      value_type;
00287       typedef typename _Base::difference_type difference_type;
00288       typedef typename _Base::reference       reference;
00289       typedef typename _Base::const_reference const_reference;
00290 
00291       typedef typename _Base::iterator iterator;
00292       typedef typename _Base::const_iterator const_iterator;
00293 
00294       explicit
00295       unordered_multiset(size_type __n = 10,
00296             const hasher& __hf = hasher(),
00297             const key_equal& __eql = key_equal(),
00298             const allocator_type& __a = allocator_type())
00299       : _Base(__n, __hf, __eql, __a)
00300       {
00301         __profcxx_hashtable_construct(this, _Base::bucket_count());
00302       }
00303 
00304       template<typename _InputIterator>
00305         unordered_multiset(_InputIterator __f, _InputIterator __l,
00306               size_type __n = 10,
00307               const hasher& __hf = hasher(),
00308               const key_equal& __eql = key_equal(),
00309               const allocator_type& __a = allocator_type())
00310       : _Base(__f, __l, __n, __hf, __eql, __a)
00311       {
00312         __profcxx_hashtable_construct(this, _Base::bucket_count());
00313       }
00314 
00315       unordered_multiset(const _Base& __x)
00316       : _Base(__x)
00317       {
00318         __profcxx_hashtable_construct(this, _Base::bucket_count());
00319       }
00320 
00321       unordered_multiset(unordered_multiset&& __x)
00322       : _Base(std::forward<_Base>(__x))
00323       {
00324         __profcxx_hashtable_construct(this, _Base::bucket_count());
00325       }
00326 
00327       unordered_multiset(initializer_list<value_type> __l,
00328              size_type __n = 10,
00329              const hasher& __hf = hasher(),
00330              const key_equal& __eql = key_equal(),
00331              const allocator_type& __a = allocator_type())
00332       : _Base(__l, __n, __hf, __eql, __a) { }
00333 
00334       unordered_multiset&
00335       operator=(const unordered_multiset& __x)
00336       {
00337     *static_cast<_Base*>(this) = __x;
00338     return *this;
00339       }
00340 
00341       unordered_multiset&
00342       operator=(unordered_multiset&& __x)
00343       {
00344     // NB: DR 1204.
00345     // NB: DR 675.
00346     this->clear();
00347     this->swap(__x);
00348     return *this;
00349       }
00350 
00351       unordered_multiset&
00352       operator=(initializer_list<value_type> __l)
00353       {
00354     this->clear();
00355     this->insert(__l);
00356     return *this;
00357       }
00358 
00359       ~unordered_multiset()
00360       {
00361         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00362                                      _Base::size());
00363         _M_profile_destruct();
00364       }
00365 
00366       void
00367       swap(unordered_multiset& __x)
00368       {
00369         _Base::swap(__x);
00370       }
00371 
00372       void
00373       clear()
00374       {
00375         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
00376                                      _Base::size());
00377         _M_profile_destruct();
00378         _Base::clear();
00379       }
00380 
00381       void
00382       insert(std::initializer_list<value_type> __l)
00383       { 
00384         size_type __old_size =  _Base::bucket_count();
00385         _Base::insert(__l); 
00386         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00387       }
00388 
00389       iterator
00390       insert(const value_type& __obj)
00391       {
00392         size_type __old_size =  _Base::bucket_count();
00393         iterator __res = _Base::insert(__obj);
00394         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00395         return __res;
00396       }
00397 
00398       iterator
00399       insert(const_iterator __iter, const value_type& __v)
00400       { 
00401         size_type __old_size = _Base::bucket_count(); 
00402         iterator __res = _Base::insert(__iter, __v);
00403         _M_profile_resize(__old_size, _Base::bucket_count()); 
00404         return __res;
00405       }
00406 
00407       template<typename _InputIter>
00408         void
00409         insert(_InputIter __first, _InputIter __last)
00410         {
00411       size_type __old_size = _Base::bucket_count(); 
00412       _Base::insert(__first, __last);
00413       _M_profile_resize(__old_size,  _Base::bucket_count()); 
00414     }
00415 
00416       void
00417       insert(const value_type* __first, const value_type* __last)
00418       {
00419         size_type __old_size = _Base::bucket_count(); 
00420         _Base::insert(__first, __last);
00421         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00422       }
00423      
00424       void rehash(size_type __n)
00425       {
00426         size_type __old_size =  _Base::bucket_count();
00427         _Base::rehash(__n);
00428         _M_profile_resize(__old_size,  _Base::bucket_count()); 
00429       }
00430 
00431     private:
00432       _Base&
00433       _M_base()       { return *this; }
00434 
00435       const _Base&
00436       _M_base() const { return *this; }
00437 
00438       void
00439       _M_profile_resize(size_type __old_size, size_type __new_size)
00440       {
00441         if (__old_size != __new_size)
00442           __profcxx_hashtable_resize(this, __old_size, __new_size);
00443       }
00444 
00445       void
00446       _M_profile_destruct()
00447       {
00448         size_type __hops = 0, __lc = 0, __chain = 0;
00449         for (iterator __it = _M_base().begin(); __it != _M_base().end();
00450          ++__it)
00451         {
00452           while (__it._M_cur_node->_M_next)
00453         {
00454              ++__chain;
00455              ++__it;
00456         }
00457 
00458           if (__chain)
00459         {
00460           ++__chain;
00461           __lc = __lc > __chain ? __lc : __chain;
00462           __hops += __chain * (__chain - 1) / 2;
00463           __chain = 0;
00464         }
00465         }
00466         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
00467       }
00468 
00469    };
00470 
00471   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00472     inline void
00473     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00474      unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00475     { __x.swap(__y); }
00476 
00477 } // namespace __profile
00478 } // namespace std
00479 
00480 #undef _GLIBCXX_BASE
00481 #undef _GLIBCXX_STD_BASE
00482 
00483 #endif

Generated on 12 Mar 2010 for libstdc++ by  doxygen 1.6.1