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