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