# 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