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