libstdc++
|
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