profile/list

Go to the documentation of this file.
00001 // Profiling list 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 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 and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file profile/list
00026  *  This file is a GNU profile extension to the Standard C++ Library.
00027  */
00028 
00029 #ifndef _GLIBCXX_PROFILE_LIST
00030 #define _GLIBCXX_PROFILE_LIST 1
00031 
00032 #include <list>
00033 #include <profile/base.h> 
00034 #include <profile/iterator_tracker.h> 
00035 
00036 namespace std
00037 {
00038 namespace __profile
00039 {
00040   /** @brief List wrapper with performance instrumentation.  */
00041 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
00042     class list
00043     : public _GLIBCXX_STD_D::list<_Tp, _Allocator>
00044     {
00045       typedef _GLIBCXX_STD_D::list<_Tp, _Allocator> _Base;
00046 
00047     public:
00048       typedef typename _Base::reference             reference;
00049       typedef typename _Base::const_reference       const_reference;
00050 
00051       typedef __iterator_tracker<typename _Base::iterator, list>        
00052                                     iterator;
00053       typedef __iterator_tracker<typename _Base::const_iterator, list>  
00054                                                     const_iterator;
00055 
00056       typedef typename _Base::size_type             size_type;
00057       typedef typename _Base::difference_type       difference_type;
00058 
00059       typedef _Tp                   value_type;
00060       typedef _Allocator                allocator_type;
00061       typedef typename _Base::pointer               pointer;
00062       typedef typename _Base::const_pointer         const_pointer;
00063       typedef std::reverse_iterator<iterator>       reverse_iterator;
00064       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00065 
00066       // 23.2.2.1 construct/copy/destroy:
00067       explicit list(const _Allocator& __a = _Allocator())
00068       : _Base(__a) 
00069       { 
00070         __profcxx_list_construct(this);     // list2slist
00071         __profcxx_list_construct2(this);    // list2vector
00072       }
00073 
00074       explicit list(size_type __n, const _Tp& __value = _Tp(),
00075             const _Allocator& __a = _Allocator())
00076       : _Base(__n, __value, __a) 
00077       { 
00078         __profcxx_list_construct(this); 
00079         __profcxx_list_construct2(this); 
00080       }
00081 
00082       template<class _InputIterator>
00083       list(_InputIterator __first, _InputIterator __last,
00084        const _Allocator& __a = _Allocator())
00085       : _Base(__first, __last, __a)
00086       {  
00087         __profcxx_list_construct(this); 
00088         __profcxx_list_construct2(this); 
00089       }
00090 
00091       list(const list& __x)
00092       : _Base(__x) 
00093       { 
00094         __profcxx_list_construct(this); 
00095         __profcxx_list_construct2(this); 
00096       }
00097 
00098       list(const _Base& __x)
00099       : _Base(__x) 
00100       {     
00101         __profcxx_list_construct(this); 
00102         __profcxx_list_construct2(this); 
00103       }
00104 
00105 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00106       list(list&& __x)
00107       : _Base(std::forward<list>(__x))
00108       { 
00109         __profcxx_list_construct(this); 
00110         __profcxx_list_construct2(this); 
00111       }
00112 
00113       list(initializer_list<value_type> __l,
00114            const allocator_type& __a = allocator_type())
00115         : _Base(__l, __a) { }
00116 #endif
00117 
00118       ~list() { 
00119         __profcxx_list_destruct(this); 
00120         __profcxx_list_destruct2(this); 
00121       }
00122 
00123       list&
00124       operator=(const list& __x)
00125       {
00126     static_cast<_Base&>(*this) = __x;
00127     return *this;
00128       }
00129 
00130 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00131       list&
00132       operator=(list&& __x)
00133       {
00134     // NB: DR 1204.
00135     // NB: DR 675.
00136     this->clear();
00137     this->swap(__x);
00138     return *this;
00139       }
00140 
00141       list&
00142       operator=(initializer_list<value_type> __l)
00143       {
00144     static_cast<_Base&>(*this) = __l;
00145     return *this;
00146       }
00147 
00148       void
00149       assign(initializer_list<value_type> __l)
00150       { _Base::assign(__l); }
00151 #endif
00152 
00153       template<class _InputIterator>
00154         void
00155         assign(_InputIterator __first, _InputIterator __last)
00156         { _Base::assign(__first, __last); }
00157 
00158       void
00159       assign(size_type __n, const _Tp& __t)
00160       { _Base::assign(__n, __t); }
00161 
00162       using _Base::get_allocator;
00163 
00164       // iterators:
00165       iterator
00166       begin()
00167       { return iterator(_Base::begin(), this); }
00168 
00169       const_iterator
00170       begin() const
00171       { return const_iterator(_Base::begin(), this); }
00172 
00173       iterator
00174       end()
00175       {
00176         __profcxx_list_rewind(this);
00177         return iterator(_Base::end(), this);
00178       }
00179 
00180       const_iterator
00181       end() const
00182       {
00183         __profcxx_list_rewind(this);
00184         return const_iterator(_Base::end(), this);
00185       }
00186 
00187       reverse_iterator
00188       rbegin()
00189       {
00190         __profcxx_list_rewind(this);
00191         return reverse_iterator(end());
00192       }
00193 
00194       const_reverse_iterator
00195       rbegin() const
00196       { 
00197         __profcxx_list_rewind(this);
00198         return const_reverse_iterator(end());
00199       }
00200 
00201       reverse_iterator
00202       rend()
00203       { return reverse_iterator(begin()); }
00204 
00205       const_reverse_iterator
00206       rend() const
00207       { return const_reverse_iterator(begin()); }
00208 
00209 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00210       const_iterator
00211       cbegin() const
00212       { return const_iterator(_Base::begin(), this); }
00213 
00214       const_iterator
00215       cend() const
00216       { return const_iterator(_Base::end(), this); }
00217 
00218       const_reverse_iterator
00219       crbegin() const
00220       { return const_reverse_iterator(end()); }
00221 
00222       const_reverse_iterator
00223       crend() const
00224       { return const_reverse_iterator(begin()); }
00225 #endif
00226 
00227       // 23.2.2.2 capacity:
00228       using _Base::empty;
00229       using _Base::size;
00230       using _Base::max_size;
00231 
00232       void
00233       resize(size_type __sz, _Tp __c = _Tp())
00234       { _Base::resize(__sz, __c); }
00235 
00236       // element access:
00237       reference
00238       front()
00239       { return _Base::front(); }
00240 
00241       const_reference
00242       front() const
00243       { return _Base::front(); }
00244 
00245       reference
00246       back()
00247       {
00248         __profcxx_list_rewind(this);
00249     return _Base::back();
00250       }
00251 
00252       const_reference
00253       back() const
00254       {
00255         __profcxx_list_rewind(this);
00256     return _Base::back();
00257       }
00258 
00259       // 23.2.2.3 modifiers:
00260       void
00261       push_front(const value_type& __x)
00262       {
00263         __profcxx_list_invalid_operator(this);
00264         __profcxx_list_operation(this);
00265         _Base::push_front(__x);
00266       }
00267 
00268 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00269       using _Base::emplace_front;
00270 #endif
00271 
00272       void
00273       pop_front()
00274       {
00275         __profcxx_list_operation(this);
00276     _Base::pop_front();
00277       }
00278 
00279       using _Base::push_back;
00280 
00281 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00282       using _Base::emplace_back;
00283 #endif
00284 
00285       void
00286       pop_back()
00287       {
00288     iterator __victim = end();
00289     --__victim;
00290     _Base::pop_back();
00291         __profcxx_list_rewind(this);
00292       }
00293 
00294 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00295       template<typename... _Args>
00296         iterator
00297         emplace(iterator __position, _Args&&... __args)
00298     {
00299       return iterator(_Base::emplace(__position.base(),
00300                                          std::forward<_Args>(__args)...));
00301     }
00302 #endif
00303 
00304       iterator
00305       insert(iterator __position, const _Tp& __x)
00306       {
00307         _M_profile_insert(this, __position, size());
00308         return iterator(_Base::insert(__position.base(), __x), this);
00309       }
00310 
00311 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00312       iterator
00313       insert(iterator __position, _Tp&& __x)
00314       { 
00315         _M_profile_insert(this, __position, size());
00316         return iterator(_Base::emplace(__position.base(), std::move(__x)),
00317                         this); 
00318       }
00319 
00320       void
00321       insert(iterator __position, initializer_list<value_type> __l)
00322       {
00323         _M_profile_insert(this, __position, size());
00324         _Base::insert(__position.base(), __l);
00325       }
00326 #endif
00327 
00328       void
00329       insert(iterator __position, size_type __n, const _Tp& __x)
00330       {
00331         _M_profile_insert(this, __position, size());
00332     _Base::insert(__position.base(), __n, __x);
00333       }
00334 
00335       template<class _InputIterator>
00336         void
00337         insert(iterator __position, _InputIterator __first,
00338            _InputIterator __last)
00339       {
00340         _M_profile_insert(this, __position, size());
00341         _Base::insert(__position.base(), __first, __last);
00342       }
00343 
00344       iterator
00345       erase(iterator __position)
00346       { return iterator(_Base::erase(__position.base()), this); }
00347 
00348       iterator
00349       erase(iterator __position, iterator __last)
00350       {
00351     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00352     // 151. can't currently clear() empty container
00353     return iterator(_Base::erase(__position.base(), __last.base()), this);
00354       }
00355 
00356       void
00357       swap(list& __x)
00358       { _Base::swap(__x); }
00359 
00360       void
00361       clear()
00362       { _Base::clear(); }
00363 
00364       // 23.2.2.4 list operations:
00365       void
00366 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00367       splice(iterator __position, list&& __x)
00368 #else
00369       splice(iterator __position, list& __x)
00370 #endif
00371       { this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); }
00372 
00373 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00374       void
00375       splice(iterator __position, list& __x)
00376       { this->splice(__position, std::move(__x)); }
00377 #endif
00378 
00379 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00380       void
00381       splice(iterator __position, list& __x, iterator __i)
00382       { this->splice(__position, std::move(__x), __i); }
00383 #endif
00384 
00385       void
00386 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00387       splice(iterator __position, list&& __x, iterator __i)
00388 #else
00389       splice(iterator __position, list& __x, iterator __i)
00390 #endif
00391       {
00392     // We used to perform the splice_alloc check:  not anymore, redundant
00393     // after implementing the relevant bits of N1599.
00394 
00395     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00396     _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
00397               __i.base());
00398       }
00399 
00400       void
00401 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00402       splice(iterator __position, list&& __x, iterator __first,
00403          iterator __last)
00404 #else
00405       splice(iterator __position, list& __x, iterator __first,
00406          iterator __last)
00407 #endif
00408       {
00409     // We used to perform the splice_alloc check:  not anymore, redundant
00410     // after implementing the relevant bits of N1599.
00411 
00412     _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
00413               __first.base(), __last.base());
00414       }
00415 
00416 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00417       void
00418       splice(iterator __position, list& __x, iterator __first, iterator __last)
00419       { this->splice(__position, std::move(__x), __first, __last); }
00420 #endif
00421 
00422       void
00423       remove(const _Tp& __value)
00424       {
00425     for (iterator __x = begin(); __x != end(); )
00426       {
00427         if (*__x == __value)
00428           __x = erase(__x);
00429         else
00430           ++__x;
00431       }
00432       }
00433 
00434       template<class _Predicate>
00435         void
00436         remove_if(_Predicate __pred)
00437         {
00438       for (iterator __x = begin(); __x != end(); )
00439         {
00440               __profcxx_list_operation(this);
00441           if (__pred(*__x))
00442         __x = erase(__x);
00443           else
00444         ++__x;
00445         }
00446     }
00447 
00448       void
00449       unique()
00450       {
00451     iterator __first = begin();
00452     iterator __last = end();
00453     if (__first == __last)
00454       return;
00455     iterator __next = __first;
00456     while (++__next != __last)
00457       {
00458             __profcxx_list_operation(this);
00459         if (*__first == *__next)
00460           erase(__next);
00461         else
00462           __first = __next;
00463         __next = __first;
00464       }
00465       }
00466 
00467       template<class _BinaryPredicate>
00468         void
00469         unique(_BinaryPredicate __binary_pred)
00470         {
00471       iterator __first = begin();
00472       iterator __last = end();
00473       if (__first == __last)
00474         return;
00475       iterator __next = __first;
00476       while (++__next != __last)
00477         {
00478               __profcxx_list_operation(this);
00479           if (__binary_pred(*__first, *__next))
00480         erase(__next);
00481           else
00482         __first = __next;
00483           __next = __first;
00484         }
00485     }
00486 
00487       void
00488 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00489       merge(list&& __x)
00490 #else
00491       merge(list& __x)
00492 #endif
00493       {
00494     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00495     // 300. list::merge() specification incomplete
00496     if (this != &__x)
00497       { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
00498       }
00499 
00500 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00501       void
00502       merge(list& __x)
00503       { this->merge(std::move(__x)); }
00504 #endif
00505 
00506       template<class _Compare>
00507         void
00508 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00509         merge(list&& __x, _Compare __comp)
00510 #else
00511         merge(list& __x, _Compare __comp)
00512 #endif
00513         {
00514       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00515       // 300. list::merge() specification incomplete
00516       if (this != &__x)
00517         { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
00518     }
00519 
00520 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00521       template<typename _Compare>
00522         void
00523         merge(list& __x, _Compare __comp)
00524         { this->merge(std::move(__x), __comp); }
00525 #endif
00526 
00527       void
00528       sort() { _Base::sort(); }
00529 
00530       template<typename _StrictWeakOrdering>
00531         void
00532         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
00533 
00534       using _Base::reverse;
00535 
00536       _Base&
00537       _M_base()       { return *this; }
00538 
00539       const _Base&
00540       _M_base() const { return *this; }
00541 
00542       inline void _M_profile_find() const 
00543       { }
00544 
00545       inline void _M_profile_iterate(int __rewind = 0) const 
00546       {
00547         __profcxx_list_operation(this);
00548         __profcxx_list_iterate(this); 
00549         if (__rewind)
00550           __profcxx_list_rewind(this);
00551       }
00552 
00553     private:
00554       size_type _M_profile_insert(void* obj, iterator __pos, size_type __size)
00555       {
00556         size_type __shift = 0;
00557         typename _Base::iterator __it = __pos.base();
00558         for ( ; __it!=_Base::end(); __it++)
00559           __shift++;
00560         __profcxx_list_rewind(this);
00561         __profcxx_list_operation(this);
00562         __profcxx_list_insert(this, __shift, __size);
00563       }
00564     };
00565 
00566   template<typename _Tp, typename _Alloc>
00567     inline bool
00568     operator==(const list<_Tp, _Alloc>& __lhs,
00569            const list<_Tp, _Alloc>& __rhs)
00570     { return __lhs._M_base() == __rhs._M_base(); }
00571 
00572   template<typename _Tp, typename _Alloc>
00573     inline bool
00574     operator!=(const list<_Tp, _Alloc>& __lhs,
00575            const list<_Tp, _Alloc>& __rhs)
00576     { return __lhs._M_base() != __rhs._M_base(); }
00577 
00578   template<typename _Tp, typename _Alloc>
00579     inline bool
00580     operator<(const list<_Tp, _Alloc>& __lhs,
00581           const list<_Tp, _Alloc>& __rhs)
00582     { return __lhs._M_base() < __rhs._M_base(); }
00583 
00584   template<typename _Tp, typename _Alloc>
00585     inline bool
00586     operator<=(const list<_Tp, _Alloc>& __lhs,
00587            const list<_Tp, _Alloc>& __rhs)
00588     { return __lhs._M_base() <= __rhs._M_base(); }
00589 
00590   template<typename _Tp, typename _Alloc>
00591     inline bool
00592     operator>=(const list<_Tp, _Alloc>& __lhs,
00593            const list<_Tp, _Alloc>& __rhs)
00594     { return __lhs._M_base() >= __rhs._M_base(); }
00595 
00596   template<typename _Tp, typename _Alloc>
00597     inline bool
00598     operator>(const list<_Tp, _Alloc>& __lhs,
00599           const list<_Tp, _Alloc>& __rhs)
00600     { return __lhs._M_base() > __rhs._M_base(); }
00601 
00602   template<typename _Tp, typename _Alloc>
00603     inline void
00604     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
00605     { __lhs.swap(__rhs); }
00606 
00607 } // namespace __profile
00608 } // namespace std
00609 
00610 #endif