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