libstdc++
debug/list
Go to the documentation of this file.
00001 // Debugging list implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file debug/list
00027  *  This file is a GNU debug extension to the Standard C++ Library.
00028  */
00029 
00030 #ifndef _GLIBCXX_DEBUG_LIST
00031 #define _GLIBCXX_DEBUG_LIST 1
00032 
00033 #include <list>
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_iterator.h>
00036 
00037 namespace std _GLIBCXX_VISIBILITY(default)
00038 {
00039 namespace __debug
00040 {
00041   /// Class std::list with safety/checking/debug instrumentation.
00042   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
00043     class list
00044     : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
00045       public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
00046     {
00047       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
00048 
00049       typedef typename _Base::iterator       _Base_iterator;
00050       typedef typename _Base::const_iterator _Base_const_iterator;
00051       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
00052       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00053     public:
00054       typedef typename _Base::reference             reference;
00055       typedef typename _Base::const_reference       const_reference;
00056 
00057       typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
00058                             iterator;
00059       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
00060                             const_iterator;
00061 
00062       typedef typename _Base::size_type             size_type;
00063       typedef typename _Base::difference_type       difference_type;
00064 
00065       typedef _Tp                   value_type;
00066       typedef _Allocator                allocator_type;
00067       typedef typename _Base::pointer               pointer;
00068       typedef typename _Base::const_pointer         const_pointer;
00069       typedef std::reverse_iterator<iterator>       reverse_iterator;
00070       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00071 
00072       // 23.2.2.1 construct/copy/destroy:
00073       explicit
00074       list(const _Allocator& __a = _Allocator())
00075       : _Base(__a) { }
00076 
00077 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00078       explicit
00079       list(size_type __n)
00080       : _Base(__n) { }
00081 
00082       list(size_type __n, const _Tp& __value,
00083        const _Allocator& __a = _Allocator())
00084       : _Base(__n, __value, __a) { }
00085 #else
00086       explicit
00087       list(size_type __n, const _Tp& __value = _Tp(),
00088        const _Allocator& __a = _Allocator())
00089       : _Base(__n, __value, __a) { }
00090 #endif
00091 
00092       template<class _InputIterator>
00093       list(_InputIterator __first, _InputIterator __last,
00094        const _Allocator& __a = _Allocator())
00095       : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00096                                    __last)),
00097               __gnu_debug::__base(__last), __a)
00098       { }
00099 
00100 
00101       list(const list& __x)
00102       : _Base(__x) { }
00103 
00104       list(const _Base& __x)
00105       : _Base(__x) { }
00106 
00107 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00108       list(list&& __x) noexcept
00109       : _Base(std::move(__x))
00110       { this->_M_swap(__x); }
00111 
00112       list(initializer_list<value_type> __l,
00113            const allocator_type& __a = allocator_type())
00114         : _Base(__l, __a) { }
00115 #endif
00116 
00117       ~list() _GLIBCXX_NOEXCEPT { }
00118 
00119       list&
00120       operator=(const list& __x)
00121       {
00122     static_cast<_Base&>(*this) = __x;
00123     this->_M_invalidate_all();
00124     return *this;
00125       }
00126 
00127 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00128       list&
00129       operator=(list&& __x)
00130       {
00131     // NB: DR 1204.
00132     // NB: DR 675.
00133     clear();
00134     swap(__x);
00135         return *this;
00136       }
00137 
00138       list&
00139       operator=(initializer_list<value_type> __l)
00140       {
00141     static_cast<_Base&>(*this) = __l;
00142     this->_M_invalidate_all();
00143     return *this;
00144       }
00145 
00146       void
00147       assign(initializer_list<value_type> __l)
00148       {
00149     _Base::assign(__l);
00150     this->_M_invalidate_all();
00151       }
00152 #endif
00153 
00154       template<class _InputIterator>
00155         void
00156         assign(_InputIterator __first, _InputIterator __last)
00157         {
00158       __glibcxx_check_valid_range(__first, __last);
00159       _Base::assign(__gnu_debug::__base(__first),
00160             __gnu_debug::__base(__last));
00161       this->_M_invalidate_all();
00162     }
00163 
00164       void
00165       assign(size_type __n, const _Tp& __t)
00166       {
00167     _Base::assign(__n, __t);
00168     this->_M_invalidate_all();
00169       }
00170 
00171       using _Base::get_allocator;
00172 
00173       // iterators:
00174       iterator
00175       begin() _GLIBCXX_NOEXCEPT
00176       { return iterator(_Base::begin(), this); }
00177 
00178       const_iterator
00179       begin() const _GLIBCXX_NOEXCEPT
00180       { return const_iterator(_Base::begin(), this); }
00181 
00182       iterator
00183       end() _GLIBCXX_NOEXCEPT
00184       { return iterator(_Base::end(), this); }
00185 
00186       const_iterator
00187       end() const _GLIBCXX_NOEXCEPT
00188       { return const_iterator(_Base::end(), this); }
00189 
00190       reverse_iterator
00191       rbegin() _GLIBCXX_NOEXCEPT
00192       { return reverse_iterator(end()); }
00193 
00194       const_reverse_iterator
00195       rbegin() const _GLIBCXX_NOEXCEPT
00196       { return const_reverse_iterator(end()); }
00197 
00198       reverse_iterator
00199       rend() _GLIBCXX_NOEXCEPT
00200       { return reverse_iterator(begin()); }
00201 
00202       const_reverse_iterator
00203       rend() const _GLIBCXX_NOEXCEPT
00204       { return const_reverse_iterator(begin()); }
00205 
00206 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00207       const_iterator
00208       cbegin() const noexcept
00209       { return const_iterator(_Base::begin(), this); }
00210 
00211       const_iterator
00212       cend() const noexcept
00213       { return const_iterator(_Base::end(), this); }
00214 
00215       const_reverse_iterator
00216       crbegin() const noexcept
00217       { return const_reverse_iterator(end()); }
00218 
00219       const_reverse_iterator
00220       crend() const noexcept
00221       { return const_reverse_iterator(begin()); }
00222 #endif
00223 
00224       // 23.2.2.2 capacity:
00225       using _Base::empty;
00226       using _Base::size;
00227       using _Base::max_size;
00228 
00229 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00230       void
00231       resize(size_type __sz)
00232       {
00233     this->_M_detach_singular();
00234 
00235     // if __sz < size(), invalidate all iterators in [begin+__sz, end())
00236     _Base_iterator __victim = _Base::begin();
00237     _Base_iterator __end = _Base::end();
00238     for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
00239       ++__victim;
00240 
00241     for (; __victim != __end; ++__victim)
00242       {
00243         this->_M_invalidate_if(_Equal(__victim));
00244       }
00245 
00246     __try
00247       {
00248         _Base::resize(__sz);
00249       }
00250     __catch(...)
00251       {
00252         this->_M_revalidate_singular();
00253         __throw_exception_again;
00254       }
00255       }
00256 
00257       void
00258       resize(size_type __sz, const _Tp& __c)
00259       {
00260     this->_M_detach_singular();
00261 
00262     // if __sz < size(), invalidate all iterators in [begin+__sz, end())
00263     _Base_iterator __victim = _Base::begin();
00264     _Base_iterator __end = _Base::end();
00265     for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
00266       ++__victim;
00267 
00268     for (; __victim != __end; ++__victim)
00269       {
00270         this->_M_invalidate_if(_Equal(__victim));
00271       }
00272 
00273     __try
00274       {
00275         _Base::resize(__sz, __c);
00276       }
00277     __catch(...)
00278       {
00279         this->_M_revalidate_singular();
00280         __throw_exception_again;
00281       }
00282       }
00283 #else
00284       void
00285       resize(size_type __sz, _Tp __c = _Tp())
00286       {
00287     this->_M_detach_singular();
00288 
00289     // if __sz < size(), invalidate all iterators in [begin+__sz, end())
00290     _Base_iterator __victim = _Base::begin();
00291     _Base_iterator __end = _Base::end();
00292     for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
00293       ++__victim;
00294 
00295     for (; __victim != __end; ++__victim)
00296       {
00297         this->_M_invalidate_if(_Equal(__victim));
00298       }
00299 
00300     __try
00301       {
00302         _Base::resize(__sz, __c);
00303       }
00304     __catch(...)
00305       {
00306         this->_M_revalidate_singular();
00307         __throw_exception_again;
00308       }
00309       }
00310 #endif
00311 
00312       // element access:
00313       reference
00314       front()
00315       {
00316     __glibcxx_check_nonempty();
00317     return _Base::front();
00318       }
00319 
00320       const_reference
00321       front() const
00322       {
00323     __glibcxx_check_nonempty();
00324     return _Base::front();
00325       }
00326 
00327       reference
00328       back()
00329       {
00330     __glibcxx_check_nonempty();
00331     return _Base::back();
00332       }
00333 
00334       const_reference
00335       back() const
00336       {
00337     __glibcxx_check_nonempty();
00338     return _Base::back();
00339       }
00340 
00341       // 23.2.2.3 modifiers:
00342       using _Base::push_front;
00343 
00344 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00345       using _Base::emplace_front;
00346 #endif
00347 
00348       void
00349       pop_front()
00350       {
00351     __glibcxx_check_nonempty();
00352     this->_M_invalidate_if(_Equal(_Base::begin()));
00353     _Base::pop_front();
00354       }
00355 
00356       using _Base::push_back;
00357 
00358 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00359       using _Base::emplace_back;
00360 #endif
00361 
00362       void
00363       pop_back()
00364       {
00365     __glibcxx_check_nonempty();
00366     this->_M_invalidate_if(_Equal(--_Base::end()));
00367     _Base::pop_back();
00368       }
00369 
00370 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00371       template<typename... _Args>
00372         iterator
00373         emplace(iterator __position, _Args&&... __args)
00374     {
00375       __glibcxx_check_insert(__position);
00376       return iterator(_Base::emplace(__position.base(),
00377                     std::forward<_Args>(__args)...), this);
00378     }
00379 #endif
00380 
00381       iterator
00382       insert(iterator __position, const _Tp& __x)
00383       {
00384     __glibcxx_check_insert(__position);
00385     return iterator(_Base::insert(__position.base(), __x), this);
00386       }
00387 
00388 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00389       iterator
00390       insert(iterator __position, _Tp&& __x)
00391       { return emplace(__position, std::move(__x)); }
00392 
00393       void
00394       insert(iterator __p, initializer_list<value_type> __l)
00395       {
00396     __glibcxx_check_insert(__p);
00397     _Base::insert(__p.base(), __l);
00398       }
00399 #endif
00400 
00401       void
00402       insert(iterator __position, size_type __n, const _Tp& __x)
00403       {
00404     __glibcxx_check_insert(__position);
00405     _Base::insert(__position.base(), __n, __x);
00406       }
00407 
00408       template<class _InputIterator>
00409         void
00410         insert(iterator __position, _InputIterator __first,
00411            _InputIterator __last)
00412         {
00413       __glibcxx_check_insert_range(__position, __first, __last);
00414       _Base::insert(__position.base(), __gnu_debug::__base(__first),
00415                        __gnu_debug::__base(__last));
00416     }
00417 
00418     private:
00419       _Base_iterator
00420       _M_erase(_Base_iterator __position)
00421       {
00422     this->_M_invalidate_if(_Equal(__position));
00423     return _Base::erase(__position);
00424       }
00425     public:
00426       iterator
00427       erase(iterator __position)
00428       {
00429     __glibcxx_check_erase(__position);
00430     return iterator(_M_erase(__position.base()), this);
00431       }
00432 
00433       iterator
00434       erase(iterator __position, iterator __last)
00435       {
00436     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00437     // 151. can't currently clear() empty container
00438     __glibcxx_check_erase_range(__position, __last);
00439     for (_Base_iterator __victim = __position.base();
00440          __victim != __last.base(); ++__victim)
00441       {
00442         _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
00443                       _M_message(__gnu_debug::__msg_valid_range)
00444                   ._M_iterator(__position, "position")
00445                   ._M_iterator(__last, "last"));
00446         this->_M_invalidate_if(_Equal(__victim));
00447       }
00448     return iterator(_Base::erase(__position.base(), __last.base()), this);
00449       }
00450 
00451       void
00452       swap(list& __x)
00453       {
00454     _Base::swap(__x);
00455     this->_M_swap(__x);
00456       }
00457 
00458       void
00459       clear() _GLIBCXX_NOEXCEPT
00460       {
00461     _Base::clear();
00462     this->_M_invalidate_all();
00463       }
00464 
00465       // 23.2.2.4 list operations:
00466       void
00467 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00468       splice(iterator __position, list&& __x)
00469 #else
00470       splice(iterator __position, list& __x)
00471 #endif
00472       {
00473     _GLIBCXX_DEBUG_VERIFY(&__x != this,
00474                   _M_message(__gnu_debug::__msg_self_splice)
00475                   ._M_sequence(*this, "this"));
00476     this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
00477     _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
00478       }
00479 
00480 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00481       void
00482       splice(iterator __position, list& __x)
00483       { splice(__position, std::move(__x)); }
00484 #endif
00485 
00486       void
00487 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00488       splice(iterator __position, list&& __x, iterator __i)
00489 #else
00490       splice(iterator __position, list& __x, iterator __i)
00491 #endif
00492       {
00493     __glibcxx_check_insert(__position);
00494 
00495     // We used to perform the splice_alloc check:  not anymore, redundant
00496     // after implementing the relevant bits of N1599.
00497 
00498     _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
00499                   _M_message(__gnu_debug::__msg_splice_bad)
00500                   ._M_iterator(__i, "__i"));
00501     _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
00502                   _M_message(__gnu_debug::__msg_splice_other)
00503                  ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
00504 
00505     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00506     // 250. splicing invalidates iterators
00507     this->_M_transfer_from_if(__x, _Equal(__i.base()));
00508     _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
00509               __i.base());
00510       }
00511 
00512 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00513       void
00514       splice(iterator __position, list& __x, iterator __i)
00515       { splice(__position, std::move(__x), __i); }
00516 #endif
00517 
00518       void
00519 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00520       splice(iterator __position, list&& __x, iterator __first,
00521          iterator __last)
00522 #else
00523       splice(iterator __position, list& __x, iterator __first,
00524          iterator __last)
00525 #endif
00526       {
00527     __glibcxx_check_insert(__position);
00528     __glibcxx_check_valid_range(__first, __last);
00529     _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
00530                   _M_message(__gnu_debug::__msg_splice_other)
00531                   ._M_sequence(__x, "x")
00532                   ._M_iterator(__first, "first"));
00533 
00534     // We used to perform the splice_alloc check:  not anymore, redundant
00535     // after implementing the relevant bits of N1599.
00536 
00537     for (_Base_iterator __tmp = __first.base();
00538          __tmp != __last.base(); ++__tmp)
00539       {
00540         _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
00541                   _M_message(__gnu_debug::__msg_valid_range)
00542                   ._M_iterator(__first, "first")
00543                   ._M_iterator(__last, "last"));
00544         _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
00545                 _M_message(__gnu_debug::__msg_splice_overlap)
00546                   ._M_iterator(__tmp, "position")
00547                   ._M_iterator(__first, "first")
00548                   ._M_iterator(__last, "last"));
00549         // _GLIBCXX_RESOLVE_LIB_DEFECTS
00550         // 250. splicing invalidates iterators
00551         this->_M_transfer_from_if(__x, _Equal(__tmp));
00552       }
00553 
00554     _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
00555               __first.base(), __last.base());
00556       }
00557 
00558 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00559       void
00560       splice(iterator __position, list& __x, iterator __first, iterator __last)
00561       { splice(__position, std::move(__x), __first, __last); }
00562 #endif
00563 
00564       void
00565       remove(const _Tp& __value)
00566       {
00567     for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
00568       {
00569         if (*__x == __value)
00570           __x = _M_erase(__x);
00571         else
00572           ++__x;
00573       }
00574       }
00575 
00576       template<class _Predicate>
00577         void
00578         remove_if(_Predicate __pred)
00579         {
00580       for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
00581         {
00582           if (__pred(*__x))
00583         __x = _M_erase(__x);
00584           else
00585         ++__x;
00586         }
00587     }
00588 
00589       void
00590       unique()
00591       {
00592     _Base_iterator __first = _Base::begin();
00593     _Base_iterator __last = _Base::end();
00594     if (__first == __last)
00595       return;
00596     _Base_iterator __next = __first; ++__next;
00597     while (__next != __last)
00598       {
00599         if (*__first == *__next)
00600           __next = _M_erase(__next);
00601         else
00602           __first = __next++;
00603       }
00604       }
00605 
00606       template<class _BinaryPredicate>
00607         void
00608         unique(_BinaryPredicate __binary_pred)
00609         {
00610       _Base_iterator __first = _Base::begin();
00611       _Base_iterator __last = _Base::end();
00612       if (__first == __last)
00613         return;
00614       _Base_iterator __next = __first; ++__next;
00615       while (__next != __last)
00616         {
00617           if (__binary_pred(*__first, *__next))
00618         __next = _M_erase(__next);
00619           else
00620         __first = __next++;
00621         }
00622     }
00623 
00624       void
00625 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00626       merge(list&& __x)
00627 #else
00628       merge(list& __x)
00629 #endif
00630       {
00631     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00632     // 300. list::merge() specification incomplete
00633     if (this != &__x)
00634       {
00635         __glibcxx_check_sorted(_Base::begin(), _Base::end());
00636         __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
00637         this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
00638         _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
00639       }
00640       }
00641 
00642 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00643       void
00644       merge(list& __x)
00645       { merge(std::move(__x)); }
00646 #endif
00647 
00648       template<class _Compare>
00649         void
00650 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00651         merge(list&& __x, _Compare __comp)
00652 #else
00653         merge(list& __x, _Compare __comp)
00654 #endif
00655         {
00656       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00657       // 300. list::merge() specification incomplete
00658       if (this != &__x)
00659         {
00660           __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
00661                       __comp);
00662           __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
00663                       __comp);
00664           this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
00665           _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
00666         }
00667     }
00668 
00669 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00670       template<typename _Compare>
00671         void
00672         merge(list& __x, _Compare __comp)
00673         { merge(std::move(__x), __comp); }
00674 #endif
00675 
00676       void
00677       sort() { _Base::sort(); }
00678 
00679       template<typename _StrictWeakOrdering>
00680         void
00681         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
00682 
00683       using _Base::reverse;
00684 
00685       _Base&
00686       _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
00687 
00688       const _Base&
00689       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
00690 
00691     private:
00692       void
00693       _M_invalidate_all()
00694       {
00695     this->_M_invalidate_if(_Not_equal(_Base::end()));
00696       }
00697     };
00698 
00699   template<typename _Tp, typename _Alloc>
00700     inline bool
00701     operator==(const list<_Tp, _Alloc>& __lhs,
00702            const list<_Tp, _Alloc>& __rhs)
00703     { return __lhs._M_base() == __rhs._M_base(); }
00704 
00705   template<typename _Tp, typename _Alloc>
00706     inline bool
00707     operator!=(const list<_Tp, _Alloc>& __lhs,
00708            const list<_Tp, _Alloc>& __rhs)
00709     { return __lhs._M_base() != __rhs._M_base(); }
00710 
00711   template<typename _Tp, typename _Alloc>
00712     inline bool
00713     operator<(const list<_Tp, _Alloc>& __lhs,
00714           const list<_Tp, _Alloc>& __rhs)
00715     { return __lhs._M_base() < __rhs._M_base(); }
00716 
00717   template<typename _Tp, typename _Alloc>
00718     inline bool
00719     operator<=(const list<_Tp, _Alloc>& __lhs,
00720            const list<_Tp, _Alloc>& __rhs)
00721     { return __lhs._M_base() <= __rhs._M_base(); }
00722 
00723   template<typename _Tp, typename _Alloc>
00724     inline bool
00725     operator>=(const list<_Tp, _Alloc>& __lhs,
00726            const list<_Tp, _Alloc>& __rhs)
00727     { return __lhs._M_base() >= __rhs._M_base(); }
00728 
00729   template<typename _Tp, typename _Alloc>
00730     inline bool
00731     operator>(const list<_Tp, _Alloc>& __lhs,
00732           const list<_Tp, _Alloc>& __rhs)
00733     { return __lhs._M_base() > __rhs._M_base(); }
00734 
00735   template<typename _Tp, typename _Alloc>
00736     inline void
00737     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
00738     { __lhs.swap(__rhs); }
00739 
00740 } // namespace __debug
00741 } // namespace std
00742 
00743 #endif