libstdc++
|
00001 // <forward_list> -*- C++ -*- 00002 00003 // Copyright (C) 2010-2013 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 00050 typedef typename _Base::iterator _Base_iterator; 00051 typedef typename _Base::const_iterator _Base_const_iterator; 00052 00053 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 00054 rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type; 00055 00056 typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; 00057 00058 public: 00059 typedef typename _Base::reference reference; 00060 typedef typename _Base::const_reference const_reference; 00061 00062 typedef __gnu_debug::_Safe_iterator<_Base_iterator, 00063 forward_list> iterator; 00064 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, 00065 forward_list> const_iterator; 00066 00067 typedef typename _Base::size_type size_type; 00068 typedef typename _Base::difference_type difference_type; 00069 00070 typedef _Tp value_type; 00071 typedef _Alloc allocator_type; 00072 typedef typename _Base::pointer pointer; 00073 typedef typename _Base::const_pointer const_pointer; 00074 00075 // 23.2.3.1 construct/copy/destroy: 00076 explicit 00077 forward_list(const _Alloc& __al = _Alloc()) 00078 : _Base(__al) { } 00079 00080 forward_list(const forward_list& __list, const _Alloc& __al) 00081 : _Base(__list, __al) 00082 { } 00083 00084 forward_list(forward_list&& __list, const _Alloc& __al) 00085 : _Base(std::move(__list._M_base()), __al) 00086 { 00087 if (__list.get_allocator() == __al) 00088 this->_M_swap(__list); 00089 else 00090 __list._M_invalidate_all(); 00091 } 00092 00093 explicit 00094 forward_list(size_type __n, const _Alloc& __al = _Alloc()) 00095 : _Base(__n, __al) 00096 { } 00097 00098 forward_list(size_type __n, const _Tp& __value, 00099 const _Alloc& __al = _Alloc()) 00100 : _Base(__n, __value, __al) 00101 { } 00102 00103 template<typename _InputIterator, 00104 typename = std::_RequireInputIter<_InputIterator>> 00105 forward_list(_InputIterator __first, _InputIterator __last, 00106 const _Alloc& __al = _Alloc()) 00107 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, 00108 __last)), 00109 __gnu_debug::__base(__last), __al) 00110 { } 00111 00112 forward_list(const forward_list& __list) 00113 : _Base(__list) 00114 { } 00115 00116 forward_list(forward_list&& __list) noexcept 00117 : _Base(std::move(__list._M_base())) 00118 { 00119 this->_M_swap(__list); 00120 } 00121 00122 forward_list(std::initializer_list<_Tp> __il, 00123 const _Alloc& __al = _Alloc()) 00124 : _Base(__il, __al) 00125 { } 00126 00127 ~forward_list() noexcept 00128 { } 00129 00130 forward_list& 00131 operator=(const forward_list& __list) 00132 { 00133 static_cast<_Base&>(*this) = __list; 00134 this->_M_invalidate_all(); 00135 return *this; 00136 } 00137 00138 forward_list& 00139 operator=(forward_list&& __list) 00140 noexcept(_Node_alloc_traits::_S_nothrow_move()) 00141 { 00142 __glibcxx_check_self_move_assign(__list); 00143 bool xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign() 00144 || __list.get_allocator() == this->get_allocator(); 00145 static_cast<_Base&>(*this) = std::move(__list); 00146 if (xfer_memory) 00147 this->_M_swap(__list); 00148 else 00149 this->_M_invalidate_all(); 00150 __list._M_invalidate_all(); 00151 return *this; 00152 } 00153 00154 forward_list& 00155 operator=(std::initializer_list<_Tp> __il) 00156 { 00157 static_cast<_Base&>(*this) = __il; 00158 this->_M_invalidate_all(); 00159 return *this; 00160 } 00161 00162 template<typename _InputIterator, 00163 typename = std::_RequireInputIter<_InputIterator>> 00164 void 00165 assign(_InputIterator __first, _InputIterator __last) 00166 { 00167 __glibcxx_check_valid_range(__first, __last); 00168 _Base::assign(__gnu_debug::__base(__first), 00169 __gnu_debug::__base(__last)); 00170 this->_M_invalidate_all(); 00171 } 00172 00173 void 00174 assign(size_type __n, const _Tp& __val) 00175 { 00176 _Base::assign(__n, __val); 00177 this->_M_invalidate_all(); 00178 } 00179 00180 void 00181 assign(std::initializer_list<_Tp> __il) 00182 { 00183 _Base::assign(__il); 00184 this->_M_invalidate_all(); 00185 } 00186 00187 using _Base::get_allocator; 00188 00189 // iterators: 00190 00191 iterator 00192 before_begin() noexcept 00193 { return iterator(_Base::before_begin(), this); } 00194 00195 const_iterator 00196 before_begin() const noexcept 00197 { return const_iterator(_Base::before_begin(), this); } 00198 00199 iterator 00200 begin() noexcept 00201 { return iterator(_Base::begin(), this); } 00202 00203 const_iterator 00204 begin() const noexcept 00205 { return const_iterator(_Base::begin(), this); } 00206 00207 iterator 00208 end() noexcept 00209 { return iterator(_Base::end(), this); } 00210 00211 const_iterator 00212 end() const noexcept 00213 { return const_iterator(_Base::end(), this); } 00214 00215 const_iterator 00216 cbegin() const noexcept 00217 { return const_iterator(_Base::cbegin(), this); } 00218 00219 const_iterator 00220 cbefore_begin() const noexcept 00221 { return const_iterator(_Base::cbefore_begin(), this); } 00222 00223 const_iterator 00224 cend() const noexcept 00225 { return const_iterator(_Base::cend(), this); } 00226 00227 using _Base::empty; 00228 using _Base::max_size; 00229 00230 // element access: 00231 00232 reference 00233 front() 00234 { 00235 __glibcxx_check_nonempty(); 00236 return _Base::front(); 00237 } 00238 00239 const_reference 00240 front() const 00241 { 00242 __glibcxx_check_nonempty(); 00243 return _Base::front(); 00244 } 00245 00246 // modiļ¬ers: 00247 00248 using _Base::emplace_front; 00249 using _Base::push_front; 00250 00251 void 00252 pop_front() 00253 { 00254 __glibcxx_check_nonempty(); 00255 this->_M_invalidate_if([this](_Base_const_iterator __it) 00256 { return __it == this->_M_base().cbegin(); }); 00257 _Base::pop_front(); 00258 } 00259 00260 template<typename... _Args> 00261 iterator 00262 emplace_after(const_iterator __pos, _Args&&... __args) 00263 { 00264 __glibcxx_check_insert_after(__pos); 00265 return iterator(_Base::emplace_after(__pos.base(), 00266 std::forward<_Args>(__args)...), 00267 this); 00268 } 00269 00270 iterator 00271 insert_after(const_iterator __pos, const _Tp& __val) 00272 { 00273 __glibcxx_check_insert_after(__pos); 00274 return iterator(_Base::insert_after(__pos.base(), __val), this); 00275 } 00276 00277 iterator 00278 insert_after(const_iterator __pos, _Tp&& __val) 00279 { 00280 __glibcxx_check_insert_after(__pos); 00281 return iterator(_Base::insert_after(__pos.base(), std::move(__val)), 00282 this); 00283 } 00284 00285 iterator 00286 insert_after(const_iterator __pos, size_type __n, const _Tp& __val) 00287 { 00288 __glibcxx_check_insert_after(__pos); 00289 return iterator(_Base::insert_after(__pos.base(), __n, __val), 00290 this); 00291 } 00292 00293 template<typename _InputIterator, 00294 typename = std::_RequireInputIter<_InputIterator>> 00295 iterator 00296 insert_after(const_iterator __pos, 00297 _InputIterator __first, _InputIterator __last) 00298 { 00299 __glibcxx_check_insert_range_after(__pos, __first, __last); 00300 return iterator(_Base::insert_after(__pos.base(), 00301 __gnu_debug::__base(__first), 00302 __gnu_debug::__base(__last)), 00303 this); 00304 } 00305 00306 iterator 00307 insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) 00308 { 00309 __glibcxx_check_insert_after(__pos); 00310 return iterator(_Base::insert_after(__pos.base(), __il), this); 00311 } 00312 00313 private: 00314 _Base_iterator 00315 _M_erase_after(_Base_const_iterator __pos) 00316 { 00317 _Base_const_iterator __next = std::next(__pos); 00318 this->_M_invalidate_if([__next](_Base_const_iterator __it) 00319 { return __it == __next; }); 00320 return _Base::erase_after(__pos); 00321 } 00322 public: 00323 iterator 00324 erase_after(const_iterator __pos) 00325 { 00326 __glibcxx_check_erase_after(__pos); 00327 return iterator(_M_erase_after(__pos.base()), this); 00328 } 00329 00330 iterator 00331 erase_after(const_iterator __pos, const_iterator __last) 00332 { 00333 __glibcxx_check_erase_range_after(__pos, __last); 00334 for (_Base_const_iterator __victim = std::next(__pos.base()); 00335 __victim != __last.base(); ++__victim) 00336 { 00337 _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(), 00338 _M_message(__gnu_debug::__msg_valid_range2) 00339 ._M_sequence(*this, "this") 00340 ._M_iterator(__pos, "pos") 00341 ._M_iterator(__last, "last")); 00342 this->_M_invalidate_if([__victim](_Base_const_iterator __it) 00343 { return __it == __victim; }); 00344 } 00345 return iterator(_Base::erase_after(__pos.base(), __last.base()), this); 00346 } 00347 00348 void 00349 swap(forward_list& __list) 00350 noexcept(_Node_alloc_traits::_S_nothrow_swap()) 00351 { 00352 if (!_Node_alloc_traits::_S_propagate_on_swap()) 00353 __glibcxx_check_equal_allocs(__list); 00354 _Base::swap(__list); 00355 this->_M_swap(__list); 00356 } 00357 00358 void 00359 resize(size_type __sz) 00360 { 00361 this->_M_detach_singular(); 00362 00363 // if __sz < size(), invalidate all iterators in [begin+__sz, end() 00364 _Base_iterator __victim = _Base::begin(); 00365 _Base_iterator __end = _Base::end(); 00366 for (size_type __i = __sz; __victim != __end && __i > 0; --__i) 00367 ++__victim; 00368 00369 for (; __victim != __end; ++__victim) 00370 { 00371 this->_M_invalidate_if([__victim](_Base_const_iterator __it) 00372 { return __it == __victim; }); 00373 } 00374 00375 __try 00376 { 00377 _Base::resize(__sz); 00378 } 00379 __catch(...) 00380 { 00381 this->_M_revalidate_singular(); 00382 __throw_exception_again; 00383 } 00384 } 00385 00386 void 00387 resize(size_type __sz, const value_type& __val) 00388 { 00389 this->_M_detach_singular(); 00390 00391 // if __sz < size(), invalidate all iterators in [begin+__sz, end()) 00392 _Base_iterator __victim = _Base::begin(); 00393 _Base_iterator __end = _Base::end(); 00394 for (size_type __i = __sz; __victim != __end && __i > 0; --__i) 00395 ++__victim; 00396 00397 for (; __victim != __end; ++__victim) 00398 { 00399 this->_M_invalidate_if([__victim](_Base_const_iterator __it) 00400 { return __it == __victim; }); 00401 } 00402 00403 __try 00404 { 00405 _Base::resize(__sz, __val); 00406 } 00407 __catch(...) 00408 { 00409 this->_M_revalidate_singular(); 00410 __throw_exception_again; 00411 } 00412 } 00413 00414 void 00415 clear() noexcept 00416 { 00417 _Base::clear(); 00418 this->_M_invalidate_all(); 00419 } 00420 00421 // 23.2.3.5 forward_list operations: 00422 void 00423 splice_after(const_iterator __pos, forward_list&& __list) 00424 { 00425 __glibcxx_check_insert_after(__pos); 00426 _GLIBCXX_DEBUG_VERIFY(&__list != this, 00427 _M_message(__gnu_debug::__msg_self_splice) 00428 ._M_sequence(*this, "this")); 00429 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(), 00430 _M_message(__gnu_debug::__msg_splice_alloc) 00431 ._M_sequence(*this) 00432 ._M_sequence(__list, "__list")); 00433 this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it) 00434 { 00435 return __it != __list._M_base().cbefore_begin() 00436 && __it != __list._M_base().end(); 00437 }); 00438 _Base::splice_after(__pos.base(), std::move(__list._M_base())); 00439 } 00440 00441 void 00442 splice_after(const_iterator __pos, forward_list& __list) 00443 { splice_after(__pos, std::move(__list)); } 00444 00445 void 00446 splice_after(const_iterator __pos, forward_list&& __list, 00447 const_iterator __i) 00448 { 00449 __glibcxx_check_insert_after(__pos); 00450 _GLIBCXX_DEBUG_VERIFY(__i._M_before_dereferenceable(), 00451 _M_message(__gnu_debug::__msg_splice_bad) 00452 ._M_iterator(__i, "__i")); 00453 _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__list), 00454 _M_message(__gnu_debug::__msg_splice_other) 00455 ._M_iterator(__i, "__i") 00456 ._M_sequence(__list, "__list")); 00457 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(), 00458 _M_message(__gnu_debug::__msg_splice_alloc) 00459 ._M_sequence(*this) 00460 ._M_sequence(__list, "__list")); 00461 00462 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00463 // 250. splicing invalidates iterators 00464 _Base_const_iterator __next = std::next(__i.base()); 00465 this->_M_transfer_from_if(__list, [__next](_Base_const_iterator __it) 00466 { return __it == __next; }); 00467 _Base::splice_after(__pos.base(), std::move(__list._M_base()), 00468 __i.base()); 00469 } 00470 00471 void 00472 splice_after(const_iterator __pos, forward_list& __list, 00473 const_iterator __i) 00474 { splice_after(__pos, std::move(__list), __i); } 00475 00476 void 00477 splice_after(const_iterator __pos, forward_list&& __list, 00478 const_iterator __before, const_iterator __last) 00479 { 00480 __glibcxx_check_insert_after(__pos); 00481 __glibcxx_check_valid_range(__before, __last); 00482 _GLIBCXX_DEBUG_VERIFY(__before._M_attached_to(&__list), 00483 _M_message(__gnu_debug::__msg_splice_other) 00484 ._M_sequence(__list, "list") 00485 ._M_iterator(__before, "before")); 00486 _GLIBCXX_DEBUG_VERIFY(__before._M_dereferenceable() 00487 || __before._M_is_before_begin(), 00488 _M_message(__gnu_debug::__msg_valid_range2) 00489 ._M_sequence(__list, "list") 00490 ._M_iterator(__before, "before") 00491 ._M_iterator(__last, "last")); 00492 _GLIBCXX_DEBUG_VERIFY(__before != __last, 00493 _M_message(__gnu_debug::__msg_valid_range2) 00494 ._M_sequence(__list, "list") 00495 ._M_iterator(__before, "before") 00496 ._M_iterator(__last, "last")); 00497 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(), 00498 _M_message(__gnu_debug::__msg_splice_alloc) 00499 ._M_sequence(*this) 00500 ._M_sequence(__list, "__list")); 00501 00502 for (_Base_const_iterator __tmp = std::next(__before.base()); 00503 __tmp != __last.base(); ++__tmp) 00504 { 00505 _GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(), 00506 _M_message(__gnu_debug::__msg_valid_range2) 00507 ._M_sequence(__list, "list") 00508 ._M_iterator(__before, "before") 00509 ._M_iterator(__last, "last")); 00510 _GLIBCXX_DEBUG_VERIFY(&__list != this || __tmp != __pos.base(), 00511 _M_message(__gnu_debug::__msg_splice_overlap) 00512 ._M_iterator(__tmp, "position") 00513 ._M_iterator(__before, "before") 00514 ._M_iterator(__last, "last")); 00515 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00516 // 250. splicing invalidates iterators 00517 this->_M_transfer_from_if(__list, [__tmp](_Base_const_iterator __it) 00518 { return __it == __tmp; }); 00519 } 00520 00521 _Base::splice_after(__pos.base(), std::move(__list._M_base()), 00522 __before.base(), __last.base()); 00523 } 00524 00525 void 00526 splice_after(const_iterator __pos, forward_list& __list, 00527 const_iterator __before, const_iterator __last) 00528 { splice_after(__pos, std::move(__list), __before, __last); } 00529 00530 void 00531 remove(const _Tp& __val) 00532 { 00533 _Base_iterator __x = _Base::before_begin(); 00534 _Base_iterator __old = __x++; 00535 while (__x != _Base::end()) 00536 { 00537 if (*__x == __val) 00538 __x = _M_erase_after(__old); 00539 else 00540 __old = __x++; 00541 } 00542 } 00543 00544 template<typename _Pred> 00545 void 00546 remove_if(_Pred __pred) 00547 { 00548 _Base_iterator __x = _Base::before_begin(); 00549 _Base_iterator __old = __x++; 00550 while (__x != _Base::end()) 00551 { 00552 if (__pred(*__x)) 00553 __x = _M_erase_after(__old); 00554 else 00555 __old = __x++; 00556 } 00557 } 00558 00559 void 00560 unique() 00561 { 00562 _Base_iterator __first = _Base::begin(); 00563 _Base_iterator __last = _Base::end(); 00564 if (__first == __last) 00565 return; 00566 _Base_iterator __next = std::next(__first); 00567 while (__next != __last) 00568 { 00569 if (*__first == *__next) 00570 __next = _M_erase_after(__first); 00571 else 00572 __first = __next++; 00573 } 00574 } 00575 00576 template<typename _BinPred> 00577 void 00578 unique(_BinPred __binary_pred) 00579 { 00580 _Base_iterator __first = _Base::begin(); 00581 _Base_iterator __last = _Base::end(); 00582 if (__first == __last) 00583 return; 00584 _Base_iterator __next = std::next(__first); 00585 while (__next != __last) 00586 { 00587 if (__binary_pred(*__first, *__next)) 00588 __next = _M_erase_after(__first); 00589 else 00590 __first = __next++; 00591 } 00592 } 00593 00594 void 00595 merge(forward_list&& __list) 00596 { 00597 if (this != &__list) 00598 { 00599 __glibcxx_check_sorted(_Base::begin(), _Base::end()); 00600 __glibcxx_check_sorted(__list._M_base().begin(), 00601 __list._M_base().end()); 00602 this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it) 00603 { 00604 return __it != __list._M_base().cbefore_begin() 00605 && __it != __list._M_base().cend(); 00606 }); 00607 _Base::merge(std::move(__list._M_base())); 00608 } 00609 } 00610 00611 void 00612 merge(forward_list& __list) 00613 { merge(std::move(__list)); } 00614 00615 template<typename _Comp> 00616 void 00617 merge(forward_list&& __list, _Comp __comp) 00618 { 00619 if (this != &__list) 00620 { 00621 __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); 00622 __glibcxx_check_sorted_pred(__list._M_base().begin(), 00623 __list._M_base().end(), __comp); 00624 this->_M_transfer_from_if(__list, 00625 [&__list](_Base_const_iterator __it) 00626 { 00627 return __it != __list._M_base().cbefore_begin() 00628 && __it != __list._M_base().cend(); 00629 }); 00630 _Base::merge(std::move(__list._M_base()), __comp); 00631 } 00632 } 00633 00634 template<typename _Comp> 00635 void 00636 merge(forward_list& __list, _Comp __comp) 00637 { merge(std::move(__list), __comp); } 00638 00639 using _Base::sort; 00640 using _Base::reverse; 00641 00642 _Base& 00643 _M_base() noexcept { return *this; } 00644 00645 const _Base& 00646 _M_base() const noexcept { return *this; } 00647 00648 private: 00649 void 00650 _M_invalidate_all() 00651 { 00652 this->_M_invalidate_if([this](_Base_const_iterator __it) 00653 { 00654 return __it != this->_M_base().cbefore_begin() 00655 && __it != this->_M_base().cend(); 00656 }); 00657 } 00658 typedef __gnu_debug::_Safe_iterator_base _Safe_iterator_base; 00659 static void 00660 _M_swap_aux(forward_list& __lhs, 00661 _Safe_iterator_base*& __lhs_iterators, 00662 forward_list& __rhs, 00663 _Safe_iterator_base*& __rhs_iterators); 00664 void _M_swap(forward_list& __list); 00665 }; 00666 00667 template<typename _Tp, typename _Alloc> 00668 void 00669 forward_list<_Tp, _Alloc>:: 00670 _M_swap_aux(forward_list<_Tp, _Alloc>& __lhs, 00671 __gnu_debug::_Safe_iterator_base*& __lhs_iterators, 00672 forward_list<_Tp, _Alloc>& __rhs, 00673 __gnu_debug::_Safe_iterator_base*& __rhs_iterators) 00674 { 00675 using __gnu_debug::_Safe_iterator_base; 00676 _Safe_iterator_base* __bbegin_its = 0; 00677 _Safe_iterator_base* __last_bbegin = 0; 00678 for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;) 00679 { 00680 // Even iterator are casted to const_iterator, not a problem. 00681 const_iterator* __victim = static_cast<const_iterator*>(__iter); 00682 __iter = __iter->_M_next; 00683 if (__victim->base() == __rhs._M_base().cbefore_begin()) 00684 { 00685 __victim->_M_unlink(); 00686 if (__lhs_iterators == __victim) 00687 __lhs_iterators = __victim->_M_next; 00688 if (__bbegin_its) 00689 { 00690 __victim->_M_next = __bbegin_its; 00691 __bbegin_its->_M_prior = __victim; 00692 } 00693 else 00694 __last_bbegin = __victim; 00695 __bbegin_its = __victim; 00696 } 00697 else 00698 __victim->_M_sequence = &__lhs; 00699 } 00700 00701 if (__bbegin_its) 00702 { 00703 if (__rhs_iterators) 00704 { 00705 __rhs_iterators->_M_prior = __last_bbegin; 00706 __last_bbegin->_M_next = __rhs_iterators; 00707 } 00708 __rhs_iterators = __bbegin_its; 00709 } 00710 } 00711 00712 /* Special forward_list _M_swap version that do not swap the 00713 * before-begin ownership.*/ 00714 template<typename _Tp, typename _Alloc> 00715 void 00716 forward_list<_Tp, _Alloc>:: 00717 _M_swap(forward_list<_Tp, _Alloc>& __list) 00718 { 00719 __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); 00720 std::swap(this->_M_iterators, __list._M_iterators); 00721 std::swap(this->_M_const_iterators, __list._M_const_iterators); 00722 // Useless, always 1 on forward_list 00723 //std::swap(this->_M_version, __list._M_version); 00724 _Safe_iterator_base* __this_its = this->_M_iterators; 00725 _M_swap_aux(__list, __list._M_iterators, *this, this->_M_iterators); 00726 _Safe_iterator_base* __this_const_its = this->_M_const_iterators; 00727 _M_swap_aux(__list, __list._M_const_iterators, *this, 00728 this->_M_const_iterators); 00729 _M_swap_aux(*this, __this_its, __list, __list._M_iterators); 00730 _M_swap_aux(*this, __this_const_its, __list, __list._M_const_iterators); 00731 } 00732 00733 template<typename _Tp, typename _Alloc> 00734 bool 00735 operator==(const forward_list<_Tp, _Alloc>& __lx, 00736 const forward_list<_Tp, _Alloc>& __ly) 00737 { return __lx._M_base() == __ly._M_base(); } 00738 00739 template<typename _Tp, typename _Alloc> 00740 inline bool 00741 operator<(const forward_list<_Tp, _Alloc>& __lx, 00742 const forward_list<_Tp, _Alloc>& __ly) 00743 { return __lx._M_base() < __ly._M_base(); } 00744 00745 template<typename _Tp, typename _Alloc> 00746 inline bool 00747 operator!=(const forward_list<_Tp, _Alloc>& __lx, 00748 const forward_list<_Tp, _Alloc>& __ly) 00749 { return !(__lx == __ly); } 00750 00751 /// Based on operator< 00752 template<typename _Tp, typename _Alloc> 00753 inline bool 00754 operator>(const forward_list<_Tp, _Alloc>& __lx, 00755 const forward_list<_Tp, _Alloc>& __ly) 00756 { return (__ly < __lx); } 00757 00758 /// Based on operator< 00759 template<typename _Tp, typename _Alloc> 00760 inline bool 00761 operator>=(const forward_list<_Tp, _Alloc>& __lx, 00762 const forward_list<_Tp, _Alloc>& __ly) 00763 { return !(__lx < __ly); } 00764 00765 /// Based on operator< 00766 template<typename _Tp, typename _Alloc> 00767 inline bool 00768 operator<=(const forward_list<_Tp, _Alloc>& __lx, 00769 const forward_list<_Tp, _Alloc>& __ly) 00770 { return !(__ly < __lx); } 00771 00772 /// See std::forward_list::swap(). 00773 template<typename _Tp, typename _Alloc> 00774 inline void 00775 swap(forward_list<_Tp, _Alloc>& __lx, 00776 forward_list<_Tp, _Alloc>& __ly) 00777 { __lx.swap(__ly); } 00778 00779 } // namespace __debug 00780 } // namespace std 00781 00782 namespace __gnu_debug 00783 { 00784 template<class _Tp, class _Alloc> 00785 struct _BeforeBeginHelper<std::__debug::forward_list<_Tp, _Alloc> > 00786 { 00787 typedef std::__debug::forward_list<_Tp, _Alloc> _Sequence; 00788 typedef typename _Sequence::const_iterator _It; 00789 typedef typename _It::iterator_type _BaseIt; 00790 00791 static bool 00792 _S_Is(_BaseIt __it, const _Sequence* __seq) 00793 { return __it == __seq->_M_base().cbefore_begin(); } 00794 00795 static bool 00796 _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) 00797 { return _S_Is(__it, __seq); } 00798 }; 00799 } 00800 00801 #endif