Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Debugging list implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-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 debug/list
  26.  *  This file is a GNU debug extension to the Standard C++ Library.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_DEBUG_LIST
  30. #define _GLIBCXX_DEBUG_LIST 1
  31.  
  32. #include <list>
  33. #include <debug/safe_sequence.h>
  34. #include <debug/safe_iterator.h>
  35.  
  36. namespace std _GLIBCXX_VISIBILITY(default)
  37. {
  38. namespace __debug
  39. {
  40.   /// Class std::list with safety/checking/debug instrumentation.
  41.   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
  42.     class list
  43.     : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
  44.       public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
  45.     {
  46.       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
  47.  
  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;
  52.     public:
  53.       typedef typename _Base::reference             reference;
  54.       typedef typename _Base::const_reference       const_reference;
  55.  
  56.       typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
  57.                                                     iterator;
  58.       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
  59.                                                     const_iterator;
  60.  
  61.       typedef typename _Base::size_type             size_type;
  62.       typedef typename _Base::difference_type       difference_type;
  63.  
  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;
  70.  
  71.       // 23.2.2.1 construct/copy/destroy:
  72.       explicit
  73.       list(const _Allocator& __a = _Allocator())
  74.       : _Base(__a) { }
  75.  
  76. #if __cplusplus >= 201103L
  77.       explicit
  78.       list(size_type __n)
  79.       : _Base(__n) { }
  80.  
  81.       list(size_type __n, const _Tp& __value,
  82.            const _Allocator& __a = _Allocator())
  83.       : _Base(__n, __value, __a) { }
  84. #else
  85.       explicit
  86.       list(size_type __n, const _Tp& __value = _Tp(),
  87.            const _Allocator& __a = _Allocator())
  88.       : _Base(__n, __value, __a) { }
  89. #endif
  90.  
  91. #if __cplusplus >= 201103L
  92.       template<class _InputIterator,
  93.                typename = std::_RequireInputIter<_InputIterator>>
  94. #else
  95.       template<class _InputIterator>
  96. #endif
  97.         list(_InputIterator __first, _InputIterator __last,
  98.              const _Allocator& __a = _Allocator())
  99.         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
  100.                                                                      __last)),
  101.                 __gnu_debug::__base(__last), __a)
  102.         { }
  103.  
  104.       list(const list& __x)
  105.       : _Base(__x) { }
  106.  
  107.       list(const _Base& __x)
  108.       : _Base(__x) { }
  109.  
  110. #if __cplusplus >= 201103L
  111.       list(list&& __x) noexcept
  112.       : _Base(std::move(__x))
  113.       { this->_M_swap(__x); }
  114.  
  115.       list(initializer_list<value_type> __l,
  116.            const allocator_type& __a = allocator_type())
  117.         : _Base(__l, __a) { }
  118. #endif
  119.  
  120.       ~list() _GLIBCXX_NOEXCEPT { }
  121.  
  122.       list&
  123.       operator=(const list& __x)
  124.       {
  125.         static_cast<_Base&>(*this) = __x;
  126.         this->_M_invalidate_all();
  127.         return *this;
  128.       }
  129.  
  130. #if __cplusplus >= 201103L
  131.       list&
  132.       operator=(list&& __x)
  133.       {
  134.         // NB: DR 1204.
  135.         // NB: DR 675.
  136.         __glibcxx_check_self_move_assign(__x);
  137.         clear();
  138.         swap(__x);
  139.         return *this;
  140.       }
  141.  
  142.       list&
  143.       operator=(initializer_list<value_type> __l)
  144.       {
  145.         static_cast<_Base&>(*this) = __l;
  146.         this->_M_invalidate_all();
  147.         return *this;
  148.       }
  149.  
  150.       void
  151.       assign(initializer_list<value_type> __l)
  152.       {
  153.         _Base::assign(__l);
  154.         this->_M_invalidate_all();
  155.       }
  156. #endif
  157.  
  158. #if __cplusplus >= 201103L
  159.       template<class _InputIterator,
  160.                typename = std::_RequireInputIter<_InputIterator>>
  161. #else
  162.       template<class _InputIterator>
  163. #endif
  164.         void
  165.         assign(_InputIterator __first, _InputIterator __last)
  166.         {
  167.           __glibcxx_check_valid_range(__first, __last);
  168.           _Base::assign(__gnu_debug::__base(__first),
  169.                         __gnu_debug::__base(__last));
  170.           this->_M_invalidate_all();
  171.         }
  172.  
  173.       void
  174.       assign(size_type __n, const _Tp& __t)
  175.       {
  176.         _Base::assign(__n, __t);
  177.         this->_M_invalidate_all();
  178.       }
  179.  
  180.       using _Base::get_allocator;
  181.  
  182.       // iterators:
  183.       iterator
  184.       begin() _GLIBCXX_NOEXCEPT
  185.       { return iterator(_Base::begin(), this); }
  186.  
  187.       const_iterator
  188.       begin() const _GLIBCXX_NOEXCEPT
  189.       { return const_iterator(_Base::begin(), this); }
  190.  
  191.       iterator
  192.       end() _GLIBCXX_NOEXCEPT
  193.       { return iterator(_Base::end(), this); }
  194.  
  195.       const_iterator
  196.       end() const _GLIBCXX_NOEXCEPT
  197.       { return const_iterator(_Base::end(), this); }
  198.  
  199.       reverse_iterator
  200.       rbegin() _GLIBCXX_NOEXCEPT
  201.       { return reverse_iterator(end()); }
  202.  
  203.       const_reverse_iterator
  204.       rbegin() const _GLIBCXX_NOEXCEPT
  205.       { return const_reverse_iterator(end()); }
  206.  
  207.       reverse_iterator
  208.       rend() _GLIBCXX_NOEXCEPT
  209.       { return reverse_iterator(begin()); }
  210.  
  211.       const_reverse_iterator
  212.       rend() const _GLIBCXX_NOEXCEPT
  213.       { return const_reverse_iterator(begin()); }
  214.  
  215. #if __cplusplus >= 201103L
  216.       const_iterator
  217.       cbegin() const noexcept
  218.       { return const_iterator(_Base::begin(), this); }
  219.  
  220.       const_iterator
  221.       cend() const noexcept
  222.       { return const_iterator(_Base::end(), this); }
  223.  
  224.       const_reverse_iterator
  225.       crbegin() const noexcept
  226.       { return const_reverse_iterator(end()); }
  227.  
  228.       const_reverse_iterator
  229.       crend() const noexcept
  230.       { return const_reverse_iterator(begin()); }
  231. #endif
  232.  
  233.       // 23.2.2.2 capacity:
  234.       using _Base::empty;
  235.       using _Base::size;
  236.       using _Base::max_size;
  237.  
  238. #if __cplusplus >= 201103L
  239.       void
  240.       resize(size_type __sz)
  241.       {
  242.         this->_M_detach_singular();
  243.  
  244.         // if __sz < size(), invalidate all iterators in [begin+__sz, end())
  245.         _Base_iterator __victim = _Base::begin();
  246.         _Base_iterator __end = _Base::end();
  247.         for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
  248.           ++__victim;
  249.  
  250.         for (; __victim != __end; ++__victim)
  251.           {
  252.             this->_M_invalidate_if(_Equal(__victim));
  253.           }
  254.  
  255.         __try
  256.           {
  257.             _Base::resize(__sz);
  258.           }
  259.         __catch(...)
  260.           {
  261.             this->_M_revalidate_singular();
  262.             __throw_exception_again;
  263.           }
  264.       }
  265.  
  266.       void
  267.       resize(size_type __sz, const _Tp& __c)
  268.       {
  269.         this->_M_detach_singular();
  270.  
  271.         // if __sz < size(), invalidate all iterators in [begin+__sz, end())
  272.         _Base_iterator __victim = _Base::begin();
  273.         _Base_iterator __end = _Base::end();
  274.         for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
  275.           ++__victim;
  276.  
  277.         for (; __victim != __end; ++__victim)
  278.           {
  279.             this->_M_invalidate_if(_Equal(__victim));
  280.           }
  281.  
  282.         __try
  283.           {
  284.             _Base::resize(__sz, __c);
  285.           }
  286.         __catch(...)
  287.           {
  288.             this->_M_revalidate_singular();
  289.             __throw_exception_again;
  290.           }
  291.       }
  292. #else
  293.       void
  294.       resize(size_type __sz, _Tp __c = _Tp())
  295.       {
  296.         this->_M_detach_singular();
  297.  
  298.         // if __sz < size(), invalidate all iterators in [begin+__sz, end())
  299.         _Base_iterator __victim = _Base::begin();
  300.         _Base_iterator __end = _Base::end();
  301.         for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
  302.           ++__victim;
  303.  
  304.         for (; __victim != __end; ++__victim)
  305.           {
  306.             this->_M_invalidate_if(_Equal(__victim));
  307.           }
  308.  
  309.         __try
  310.           {
  311.             _Base::resize(__sz, __c);
  312.           }
  313.         __catch(...)
  314.           {
  315.             this->_M_revalidate_singular();
  316.             __throw_exception_again;
  317.           }
  318.       }
  319. #endif
  320.  
  321.       // element access:
  322.       reference
  323.       front()
  324.       {
  325.         __glibcxx_check_nonempty();
  326.         return _Base::front();
  327.       }
  328.  
  329.       const_reference
  330.       front() const
  331.       {
  332.         __glibcxx_check_nonempty();
  333.         return _Base::front();
  334.       }
  335.  
  336.       reference
  337.       back()
  338.       {
  339.         __glibcxx_check_nonempty();
  340.         return _Base::back();
  341.       }
  342.  
  343.       const_reference
  344.       back() const
  345.       {
  346.         __glibcxx_check_nonempty();
  347.         return _Base::back();
  348.       }
  349.  
  350.       // 23.2.2.3 modifiers:
  351.       using _Base::push_front;
  352.  
  353. #if __cplusplus >= 201103L
  354.       using _Base::emplace_front;
  355. #endif
  356.  
  357.       void
  358.       pop_front()
  359.       {
  360.         __glibcxx_check_nonempty();
  361.         this->_M_invalidate_if(_Equal(_Base::begin()));
  362.         _Base::pop_front();
  363.       }
  364.  
  365.       using _Base::push_back;
  366.  
  367. #if __cplusplus >= 201103L
  368.       using _Base::emplace_back;
  369. #endif
  370.  
  371.       void
  372.       pop_back()
  373.       {
  374.         __glibcxx_check_nonempty();
  375.         this->_M_invalidate_if(_Equal(--_Base::end()));
  376.         _Base::pop_back();
  377.       }
  378.  
  379. #if __cplusplus >= 201103L
  380.       template<typename... _Args>
  381.         iterator
  382.         emplace(iterator __position, _Args&&... __args)
  383.         {
  384.           __glibcxx_check_insert(__position);
  385.           return iterator(_Base::emplace(__position.base(),
  386.                                         std::forward<_Args>(__args)...), this);
  387.         }
  388. #endif
  389.  
  390.       iterator
  391.       insert(iterator __position, const _Tp& __x)
  392.       {
  393.         __glibcxx_check_insert(__position);
  394.         return iterator(_Base::insert(__position.base(), __x), this);
  395.       }
  396.  
  397. #if __cplusplus >= 201103L
  398.       iterator
  399.       insert(iterator __position, _Tp&& __x)
  400.       { return emplace(__position, std::move(__x)); }
  401.  
  402.       void
  403.       insert(iterator __p, initializer_list<value_type> __l)
  404.       {
  405.         __glibcxx_check_insert(__p);
  406.         _Base::insert(__p.base(), __l);
  407.       }
  408. #endif
  409.  
  410.       void
  411.       insert(iterator __position, size_type __n, const _Tp& __x)
  412.       {
  413.         __glibcxx_check_insert(__position);
  414.         _Base::insert(__position.base(), __n, __x);
  415.       }
  416.  
  417. #if __cplusplus >= 201103L
  418.       template<class _InputIterator,
  419.                typename = std::_RequireInputIter<_InputIterator>>
  420. #else
  421.       template<class _InputIterator>
  422. #endif
  423.         void
  424.         insert(iterator __position, _InputIterator __first,
  425.                _InputIterator __last)
  426.         {
  427.           __glibcxx_check_insert_range(__position, __first, __last);
  428.           _Base::insert(__position.base(), __gnu_debug::__base(__first),
  429.                                            __gnu_debug::__base(__last));
  430.         }
  431.  
  432.     private:
  433.       _Base_iterator
  434.       _M_erase(_Base_iterator __position)
  435.       {
  436.         this->_M_invalidate_if(_Equal(__position));
  437.         return _Base::erase(__position);
  438.       }
  439.     public:
  440.       iterator
  441.       erase(iterator __position)
  442.       {
  443.         __glibcxx_check_erase(__position);
  444.         return iterator(_M_erase(__position.base()), this);
  445.       }
  446.  
  447.       iterator
  448.       erase(iterator __position, iterator __last)
  449.       {
  450.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  451.         // 151. can't currently clear() empty container
  452.         __glibcxx_check_erase_range(__position, __last);
  453.         for (_Base_iterator __victim = __position.base();
  454.              __victim != __last.base(); ++__victim)
  455.           {
  456.             _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
  457.                                   _M_message(__gnu_debug::__msg_valid_range)
  458.                                   ._M_iterator(__position, "position")
  459.                                   ._M_iterator(__last, "last"));
  460.             this->_M_invalidate_if(_Equal(__victim));
  461.           }
  462.         return iterator(_Base::erase(__position.base(), __last.base()), this);
  463.       }
  464.  
  465.       void
  466.       swap(list& __x)
  467.       {
  468.         _Base::swap(__x);
  469.         this->_M_swap(__x);
  470.       }
  471.  
  472.       void
  473.       clear() _GLIBCXX_NOEXCEPT
  474.       {
  475.         _Base::clear();
  476.         this->_M_invalidate_all();
  477.       }
  478.  
  479.       // 23.2.2.4 list operations:
  480.       void
  481. #if __cplusplus >= 201103L
  482.       splice(iterator __position, list&& __x)
  483. #else
  484.       splice(iterator __position, list& __x)
  485. #endif
  486.       {
  487.         _GLIBCXX_DEBUG_VERIFY(&__x != this,
  488.                               _M_message(__gnu_debug::__msg_self_splice)
  489.                               ._M_sequence(*this, "this"));
  490.         this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
  491.         _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
  492.       }
  493.  
  494. #if __cplusplus >= 201103L
  495.       void
  496.       splice(iterator __position, list& __x)
  497.       { splice(__position, std::move(__x)); }
  498. #endif
  499.  
  500.       void
  501. #if __cplusplus >= 201103L
  502.       splice(iterator __position, list&& __x, iterator __i)
  503. #else
  504.       splice(iterator __position, list& __x, iterator __i)
  505. #endif
  506.       {
  507.         __glibcxx_check_insert(__position);
  508.  
  509.         // We used to perform the splice_alloc check:  not anymore, redundant
  510.         // after implementing the relevant bits of N1599.
  511.  
  512.         _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
  513.                               _M_message(__gnu_debug::__msg_splice_bad)
  514.                               ._M_iterator(__i, "__i"));
  515.         _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
  516.                               _M_message(__gnu_debug::__msg_splice_other)
  517.                              ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
  518.  
  519.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  520.         // 250. splicing invalidates iterators
  521.         this->_M_transfer_from_if(__x, _Equal(__i.base()));
  522.         _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
  523.                       __i.base());
  524.       }
  525.  
  526. #if __cplusplus >= 201103L
  527.       void
  528.       splice(iterator __position, list& __x, iterator __i)
  529.       { splice(__position, std::move(__x), __i); }
  530. #endif
  531.  
  532.       void
  533. #if __cplusplus >= 201103L
  534.       splice(iterator __position, list&& __x, iterator __first,
  535.              iterator __last)
  536. #else
  537.       splice(iterator __position, list& __x, iterator __first,
  538.              iterator __last)
  539. #endif
  540.       {
  541.         __glibcxx_check_insert(__position);
  542.         __glibcxx_check_valid_range(__first, __last);
  543.         _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
  544.                               _M_message(__gnu_debug::__msg_splice_other)
  545.                               ._M_sequence(__x, "x")
  546.                               ._M_iterator(__first, "first"));
  547.  
  548.         // We used to perform the splice_alloc check:  not anymore, redundant
  549.         // after implementing the relevant bits of N1599.
  550.  
  551.         for (_Base_iterator __tmp = __first.base();
  552.              __tmp != __last.base(); ++__tmp)
  553.           {
  554.             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
  555.                                   _M_message(__gnu_debug::__msg_valid_range)
  556.                                   ._M_iterator(__first, "first")
  557.                                   ._M_iterator(__last, "last"));
  558.             _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
  559.                                 _M_message(__gnu_debug::__msg_splice_overlap)
  560.                                   ._M_iterator(__tmp, "position")
  561.                                   ._M_iterator(__first, "first")
  562.                                   ._M_iterator(__last, "last"));
  563.             // _GLIBCXX_RESOLVE_LIB_DEFECTS
  564.             // 250. splicing invalidates iterators
  565.             this->_M_transfer_from_if(__x, _Equal(__tmp));
  566.           }
  567.  
  568.         _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
  569.                       __first.base(), __last.base());
  570.       }
  571.  
  572. #if __cplusplus >= 201103L
  573.       void
  574.       splice(iterator __position, list& __x, iterator __first, iterator __last)
  575.       { splice(__position, std::move(__x), __first, __last); }
  576. #endif
  577.  
  578.       void
  579.       remove(const _Tp& __value)
  580.       {
  581.         for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
  582.           {
  583.             if (*__x == __value)
  584.               __x = _M_erase(__x);
  585.             else
  586.               ++__x;
  587.           }
  588.       }
  589.  
  590.       template<class _Predicate>
  591.         void
  592.         remove_if(_Predicate __pred)
  593.         {
  594.           for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
  595.             {
  596.               if (__pred(*__x))
  597.                 __x = _M_erase(__x);
  598.               else
  599.                 ++__x;
  600.             }
  601.         }
  602.  
  603.       void
  604.       unique()
  605.       {
  606.         _Base_iterator __first = _Base::begin();
  607.         _Base_iterator __last = _Base::end();
  608.         if (__first == __last)
  609.           return;
  610.         _Base_iterator __next = __first; ++__next;
  611.         while (__next != __last)
  612.           {
  613.             if (*__first == *__next)
  614.               __next = _M_erase(__next);
  615.             else
  616.               __first = __next++;
  617.           }
  618.       }
  619.  
  620.       template<class _BinaryPredicate>
  621.         void
  622.         unique(_BinaryPredicate __binary_pred)
  623.         {
  624.           _Base_iterator __first = _Base::begin();
  625.           _Base_iterator __last = _Base::end();
  626.           if (__first == __last)
  627.             return;
  628.           _Base_iterator __next = __first; ++__next;
  629.           while (__next != __last)
  630.             {
  631.               if (__binary_pred(*__first, *__next))
  632.                 __next = _M_erase(__next);
  633.               else
  634.                 __first = __next++;
  635.             }
  636.         }
  637.  
  638.       void
  639. #if __cplusplus >= 201103L
  640.       merge(list&& __x)
  641. #else
  642.       merge(list& __x)
  643. #endif
  644.       {
  645.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  646.         // 300. list::merge() specification incomplete
  647.         if (this != &__x)
  648.           {
  649.             __glibcxx_check_sorted(_Base::begin(), _Base::end());
  650.             __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
  651.             this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
  652.             _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
  653.           }
  654.       }
  655.  
  656. #if __cplusplus >= 201103L
  657.       void
  658.       merge(list& __x)
  659.       { merge(std::move(__x)); }
  660. #endif
  661.  
  662.       template<class _Compare>
  663.         void
  664. #if __cplusplus >= 201103L
  665.         merge(list&& __x, _Compare __comp)
  666. #else
  667.         merge(list& __x, _Compare __comp)
  668. #endif
  669.         {
  670.           // _GLIBCXX_RESOLVE_LIB_DEFECTS
  671.           // 300. list::merge() specification incomplete
  672.           if (this != &__x)
  673.             {
  674.               __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
  675.                                           __comp);
  676.               __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
  677.                                           __comp);
  678.               this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
  679.               _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
  680.             }
  681.         }
  682.  
  683. #if __cplusplus >= 201103L
  684.       template<typename _Compare>
  685.         void
  686.         merge(list& __x, _Compare __comp)
  687.         { merge(std::move(__x), __comp); }
  688. #endif
  689.  
  690.       void
  691.       sort() { _Base::sort(); }
  692.  
  693.       template<typename _StrictWeakOrdering>
  694.         void
  695.         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
  696.  
  697.       using _Base::reverse;
  698.  
  699.       _Base&
  700.       _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
  701.  
  702.       const _Base&
  703.       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  704.  
  705.     private:
  706.       void
  707.       _M_invalidate_all()
  708.       {
  709.         this->_M_invalidate_if(_Not_equal(_Base::end()));
  710.       }
  711.     };
  712.  
  713.   template<typename _Tp, typename _Alloc>
  714.     inline bool
  715.     operator==(const list<_Tp, _Alloc>& __lhs,
  716.                const list<_Tp, _Alloc>& __rhs)
  717.     { return __lhs._M_base() == __rhs._M_base(); }
  718.  
  719.   template<typename _Tp, typename _Alloc>
  720.     inline bool
  721.     operator!=(const list<_Tp, _Alloc>& __lhs,
  722.                const list<_Tp, _Alloc>& __rhs)
  723.     { return __lhs._M_base() != __rhs._M_base(); }
  724.  
  725.   template<typename _Tp, typename _Alloc>
  726.     inline bool
  727.     operator<(const list<_Tp, _Alloc>& __lhs,
  728.               const list<_Tp, _Alloc>& __rhs)
  729.     { return __lhs._M_base() < __rhs._M_base(); }
  730.  
  731.   template<typename _Tp, typename _Alloc>
  732.     inline bool
  733.     operator<=(const list<_Tp, _Alloc>& __lhs,
  734.                const list<_Tp, _Alloc>& __rhs)
  735.     { return __lhs._M_base() <= __rhs._M_base(); }
  736.  
  737.   template<typename _Tp, typename _Alloc>
  738.     inline bool
  739.     operator>=(const list<_Tp, _Alloc>& __lhs,
  740.                const list<_Tp, _Alloc>& __rhs)
  741.     { return __lhs._M_base() >= __rhs._M_base(); }
  742.  
  743.   template<typename _Tp, typename _Alloc>
  744.     inline bool
  745.     operator>(const list<_Tp, _Alloc>& __lhs,
  746.               const list<_Tp, _Alloc>& __rhs)
  747.     { return __lhs._M_base() > __rhs._M_base(); }
  748.  
  749.   template<typename _Tp, typename _Alloc>
  750.     inline void
  751.     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
  752.     { __lhs.swap(__rhs); }
  753.  
  754. } // namespace __debug
  755. } // namespace std
  756.  
  757. #endif
  758.