1 // Profiling list implementation -*- C++ -*-
 
    3 // Copyright (C) 2009-2014 Free Software Foundation, Inc.
 
    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)
 
   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.
 
   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.
 
   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/>.
 
   25 /** @file profile/list
 
   26  *  This file is a GNU profile extension to the Standard C++ Library.
 
   29 #ifndef _GLIBCXX_PROFILE_LIST
 
   30 #define _GLIBCXX_PROFILE_LIST 1
 
   33 #include <profile/base.h> 
 
   34 #include <profile/iterator_tracker.h> 
 
   36 namespace std _GLIBCXX_VISIBILITY(default)
 
   40   /** @brief List wrapper with performance instrumentation.  */
 
   41 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
 
   43     : public _GLIBCXX_STD_C::list<_Tp, _Allocator>
 
   45       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
 
   48       typedef typename _Base::reference             reference;
 
   49       typedef typename _Base::const_reference       const_reference;
 
   51       typedef __iterator_tracker<typename _Base::iterator, list>        
 
   53       typedef __iterator_tracker<typename _Base::const_iterator, list>  
 
   56       typedef typename _Base::size_type             size_type;
 
   57       typedef typename _Base::difference_type       difference_type;
 
   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;
 
   66       // 23.2.2.1 construct/copy/destroy:
 
   68       list() _GLIBCXX_NOEXCEPT
 
   71         __profcxx_list_construct(this);    // list2slist
 
   72         __profcxx_list_construct2(this);   // list2vector
 
   76       list(const _Allocator& __a) _GLIBCXX_NOEXCEPT
 
   79         __profcxx_list_construct(this);    // list2slist
 
   80         __profcxx_list_construct2(this);   // list2vector
 
   83 #if __cplusplus >= 201103L
 
   88         __profcxx_list_construct(this); 
 
   89         __profcxx_list_construct2(this); 
 
   92       list(size_type __n, const _Tp& __value,
 
   93       const _Allocator& __a = _Allocator())
 
   94       : _Base(__n, __value, __a) 
 
   96         __profcxx_list_construct(this); 
 
   97         __profcxx_list_construct2(this); 
 
  101       list(size_type __n, const _Tp& __value = _Tp(),
 
  102       const _Allocator& __a = _Allocator())
 
  103       : _Base(__n, __value, __a) 
 
  105         __profcxx_list_construct(this); 
 
  106         __profcxx_list_construct2(this); 
 
  110 #if __cplusplus >= 201103L
 
  111       template<typename _InputIterator,
 
  112           typename = std::_RequireInputIter<_InputIterator>>
 
  114       template<class _InputIterator>
 
  116       list(_InputIterator __first, _InputIterator __last,
 
  117       const _Allocator& __a = _Allocator())
 
  118       : _Base(__first, __last, __a)
 
  120         __profcxx_list_construct(this); 
 
  121         __profcxx_list_construct2(this); 
 
  124       list(const list& __x)
 
  127         __profcxx_list_construct(this); 
 
  128         __profcxx_list_construct2(this); 
 
  131       list(const _Base& __x)
 
  134         __profcxx_list_construct(this); 
 
  135         __profcxx_list_construct2(this); 
 
  138 #if __cplusplus >= 201103L
 
  139       list(list&& __x) noexcept
 
  140       : _Base(std::move(__x))
 
  142         __profcxx_list_construct(this); 
 
  143         __profcxx_list_construct2(this); 
 
  146       list(initializer_list<value_type> __l,
 
  147            const allocator_type& __a = allocator_type())
 
  148         : _Base(__l, __a) { }
 
  151       ~list() _GLIBCXX_NOEXCEPT
 
  153         __profcxx_list_destruct(this); 
 
  154         __profcxx_list_destruct2(this); 
 
  158       operator=(const list& __x)
 
  160    static_cast<_Base&>(*this) = __x;
 
  164 #if __cplusplus >= 201103L
 
  166       operator=(list&& __x)
 
  176       operator=(initializer_list<value_type> __l)
 
  178    static_cast<_Base&>(*this) = __l;
 
  183       assign(initializer_list<value_type> __l)
 
  184       {    _Base::assign(__l); }
 
  187 #if __cplusplus >= 201103L
 
  188       template<typename _InputIterator,
 
  189           typename = std::_RequireInputIter<_InputIterator>>
 
  191       template<class _InputIterator>
 
  194         assign(_InputIterator __first, _InputIterator __last)
 
  195         { _Base::assign(__first, __last); }
 
  198       assign(size_type __n, const _Tp& __t)
 
  199       {    _Base::assign(__n, __t); }
 
  201       using _Base::get_allocator;
 
  205       begin() _GLIBCXX_NOEXCEPT
 
  206       { return iterator(_Base::begin(), this); }
 
  209       begin() const _GLIBCXX_NOEXCEPT
 
  210       { return const_iterator(_Base::begin(), this); }
 
  213       end() _GLIBCXX_NOEXCEPT
 
  215         __profcxx_list_rewind(this);
 
  216         return iterator(_Base::end(), this);
 
  220       end() const _GLIBCXX_NOEXCEPT
 
  222         __profcxx_list_rewind(this);
 
  223         return const_iterator(_Base::end(), this);
 
  227       rbegin() _GLIBCXX_NOEXCEPT
 
  229         __profcxx_list_rewind(this);
 
  230         return reverse_iterator(end());
 
  233       const_reverse_iterator
 
  234       rbegin() const _GLIBCXX_NOEXCEPT
 
  236         __profcxx_list_rewind(this);
 
  237         return const_reverse_iterator(end());
 
  241       rend() _GLIBCXX_NOEXCEPT
 
  242       { return reverse_iterator(begin()); }
 
  244       const_reverse_iterator
 
  245       rend() const _GLIBCXX_NOEXCEPT
 
  246       { return const_reverse_iterator(begin()); }
 
  248 #if __cplusplus >= 201103L
 
  250       cbegin() const noexcept
 
  251       { return const_iterator(_Base::begin(), this); }
 
  254       cend() const noexcept
 
  255       { return const_iterator(_Base::end(), this); }
 
  257       const_reverse_iterator
 
  258       crbegin() const noexcept
 
  259       { return const_reverse_iterator(end()); }
 
  261       const_reverse_iterator
 
  262       crend() const noexcept
 
  263       { return const_reverse_iterator(begin()); }
 
  266       // 23.2.2.2 capacity:
 
  269       using _Base::max_size;
 
  271 #if __cplusplus >= 201103L
 
  273       resize(size_type __sz)
 
  274       { _Base::resize(__sz); }
 
  277       resize(size_type __sz, const _Tp& __c)
 
  278       { _Base::resize(__sz, __c); }
 
  281       resize(size_type __sz, _Tp __c = _Tp())
 
  282       { _Base::resize(__sz, __c); }
 
  287       front() _GLIBCXX_NOEXCEPT
 
  288       { return _Base::front(); }
 
  291       front() const _GLIBCXX_NOEXCEPT
 
  292       { return _Base::front(); }
 
  295       back() _GLIBCXX_NOEXCEPT
 
  297         __profcxx_list_rewind(this);
 
  298    return _Base::back();
 
  302       back() const _GLIBCXX_NOEXCEPT
 
  304         __profcxx_list_rewind(this);
 
  305    return _Base::back();
 
  308       // 23.2.2.3 modifiers:
 
  310       push_front(const value_type& __x)
 
  312         __profcxx_list_invalid_operator(this);
 
  313         __profcxx_list_operation(this);
 
  314         _Base::push_front(__x);
 
  317 #if __cplusplus >= 201103L
 
  318       using _Base::emplace_front;
 
  322       pop_front() _GLIBCXX_NOEXCEPT
 
  324         __profcxx_list_operation(this);
 
  328       using _Base::push_back;
 
  330 #if __cplusplus >= 201103L
 
  331       using _Base::emplace_back;
 
  335       pop_back() _GLIBCXX_NOEXCEPT
 
  337    iterator __victim = end();
 
  340         __profcxx_list_rewind(this);
 
  343 #if __cplusplus >= 201103L
 
  344       template<typename... _Args>
 
  346         emplace(const_iterator __position, _Args&&... __args)
 
  348      return iterator(_Base::emplace(__position.base(),
 
  349                                          std::forward<_Args>(__args)...),
 
  355 #if __cplusplus >= 201103L
 
  356       insert(const_iterator __position, const _Tp& __x)
 
  358       insert(iterator __position, const _Tp& __x)
 
  361         _M_profile_insert(this, __position, size());
 
  362         return iterator(_Base::insert(__position.base(), __x), this);
 
  365 #if __cplusplus >= 201103L
 
  367       insert(const_iterator __position, _Tp&& __x)
 
  369         _M_profile_insert(this, __position, size());
 
  370         return iterator(_Base::emplace(__position.base(), std::move(__x)),
 
  375       insert(const_iterator __position, initializer_list<value_type> __l)
 
  377         _M_profile_insert(this, __position, size());
 
  378         return iterator(_Base::insert(__position.base(), __l), this);
 
  382 #if __cplusplus >= 201103L
 
  384       insert(const_iterator __position, size_type __n, const _Tp& __x)
 
  386         _M_profile_insert(this, __position, size());
 
  387    return iterator(_Base::insert(__position.base(), __n, __x), this);
 
  391       insert(iterator __position, size_type __n, const _Tp& __x)
 
  393         _M_profile_insert(this, __position, size());
 
  394    _Base::insert(__position.base(), __n, __x);
 
  398 #if __cplusplus >= 201103L
 
  399       template<typename _InputIterator,
 
  400           typename = std::_RequireInputIter<_InputIterator>>
 
  402         insert(const_iterator __position, _InputIterator __first,
 
  403           _InputIterator __last)
 
  405      _M_profile_insert(this, __position, size());
 
  406      return iterator(_Base::insert(__position.base(), __first, __last),
 
  410       template<class _InputIterator>
 
  412         insert(iterator __position, _InputIterator __first,
 
  413           _InputIterator __last)
 
  415      _M_profile_insert(this, __position, size());
 
  416      _Base::insert(__position.base(), __first, __last);
 
  421 #if __cplusplus >= 201103L
 
  422       erase(const_iterator __position) noexcept
 
  424       erase(iterator __position)
 
  426       {    return iterator(_Base::erase(__position.base()), this); }
 
  429 #if __cplusplus >= 201103L
 
  430       erase(const_iterator __position, const_iterator __last) noexcept
 
  432       erase(iterator __position, iterator __last)
 
  435    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  436    // 151. can't currently clear() empty container
 
  437    return iterator(_Base::erase(__position.base(), __last.base()), this);
 
  442       {    _Base::swap(__x); }
 
  445       clear() _GLIBCXX_NOEXCEPT
 
  448       // 23.2.2.4 list operations:
 
  450 #if __cplusplus >= 201103L
 
  451       splice(const_iterator __position, list&& __x) noexcept
 
  453       splice(iterator __position, list& __x)
 
  455       { this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); }
 
  457 #if __cplusplus >= 201103L
 
  459       splice(const_iterator __position, list& __x) noexcept
 
  460       { this->splice(__position, std::move(__x)); }
 
  463       splice(const_iterator __position, list& __x, const_iterator __i)
 
  464       { this->splice(__position, std::move(__x), __i); }
 
  468 #if __cplusplus >= 201103L
 
  469       splice(const_iterator __position, list&& __x, const_iterator __i) noexcept
 
  471       splice(iterator __position, list& __x, iterator __i)
 
  474    // We used to perform the splice_alloc check:  not anymore, redundant
 
  475    // after implementing the relevant bits of N1599.
 
  477    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  478    _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
 
  483 #if __cplusplus >= 201103L
 
  484       splice(const_iterator __position, list&& __x, const_iterator __first,
 
  485         const_iterator __last) noexcept
 
  487       splice(iterator __position, list& __x, iterator __first,
 
  491    // We used to perform the splice_alloc check:  not anymore, redundant
 
  492    // after implementing the relevant bits of N1599.
 
  494    _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
 
  495              __first.base(), __last.base());
 
  498 #if __cplusplus >= 201103L
 
  500       splice(const_iterator __position, list& __x,
 
  501         const_iterator __first, const_iterator __last) noexcept
 
  502       { this->splice(__position, std::move(__x), __first, __last); }
 
  506       remove(const _Tp& __value)
 
  508    for (iterator __x = begin(); __x != end(); )
 
  517       template<class _Predicate>
 
  519         remove_if(_Predicate __pred)
 
  521      for (iterator __x = begin(); __x != end(); )
 
  523               __profcxx_list_operation(this);
 
  534    iterator __first = begin();
 
  535    iterator __last = end();
 
  536    if (__first == __last)
 
  538    iterator __next = __first;
 
  539    while (++__next != __last)
 
  541             __profcxx_list_operation(this);
 
  542        if (*__first == *__next)
 
  550       template<class _BinaryPredicate>
 
  552         unique(_BinaryPredicate __binary_pred)
 
  554      iterator __first = begin();
 
  555      iterator __last = end();
 
  556      if (__first == __last)
 
  558      iterator __next = __first;
 
  559      while (++__next != __last)
 
  561               __profcxx_list_operation(this);
 
  562          if (__binary_pred(*__first, *__next))
 
  571 #if __cplusplus >= 201103L
 
  577    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  578    // 300. list::merge() specification incomplete
 
  580      { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); }
 
  583 #if __cplusplus >= 201103L
 
  586       { this->merge(std::move(__x)); }
 
  589       template<class _Compare>
 
  591 #if __cplusplus >= 201103L
 
  592         merge(list&& __x, _Compare __comp)
 
  594         merge(list& __x, _Compare __comp)
 
  597      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  598      // 300. list::merge() specification incomplete
 
  600        { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); }
 
  603 #if __cplusplus >= 201103L
 
  604       template<typename _Compare>
 
  606         merge(list& __x, _Compare __comp)
 
  607         { this->merge(std::move(__x), __comp); }
 
  611       sort() { _Base::sort(); }
 
  613       template<typename _StrictWeakOrdering>
 
  615         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
 
  617       using _Base::reverse;
 
  620       _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
 
  623       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
  625       void _M_profile_find() const
 
  628       void _M_profile_iterate(int __rewind = 0) const 
 
  630         __profcxx_list_operation(this);
 
  631         __profcxx_list_iterate(this); 
 
  633           __profcxx_list_rewind(this);
 
  638       _M_profile_insert(void* obj, const_iterator __pos, size_type __size)
 
  640         size_type __shift = 0;
 
  641         typename _Base::const_iterator __it = __pos.base();
 
  642         for (; __it != _Base::end(); ++__it)
 
  644         __profcxx_list_rewind(this);
 
  645         __profcxx_list_operation(this);
 
  646         __profcxx_list_insert(this, __shift, __size);
 
  650   template<typename _Tp, typename _Alloc>
 
  652     operator==(const list<_Tp, _Alloc>& __lhs,
 
  653           const list<_Tp, _Alloc>& __rhs)
 
  654     { return __lhs._M_base() == __rhs._M_base(); }
 
  656   template<typename _Tp, typename _Alloc>
 
  658     operator!=(const list<_Tp, _Alloc>& __lhs,
 
  659           const list<_Tp, _Alloc>& __rhs)
 
  660     { return __lhs._M_base() != __rhs._M_base(); }
 
  662   template<typename _Tp, typename _Alloc>
 
  664     operator<(const list<_Tp, _Alloc>& __lhs,
 
  665          const list<_Tp, _Alloc>& __rhs)
 
  666     { return __lhs._M_base() < __rhs._M_base(); }
 
  668   template<typename _Tp, typename _Alloc>
 
  670     operator<=(const list<_Tp, _Alloc>& __lhs,
 
  671           const list<_Tp, _Alloc>& __rhs)
 
  672     { return __lhs._M_base() <= __rhs._M_base(); }
 
  674   template<typename _Tp, typename _Alloc>
 
  676     operator>=(const list<_Tp, _Alloc>& __lhs,
 
  677           const list<_Tp, _Alloc>& __rhs)
 
  678     { return __lhs._M_base() >= __rhs._M_base(); }
 
  680   template<typename _Tp, typename _Alloc>
 
  682     operator>(const list<_Tp, _Alloc>& __lhs,
 
  683          const list<_Tp, _Alloc>& __rhs)
 
  684     { return __lhs._M_base() > __rhs._M_base(); }
 
  686   template<typename _Tp, typename _Alloc>
 
  688     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
 
  689     { __lhs.swap(__rhs); }
 
  691 } // namespace __profile