Home | History | Annotate | Download | only in profile
      1 // Profiling list implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2009-2013 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file profile/list
     26  *  This file is a GNU profile extension to the Standard C++ Library.
     27  */
     28 
     29 #ifndef _GLIBCXX_PROFILE_LIST
     30 #define _GLIBCXX_PROFILE_LIST 1
     31 
     32 #include <list>
     33 #include <profile/base.h> 
     34 #include <profile/iterator_tracker.h> 
     35 
     36 namespace std _GLIBCXX_VISIBILITY(default)
     37 {
     38 namespace __profile
     39 {
     40   /** @brief List wrapper with performance instrumentation.  */
     41 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
     42     class list
     43     : public _GLIBCXX_STD_C::list<_Tp, _Allocator>
     44     {
     45       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
     46 
     47     public:
     48       typedef typename _Base::reference             reference;
     49       typedef typename _Base::const_reference       const_reference;
     50 
     51       typedef __iterator_tracker<typename _Base::iterator, list>        
     52 				                    iterator;
     53       typedef __iterator_tracker<typename _Base::const_iterator, list>  
     54                                                     const_iterator;
     55 
     56       typedef typename _Base::size_type             size_type;
     57       typedef typename _Base::difference_type       difference_type;
     58 
     59       typedef _Tp				    value_type;
     60       typedef _Allocator			    allocator_type;
     61       typedef typename _Base::pointer               pointer;
     62       typedef typename _Base::const_pointer         const_pointer;
     63       typedef std::reverse_iterator<iterator>       reverse_iterator;
     64       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     65 
     66       // 23.2.2.1 construct/copy/destroy:
     67       explicit
     68       list(const _Allocator& __a = _Allocator())
     69       : _Base(__a) 
     70       {
     71         __profcxx_list_construct(this); 	// list2slist
     72         __profcxx_list_construct2(this); 	// list2vector
     73       }
     74 
     75 #if __cplusplus >= 201103L
     76       explicit
     77       list(size_type __n)
     78       : _Base(__n) 
     79       {
     80         __profcxx_list_construct(this); 
     81         __profcxx_list_construct2(this); 
     82       }
     83 
     84       list(size_type __n, const _Tp& __value,
     85 	   const _Allocator& __a = _Allocator())
     86       : _Base(__n, __value, __a) 
     87       {
     88         __profcxx_list_construct(this); 
     89         __profcxx_list_construct2(this); 
     90       }
     91 #else
     92       explicit
     93       list(size_type __n, const _Tp& __value = _Tp(),
     94 	   const _Allocator& __a = _Allocator())
     95       : _Base(__n, __value, __a) 
     96       {
     97         __profcxx_list_construct(this); 
     98         __profcxx_list_construct2(this); 
     99       }
    100 #endif
    101 
    102 #if __cplusplus >= 201103L
    103       template<typename _InputIterator,
    104 	       typename = std::_RequireInputIter<_InputIterator>>
    105 #else
    106       template<class _InputIterator>
    107 #endif
    108       list(_InputIterator __first, _InputIterator __last,
    109 	   const _Allocator& __a = _Allocator())
    110       : _Base(__first, __last, __a)
    111       {
    112         __profcxx_list_construct(this); 
    113         __profcxx_list_construct2(this); 
    114       }
    115 
    116       list(const list& __x)
    117       : _Base(__x) 
    118       {
    119         __profcxx_list_construct(this); 
    120         __profcxx_list_construct2(this); 
    121       }
    122 
    123       list(const _Base& __x)
    124       : _Base(__x) 
    125       {
    126         __profcxx_list_construct(this); 
    127         __profcxx_list_construct2(this); 
    128       }
    129 
    130 #if __cplusplus >= 201103L
    131       list(list&& __x) noexcept
    132       : _Base(std::move(__x))
    133       {
    134         __profcxx_list_construct(this); 
    135         __profcxx_list_construct2(this); 
    136       }
    137 
    138       list(initializer_list<value_type> __l,
    139            const allocator_type& __a = allocator_type())
    140         : _Base(__l, __a) { }
    141 #endif
    142 
    143       ~list() _GLIBCXX_NOEXCEPT
    144       { 
    145         __profcxx_list_destruct(this); 
    146         __profcxx_list_destruct2(this); 
    147       }
    148 
    149       list&
    150       operator=(const list& __x)
    151       {
    152 	static_cast<_Base&>(*this) = __x;
    153 	return *this;
    154       }
    155 
    156 #if __cplusplus >= 201103L
    157       list&
    158       operator=(list&& __x)
    159       {
    160 	// NB: DR 1204.
    161 	// NB: DR 675.
    162 	this->clear();
    163 	this->swap(__x);
    164 	return *this;
    165       }
    166 
    167       list&
    168       operator=(initializer_list<value_type> __l)
    169       {
    170 	static_cast<_Base&>(*this) = __l;
    171 	return *this;
    172       }
    173 
    174       void
    175       assign(initializer_list<value_type> __l)
    176       {	_Base::assign(__l); }
    177 #endif
    178 
    179 #if __cplusplus >= 201103L
    180       template<typename _InputIterator,
    181 	       typename = std::_RequireInputIter<_InputIterator>>
    182 #else
    183       template<class _InputIterator>
    184 #endif
    185         void
    186         assign(_InputIterator __first, _InputIterator __last)
    187         { _Base::assign(__first, __last); }
    188 
    189       void
    190       assign(size_type __n, const _Tp& __t)
    191       {	_Base::assign(__n, __t); }
    192 
    193       using _Base::get_allocator;
    194 
    195       // iterators:
    196       iterator
    197       begin() _GLIBCXX_NOEXCEPT
    198       { return iterator(_Base::begin(), this); }
    199 
    200       const_iterator
    201       begin() const _GLIBCXX_NOEXCEPT
    202       { return const_iterator(_Base::begin(), this); }
    203 
    204       iterator
    205       end() _GLIBCXX_NOEXCEPT
    206       {
    207         __profcxx_list_rewind(this);
    208         return iterator(_Base::end(), this);
    209       }
    210 
    211       const_iterator
    212       end() const _GLIBCXX_NOEXCEPT
    213       {
    214         __profcxx_list_rewind(this);
    215         return const_iterator(_Base::end(), this);
    216       }
    217 
    218       reverse_iterator
    219       rbegin() _GLIBCXX_NOEXCEPT
    220       {
    221         __profcxx_list_rewind(this);
    222         return reverse_iterator(end());
    223       }
    224 
    225       const_reverse_iterator
    226       rbegin() const _GLIBCXX_NOEXCEPT
    227       { 
    228         __profcxx_list_rewind(this);
    229         return const_reverse_iterator(end());
    230       }
    231 
    232       reverse_iterator
    233       rend() _GLIBCXX_NOEXCEPT
    234       { return reverse_iterator(begin()); }
    235 
    236       const_reverse_iterator
    237       rend() const _GLIBCXX_NOEXCEPT
    238       { return const_reverse_iterator(begin()); }
    239 
    240 #if __cplusplus >= 201103L
    241       const_iterator
    242       cbegin() const noexcept
    243       { return const_iterator(_Base::begin(), this); }
    244 
    245       const_iterator
    246       cend() const noexcept
    247       { return const_iterator(_Base::end(), this); }
    248 
    249       const_reverse_iterator
    250       crbegin() const noexcept
    251       { return const_reverse_iterator(end()); }
    252 
    253       const_reverse_iterator
    254       crend() const noexcept
    255       { return const_reverse_iterator(begin()); }
    256 #endif
    257 
    258       // 23.2.2.2 capacity:
    259       using _Base::empty;
    260       using _Base::size;
    261       using _Base::max_size;
    262 
    263 #if __cplusplus >= 201103L
    264       void
    265       resize(size_type __sz)
    266       { _Base::resize(__sz); }
    267 
    268       void
    269       resize(size_type __sz, const _Tp& __c)
    270       { _Base::resize(__sz, __c); }
    271 #else
    272       void
    273       resize(size_type __sz, _Tp __c = _Tp())
    274       { _Base::resize(__sz, __c); }
    275 #endif
    276 
    277       // element access:
    278       reference
    279       front()
    280       { return _Base::front(); }
    281 
    282       const_reference
    283       front() const
    284       { return _Base::front(); }
    285 
    286       reference
    287       back()
    288       {
    289         __profcxx_list_rewind(this);
    290 	return _Base::back();
    291       }
    292 
    293       const_reference
    294       back() const
    295       {
    296         __profcxx_list_rewind(this);
    297 	return _Base::back();
    298       }
    299 
    300       // 23.2.2.3 modifiers:
    301       void
    302       push_front(const value_type& __x)
    303       {
    304         __profcxx_list_invalid_operator(this);
    305         __profcxx_list_operation(this);
    306         _Base::push_front(__x);
    307       }
    308 
    309 #if __cplusplus >= 201103L
    310       using _Base::emplace_front;
    311 #endif
    312 
    313       void
    314       pop_front()
    315       {
    316         __profcxx_list_operation(this);
    317 	_Base::pop_front();
    318       }
    319 
    320       using _Base::push_back;
    321 
    322 #if __cplusplus >= 201103L
    323       using _Base::emplace_back;
    324 #endif
    325 
    326       void
    327       pop_back()
    328       {
    329 	iterator __victim = end();
    330 	--__victim;
    331 	_Base::pop_back();
    332         __profcxx_list_rewind(this);
    333       }
    334 
    335 #if __cplusplus >= 201103L
    336       template<typename... _Args>
    337         iterator
    338         emplace(iterator __position, _Args&&... __args)
    339 	{
    340 	  return iterator(_Base::emplace(__position.base(),
    341                                          std::forward<_Args>(__args)...),
    342 			  this);
    343 	}
    344 #endif
    345 
    346       iterator
    347       insert(iterator __position, const _Tp& __x)
    348       {
    349         _M_profile_insert(this, __position, size());
    350         return iterator(_Base::insert(__position.base(), __x), this);
    351       }
    352 
    353 #if __cplusplus >= 201103L
    354       iterator
    355       insert(iterator __position, _Tp&& __x)
    356       { 
    357         _M_profile_insert(this, __position, size());
    358         return iterator(_Base::emplace(__position.base(), std::move(__x)),
    359                         this); 
    360       }
    361 
    362       void
    363       insert(iterator __position, initializer_list<value_type> __l)
    364       {
    365         _M_profile_insert(this, __position, size());
    366         _Base::insert(__position.base(), __l);
    367       }
    368 #endif
    369 
    370       void
    371       insert(iterator __position, size_type __n, const _Tp& __x)
    372       {
    373         _M_profile_insert(this, __position, size());
    374 	_Base::insert(__position.base(), __n, __x);
    375       }
    376 
    377 #if __cplusplus >= 201103L
    378       template<typename _InputIterator,
    379 	       typename = std::_RequireInputIter<_InputIterator>>
    380 #else
    381       template<class _InputIterator>
    382 #endif
    383         void
    384         insert(iterator __position, _InputIterator __first,
    385 	       _InputIterator __last)
    386 	{
    387 	  _M_profile_insert(this, __position, size());
    388 	  _Base::insert(__position.base(), __first, __last);
    389 	}
    390 
    391       iterator
    392       erase(iterator __position)
    393       {	return iterator(_Base::erase(__position.base()), this); }
    394 
    395       iterator
    396       erase(iterator __position, iterator __last)
    397       {
    398 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
    399 	// 151. can't currently clear() empty container
    400 	return iterator(_Base::erase(__position.base(), __last.base()), this);
    401       }
    402 
    403       void
    404       swap(list& __x)
    405       {	_Base::swap(__x); }
    406 
    407       void
    408       clear() _GLIBCXX_NOEXCEPT
    409       {	_Base::clear(); }
    410 
    411       // 23.2.2.4 list operations:
    412       void
    413 #if __cplusplus >= 201103L
    414       splice(iterator __position, list&& __x)
    415 #else
    416       splice(iterator __position, list& __x)
    417 #endif
    418       { this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); }
    419 
    420 #if __cplusplus >= 201103L
    421       void
    422       splice(iterator __position, list& __x)
    423       { this->splice(__position, std::move(__x)); }
    424 #endif
    425 
    426 #if __cplusplus >= 201103L
    427       void
    428       splice(iterator __position, list& __x, iterator __i)
    429       { this->splice(__position, std::move(__x), __i); }
    430 #endif
    431 
    432       void
    433 #if __cplusplus >= 201103L
    434       splice(iterator __position, list&& __x, iterator __i)
    435 #else
    436       splice(iterator __position, list& __x, iterator __i)
    437 #endif
    438       {
    439 	// We used to perform the splice_alloc check:  not anymore, redundant
    440 	// after implementing the relevant bits of N1599.
    441 
    442 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
    443 	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
    444 		      __i.base());
    445       }
    446 
    447       void
    448 #if __cplusplus >= 201103L
    449       splice(iterator __position, list&& __x, iterator __first,
    450 	     iterator __last)
    451 #else
    452       splice(iterator __position, list& __x, iterator __first,
    453 	     iterator __last)
    454 #endif
    455       {
    456 	// We used to perform the splice_alloc check:  not anymore, redundant
    457 	// after implementing the relevant bits of N1599.
    458 
    459 	_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
    460 		      __first.base(), __last.base());
    461       }
    462 
    463 #if __cplusplus >= 201103L
    464       void
    465       splice(iterator __position, list& __x, iterator __first, iterator __last)
    466       { this->splice(__position, std::move(__x), __first, __last); }
    467 #endif
    468 
    469       void
    470       remove(const _Tp& __value)
    471       {
    472 	for (iterator __x = begin(); __x != end(); )
    473 	  {
    474 	    if (*__x == __value)
    475 	      __x = erase(__x);
    476 	    else
    477 	      ++__x;
    478 	  }
    479       }
    480 
    481       template<class _Predicate>
    482         void
    483         remove_if(_Predicate __pred)
    484         {
    485 	  for (iterator __x = begin(); __x != end(); )
    486 	    {
    487               __profcxx_list_operation(this);
    488 	      if (__pred(*__x))
    489 		__x = erase(__x);
    490 	      else
    491 		++__x;
    492 	    }
    493 	}
    494 
    495       void
    496       unique()
    497       {
    498 	iterator __first = begin();
    499 	iterator __last = end();
    500 	if (__first == __last)
    501 	  return;
    502 	iterator __next = __first;
    503 	while (++__next != __last)
    504 	  {
    505             __profcxx_list_operation(this);
    506 	    if (*__first == *__next)
    507 	      erase(__next);
    508 	    else
    509 	      __first = __next;
    510 	    __next = __first;
    511 	  }
    512       }
    513 
    514       template<class _BinaryPredicate>
    515         void
    516         unique(_BinaryPredicate __binary_pred)
    517         {
    518 	  iterator __first = begin();
    519 	  iterator __last = end();
    520 	  if (__first == __last)
    521 	    return;
    522 	  iterator __next = __first;
    523 	  while (++__next != __last)
    524 	    {
    525               __profcxx_list_operation(this);
    526 	      if (__binary_pred(*__first, *__next))
    527 		erase(__next);
    528 	      else
    529 		__first = __next;
    530 	      __next = __first;
    531 	    }
    532 	}
    533 
    534       void
    535 #if __cplusplus >= 201103L
    536       merge(list&& __x)
    537 #else
    538       merge(list& __x)
    539 #endif
    540       {
    541 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
    542 	// 300. list::merge() specification incomplete
    543 	if (this != &__x)
    544 	  { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
    545       }
    546 
    547 #if __cplusplus >= 201103L
    548       void
    549       merge(list& __x)
    550       { this->merge(std::move(__x)); }
    551 #endif
    552 
    553       template<class _Compare>
    554         void
    555 #if __cplusplus >= 201103L
    556         merge(list&& __x, _Compare __comp)
    557 #else
    558         merge(list& __x, _Compare __comp)
    559 #endif
    560         {
    561 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
    562 	  // 300. list::merge() specification incomplete
    563 	  if (this != &__x)
    564 	    { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
    565 	}
    566 
    567 #if __cplusplus >= 201103L
    568       template<typename _Compare>
    569         void
    570         merge(list& __x, _Compare __comp)
    571         { this->merge(std::move(__x), __comp); }
    572 #endif
    573 
    574       void
    575       sort() { _Base::sort(); }
    576 
    577       template<typename _StrictWeakOrdering>
    578         void
    579         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
    580 
    581       using _Base::reverse;
    582 
    583       _Base&
    584       _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
    585 
    586       const _Base&
    587       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
    588 
    589       void _M_profile_find() const
    590       { }
    591 
    592       void _M_profile_iterate(int __rewind = 0) const 
    593       {
    594         __profcxx_list_operation(this);
    595         __profcxx_list_iterate(this); 
    596         if (__rewind)
    597           __profcxx_list_rewind(this);
    598       }
    599 
    600     private:
    601       size_type _M_profile_insert(void* obj, iterator __pos, size_type __size)
    602       {
    603         size_type __shift = 0;
    604         typename _Base::iterator __it = __pos.base();
    605         for ( ; __it!=_Base::end(); __it++)
    606           __shift++;
    607         __profcxx_list_rewind(this);
    608         __profcxx_list_operation(this);
    609         __profcxx_list_insert(this, __shift, __size);
    610       }
    611     };
    612 
    613   template<typename _Tp, typename _Alloc>
    614     inline bool
    615     operator==(const list<_Tp, _Alloc>& __lhs,
    616 	       const list<_Tp, _Alloc>& __rhs)
    617     { return __lhs._M_base() == __rhs._M_base(); }
    618 
    619   template<typename _Tp, typename _Alloc>
    620     inline bool
    621     operator!=(const list<_Tp, _Alloc>& __lhs,
    622 	       const list<_Tp, _Alloc>& __rhs)
    623     { return __lhs._M_base() != __rhs._M_base(); }
    624 
    625   template<typename _Tp, typename _Alloc>
    626     inline bool
    627     operator<(const list<_Tp, _Alloc>& __lhs,
    628 	      const list<_Tp, _Alloc>& __rhs)
    629     { return __lhs._M_base() < __rhs._M_base(); }
    630 
    631   template<typename _Tp, typename _Alloc>
    632     inline bool
    633     operator<=(const list<_Tp, _Alloc>& __lhs,
    634 	       const list<_Tp, _Alloc>& __rhs)
    635     { return __lhs._M_base() <= __rhs._M_base(); }
    636 
    637   template<typename _Tp, typename _Alloc>
    638     inline bool
    639     operator>=(const list<_Tp, _Alloc>& __lhs,
    640 	       const list<_Tp, _Alloc>& __rhs)
    641     { return __lhs._M_base() >= __rhs._M_base(); }
    642 
    643   template<typename _Tp, typename _Alloc>
    644     inline bool
    645     operator>(const list<_Tp, _Alloc>& __lhs,
    646 	      const list<_Tp, _Alloc>& __rhs)
    647     { return __lhs._M_base() > __rhs._M_base(); }
    648 
    649   template<typename _Tp, typename _Alloc>
    650     inline void
    651     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
    652     { __lhs.swap(__rhs); }
    653 
    654 } // namespace __profile
    655 } // namespace std
    656 
    657 #endif
    658