1 // Debugging list implementation -*- C++ -*-
 
    3 // Copyright (C) 2003-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/>.
 
   26  *  This file is a GNU debug extension to the Standard C++ Library.
 
   29 #ifndef _GLIBCXX_DEBUG_LIST
 
   30 #define _GLIBCXX_DEBUG_LIST 1
 
   33 #include <debug/safe_sequence.h>
 
   34 #include <debug/safe_iterator.h>
 
   36 namespace std _GLIBCXX_VISIBILITY(default)
 
   40   /// Class std::list with safety/checking/debug instrumentation.
 
   41   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
 
   43     : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
 
   44       public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
 
   46       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
 
   48       typedef typename _Base::iterator       _Base_iterator;
 
   49       typedef typename _Base::const_iterator _Base_const_iterator;
 
   50       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
 
   51       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
 
   53       typedef typename _Base::reference             reference;
 
   54       typedef typename _Base::const_reference       const_reference;
 
   56       typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
 
   58       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
 
   61       typedef typename _Base::size_type             size_type;
 
   62       typedef typename _Base::difference_type       difference_type;
 
   64       typedef _Tp                  value_type;
 
   65       typedef _Allocator               allocator_type;
 
   66       typedef typename _Base::pointer               pointer;
 
   67       typedef typename _Base::const_pointer         const_pointer;
 
   68       typedef std::reverse_iterator<iterator>       reverse_iterator;
 
   69       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
   71       // 23.2.2.1 construct/copy/destroy:
 
   73       list() _GLIBCXX_NOEXCEPT
 
   77       list(const _Allocator& __a) _GLIBCXX_NOEXCEPT
 
   80 #if __cplusplus >= 201103L
 
   85       list(size_type __n, const _Tp& __value,
 
   86       const _Allocator& __a = _Allocator())
 
   87       : _Base(__n, __value, __a) { }
 
   90       list(size_type __n, const _Tp& __value = _Tp(),
 
   91       const _Allocator& __a = _Allocator())
 
   92       : _Base(__n, __value, __a) { }
 
   95 #if __cplusplus >= 201103L
 
   96       template<class _InputIterator,
 
   97           typename = std::_RequireInputIter<_InputIterator>>
 
   99       template<class _InputIterator>
 
  101    list(_InputIterator __first, _InputIterator __last,
 
  102         const _Allocator& __a = _Allocator())
 
  103    : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
 
  105        __gnu_debug::__base(__last), __a)
 
  108       list(const list& __x)
 
  111       list(const _Base& __x)
 
  114 #if __cplusplus >= 201103L
 
  115       list(list&& __x) noexcept
 
  116       : _Base(std::move(__x))
 
  117       { this->_M_swap(__x); }
 
  119       list(initializer_list<value_type> __l,
 
  120            const allocator_type& __a = allocator_type())
 
  121         : _Base(__l, __a) { }
 
  124       ~list() _GLIBCXX_NOEXCEPT { }
 
  127       operator=(const list& __x)
 
  129    static_cast<_Base&>(*this) = __x;
 
  130    this->_M_invalidate_all();
 
  134 #if __cplusplus >= 201103L
 
  136       operator=(list&& __x)
 
  140    __glibcxx_check_self_move_assign(__x);
 
  147       operator=(initializer_list<value_type> __l)
 
  149    static_cast<_Base&>(*this) = __l;
 
  150    this->_M_invalidate_all();
 
  155       assign(initializer_list<value_type> __l)
 
  158    this->_M_invalidate_all();
 
  162 #if __cplusplus >= 201103L
 
  163       template<class _InputIterator,
 
  164           typename = std::_RequireInputIter<_InputIterator>>
 
  166       template<class _InputIterator>
 
  169         assign(_InputIterator __first, _InputIterator __last)
 
  171      __glibcxx_check_valid_range(__first, __last);
 
  172      _Base::assign(__gnu_debug::__base(__first),
 
  173            __gnu_debug::__base(__last));
 
  174      this->_M_invalidate_all();
 
  178       assign(size_type __n, const _Tp& __t)
 
  180    _Base::assign(__n, __t);
 
  181    this->_M_invalidate_all();
 
  184       using _Base::get_allocator;
 
  188       begin() _GLIBCXX_NOEXCEPT
 
  189       { return iterator(_Base::begin(), this); }
 
  192       begin() const _GLIBCXX_NOEXCEPT
 
  193       { return const_iterator(_Base::begin(), this); }
 
  196       end() _GLIBCXX_NOEXCEPT
 
  197       { return iterator(_Base::end(), this); }
 
  200       end() const _GLIBCXX_NOEXCEPT
 
  201       { return const_iterator(_Base::end(), this); }
 
  204       rbegin() _GLIBCXX_NOEXCEPT
 
  205       { return reverse_iterator(end()); }
 
  207       const_reverse_iterator
 
  208       rbegin() const _GLIBCXX_NOEXCEPT
 
  209       { return const_reverse_iterator(end()); }
 
  212       rend() _GLIBCXX_NOEXCEPT
 
  213       { return reverse_iterator(begin()); }
 
  215       const_reverse_iterator
 
  216       rend() const _GLIBCXX_NOEXCEPT
 
  217       { return const_reverse_iterator(begin()); }
 
  219 #if __cplusplus >= 201103L
 
  221       cbegin() const noexcept
 
  222       { return const_iterator(_Base::begin(), this); }
 
  225       cend() const noexcept
 
  226       { return const_iterator(_Base::end(), this); }
 
  228       const_reverse_iterator
 
  229       crbegin() const noexcept
 
  230       { return const_reverse_iterator(end()); }
 
  232       const_reverse_iterator
 
  233       crend() const noexcept
 
  234       { return const_reverse_iterator(begin()); }
 
  237       // 23.2.2.2 capacity:
 
  240       using _Base::max_size;
 
  242 #if __cplusplus >= 201103L
 
  244       resize(size_type __sz)
 
  246    this->_M_detach_singular();
 
  248    // if __sz < size(), invalidate all iterators in [begin+__sz, end())
 
  249    _Base_iterator __victim = _Base::begin();
 
  250    _Base_iterator __end = _Base::end();
 
  251    for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
 
  254    for (; __victim != __end; ++__victim)
 
  256        this->_M_invalidate_if(_Equal(__victim));
 
  265        this->_M_revalidate_singular();
 
  266        __throw_exception_again;
 
  271       resize(size_type __sz, const _Tp& __c)
 
  273    this->_M_detach_singular();
 
  275    // if __sz < size(), invalidate all iterators in [begin+__sz, end())
 
  276    _Base_iterator __victim = _Base::begin();
 
  277    _Base_iterator __end = _Base::end();
 
  278    for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
 
  281    for (; __victim != __end; ++__victim)
 
  283        this->_M_invalidate_if(_Equal(__victim));
 
  288        _Base::resize(__sz, __c);
 
  292        this->_M_revalidate_singular();
 
  293        __throw_exception_again;
 
  298       resize(size_type __sz, _Tp __c = _Tp())
 
  300    this->_M_detach_singular();
 
  302    // if __sz < size(), invalidate all iterators in [begin+__sz, end())
 
  303    _Base_iterator __victim = _Base::begin();
 
  304    _Base_iterator __end = _Base::end();
 
  305    for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
 
  308    for (; __victim != __end; ++__victim)
 
  310        this->_M_invalidate_if(_Equal(__victim));
 
  315        _Base::resize(__sz, __c);
 
  319        this->_M_revalidate_singular();
 
  320        __throw_exception_again;
 
  327       front() _GLIBCXX_NOEXCEPT
 
  329    __glibcxx_check_nonempty();
 
  330    return _Base::front();
 
  334       front() const _GLIBCXX_NOEXCEPT
 
  336    __glibcxx_check_nonempty();
 
  337    return _Base::front();
 
  341       back() _GLIBCXX_NOEXCEPT
 
  343    __glibcxx_check_nonempty();
 
  344    return _Base::back();
 
  348       back() const _GLIBCXX_NOEXCEPT
 
  350    __glibcxx_check_nonempty();
 
  351    return _Base::back();
 
  354       // 23.2.2.3 modifiers:
 
  355       using _Base::push_front;
 
  357 #if __cplusplus >= 201103L
 
  358       using _Base::emplace_front;
 
  362       pop_front() _GLIBCXX_NOEXCEPT
 
  364    __glibcxx_check_nonempty();
 
  365    this->_M_invalidate_if(_Equal(_Base::begin()));
 
  369       using _Base::push_back;
 
  371 #if __cplusplus >= 201103L
 
  372       using _Base::emplace_back;
 
  376       pop_back() _GLIBCXX_NOEXCEPT
 
  378    __glibcxx_check_nonempty();
 
  379    this->_M_invalidate_if(_Equal(--_Base::end()));
 
  383 #if __cplusplus >= 201103L
 
  384       template<typename... _Args>
 
  386         emplace(const_iterator __position, _Args&&... __args)
 
  388      __glibcxx_check_insert(__position);
 
  389      return iterator(_Base::emplace(__position.base(),
 
  390                    std::forward<_Args>(__args)...), this);
 
  395 #if __cplusplus >= 201103L
 
  396      insert(const_iterator __position, const _Tp& __x)
 
  398      insert(iterator __position, const _Tp& __x)
 
  401        __glibcxx_check_insert(__position);
 
  402        return iterator(_Base::insert(__position.base(), __x), this);
 
  405 #if __cplusplus >= 201103L
 
  407       insert(const_iterator __position, _Tp&& __x)
 
  408       { return emplace(__position, std::move(__x)); }
 
  411       insert(const_iterator __p, initializer_list<value_type> __l)
 
  413    __glibcxx_check_insert(__p);
 
  414    return iterator(_Base::insert(__p.base(), __l), this);
 
  418 #if __cplusplus >= 201103L
 
  420       insert(const_iterator __position, size_type __n, const _Tp& __x)
 
  422    __glibcxx_check_insert(__position);
 
  423    return iterator(_Base::insert(__position.base(), __n, __x), this);
 
  427       insert(iterator __position, size_type __n, const _Tp& __x)
 
  429    __glibcxx_check_insert(__position);
 
  430    _Base::insert(__position.base(), __n, __x);
 
  434 #if __cplusplus >= 201103L
 
  435       template<class _InputIterator,
 
  436           typename = std::_RequireInputIter<_InputIterator>>
 
  438         insert(const_iterator __position, _InputIterator __first,
 
  439           _InputIterator __last)
 
  441      __glibcxx_check_insert_range(__position, __first, __last);
 
  442      return iterator(_Base::insert(__position.base(),
 
  443                    __gnu_debug::__base(__first),
 
  444                    __gnu_debug::__base(__last)),
 
  448       template<class _InputIterator>
 
  450         insert(iterator __position, _InputIterator __first,
 
  451           _InputIterator __last)
 
  453      __glibcxx_check_insert_range(__position, __first, __last);
 
  454      _Base::insert(__position.base(), __gnu_debug::__base(__first),
 
  455                       __gnu_debug::__base(__last));
 
  461 #if __cplusplus >= 201103L
 
  462       _M_erase(_Base_const_iterator __position) noexcept
 
  464       _M_erase(_Base_iterator __position)
 
  467    this->_M_invalidate_if(_Equal(__position));
 
  468    return _Base::erase(__position);
 
  473 #if __cplusplus >= 201103L
 
  474       erase(const_iterator __position) noexcept
 
  476       erase(iterator __position)
 
  479    __glibcxx_check_erase(__position);
 
  480    return iterator(_M_erase(__position.base()), this);
 
  484 #if __cplusplus >= 201103L
 
  485       erase(const_iterator __first, const_iterator __last) noexcept
 
  487       erase(iterator __first, iterator __last)
 
  490    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  491    // 151. can't currently clear() empty container
 
  492    __glibcxx_check_erase_range(__first, __last);
 
  493    for (_Base_const_iterator __victim = __first.base();
 
  494         __victim != __last.base(); ++__victim)
 
  496        _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
 
  497                      _M_message(__gnu_debug::__msg_valid_range)
 
  498                  ._M_iterator(__first, "position")
 
  499                  ._M_iterator(__last, "last"));
 
  500        this->_M_invalidate_if(_Equal(__victim));
 
  502    return iterator(_Base::erase(__first.base(), __last.base()), this);
 
  513       clear() _GLIBCXX_NOEXCEPT
 
  516    this->_M_invalidate_all();
 
  519       // 23.2.2.4 list operations:
 
  521 #if __cplusplus >= 201103L
 
  522       splice(const_iterator __position, list&& __x) noexcept
 
  524       splice(iterator __position, list& __x)
 
  527    _GLIBCXX_DEBUG_VERIFY(&__x != this,
 
  528                  _M_message(__gnu_debug::__msg_self_splice)
 
  529                  ._M_sequence(*this, "this"));
 
  530    this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
 
  531    _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
 
  534 #if __cplusplus >= 201103L
 
  536       splice(const_iterator __position, list& __x) noexcept
 
  537       { splice(__position, std::move(__x)); }
 
  541 #if __cplusplus >= 201103L
 
  542       splice(const_iterator __position, list&& __x, const_iterator __i) noexcept
 
  544       splice(iterator __position, list& __x, iterator __i)
 
  547    __glibcxx_check_insert(__position);
 
  549    // We used to perform the splice_alloc check:  not anymore, redundant
 
  550    // after implementing the relevant bits of N1599.
 
  552    _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
 
  553                  _M_message(__gnu_debug::__msg_splice_bad)
 
  554                  ._M_iterator(__i, "__i"));
 
  555    _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
 
  556                  _M_message(__gnu_debug::__msg_splice_other)
 
  557                 ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
 
  559    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  560    // 250. splicing invalidates iterators
 
  561    this->_M_transfer_from_if(__x, _Equal(__i.base()));
 
  562    _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
 
  566 #if __cplusplus >= 201103L
 
  568       splice(const_iterator __position, list& __x, const_iterator __i) noexcept
 
  569       { splice(__position, std::move(__x), __i); }
 
  573 #if __cplusplus >= 201103L
 
  574       splice(const_iterator __position, list&& __x, const_iterator __first,
 
  575         const_iterator __last) noexcept
 
  577       splice(iterator __position, list& __x, iterator __first,
 
  581    __glibcxx_check_insert(__position);
 
  582    __glibcxx_check_valid_range(__first, __last);
 
  583    _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
 
  584                  _M_message(__gnu_debug::__msg_splice_other)
 
  585                  ._M_sequence(__x, "x")
 
  586                  ._M_iterator(__first, "first"));
 
  588    // We used to perform the splice_alloc check:  not anymore, redundant
 
  589    // after implementing the relevant bits of N1599.
 
  591    for (_Base_const_iterator __tmp = __first.base();
 
  592         __tmp != __last.base(); ++__tmp)
 
  594        _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
 
  595                  _M_message(__gnu_debug::__msg_valid_range)
 
  596                  ._M_iterator(__first, "first")
 
  597                  ._M_iterator(__last, "last"));
 
  598        _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position.base(),
 
  599                _M_message(__gnu_debug::__msg_splice_overlap)
 
  600                  ._M_iterator(__tmp, "position")
 
  601                  ._M_iterator(__first, "first")
 
  602                  ._M_iterator(__last, "last"));
 
  603        // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  604        // 250. splicing invalidates iterators
 
  605        this->_M_transfer_from_if(__x, _Equal(__tmp));
 
  608    _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
 
  609              __first.base(), __last.base());
 
  612 #if __cplusplus >= 201103L
 
  614       splice(const_iterator __position, list& __x,
 
  615         const_iterator __first, const_iterator __last) noexcept
 
  616       { splice(__position, std::move(__x), __first, __last); }
 
  620       remove(const _Tp& __value)
 
  622    for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
 
  631       template<class _Predicate>
 
  633         remove_if(_Predicate __pred)
 
  635      for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
 
  647    _Base_iterator __first = _Base::begin();
 
  648    _Base_iterator __last = _Base::end();
 
  649    if (__first == __last)
 
  651    _Base_iterator __next = __first; ++__next;
 
  652    while (__next != __last)
 
  654        if (*__first == *__next)
 
  655          __next = _M_erase(__next);
 
  661       template<class _BinaryPredicate>
 
  663         unique(_BinaryPredicate __binary_pred)
 
  665      _Base_iterator __first = _Base::begin();
 
  666      _Base_iterator __last = _Base::end();
 
  667      if (__first == __last)
 
  669      _Base_iterator __next = __first; ++__next;
 
  670      while (__next != __last)
 
  672          if (__binary_pred(*__first, *__next))
 
  673        __next = _M_erase(__next);
 
  680 #if __cplusplus >= 201103L
 
  686    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  687    // 300. list::merge() specification incomplete
 
  690        __glibcxx_check_sorted(_Base::begin(), _Base::end());
 
  691        __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
 
  692        this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
 
  693        _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
 
  697 #if __cplusplus >= 201103L
 
  700       { merge(std::move(__x)); }
 
  703       template<class _Compare>
 
  705 #if __cplusplus >= 201103L
 
  706         merge(list&& __x, _Compare __comp)
 
  708         merge(list& __x, _Compare __comp)
 
  711      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  712      // 300. list::merge() specification incomplete
 
  715          __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
 
  717          __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
 
  719          this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
 
  720          _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
 
  724 #if __cplusplus >= 201103L
 
  725       template<typename _Compare>
 
  727         merge(list& __x, _Compare __comp)
 
  728         { merge(std::move(__x), __comp); }
 
  732       sort() { _Base::sort(); }
 
  734       template<typename _StrictWeakOrdering>
 
  736         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
 
  738       using _Base::reverse;
 
  741       _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
 
  744       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
  750    this->_M_invalidate_if(_Not_equal(_Base::end()));
 
  754   template<typename _Tp, typename _Alloc>
 
  756     operator==(const list<_Tp, _Alloc>& __lhs,
 
  757           const list<_Tp, _Alloc>& __rhs)
 
  758     { return __lhs._M_base() == __rhs._M_base(); }
 
  760   template<typename _Tp, typename _Alloc>
 
  762     operator!=(const list<_Tp, _Alloc>& __lhs,
 
  763           const list<_Tp, _Alloc>& __rhs)
 
  764     { return __lhs._M_base() != __rhs._M_base(); }
 
  766   template<typename _Tp, typename _Alloc>
 
  768     operator<(const list<_Tp, _Alloc>& __lhs,
 
  769          const list<_Tp, _Alloc>& __rhs)
 
  770     { return __lhs._M_base() < __rhs._M_base(); }
 
  772   template<typename _Tp, typename _Alloc>
 
  774     operator<=(const list<_Tp, _Alloc>& __lhs,
 
  775           const list<_Tp, _Alloc>& __rhs)
 
  776     { return __lhs._M_base() <= __rhs._M_base(); }
 
  778   template<typename _Tp, typename _Alloc>
 
  780     operator>=(const list<_Tp, _Alloc>& __lhs,
 
  781           const list<_Tp, _Alloc>& __rhs)
 
  782     { return __lhs._M_base() >= __rhs._M_base(); }
 
  784   template<typename _Tp, typename _Alloc>
 
  786     operator>(const list<_Tp, _Alloc>& __lhs,
 
  787          const list<_Tp, _Alloc>& __rhs)
 
  788     { return __lhs._M_base() > __rhs._M_base(); }
 
  790   template<typename _Tp, typename _Alloc>
 
  792     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
 
  793     { __lhs.swap(__rhs); }
 
  795 } // namespace __debug
 
  798 #ifndef _GLIBCXX_DEBUG_PEDANTIC
 
  799 namespace __gnu_debug
 
  801   template<class _Tp, class _Alloc>
 
  802     struct _Insert_range_from_self_is_safe<std::__debug::list<_Tp, _Alloc> >
 
  803     { enum { __value = 1 }; };