The C and C++ Include Header Files
/usr/include/c++/11/debug/forward_list
$ cat -n /usr/include/c++/11/debug/forward_list 1 //
-*- C++ -*- 2 3 // Copyright (C) 2010-2021 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 /** @file debug/forward_list 26 * This file is a GNU debug extension to the Standard C++ Library. 27 */ 28 29 #ifndef _GLIBCXX_DEBUG_FORWARD_LIST 30 #define _GLIBCXX_DEBUG_FORWARD_LIST 1 31 32 #pragma GCC system_header 33 34 #include
35 namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug { 36 template
class forward_list; 37 } } // namespace std::__debug 38 39 #include
40 #include
41 #include
42 #include
43 44 // Special validity check for forward_list ranges. 45 #define __glibcxx_check_valid_fl_range(_First,_Last,_Dist) \ 46 _GLIBCXX_DEBUG_VERIFY(_First._M_valid_range(_Last, _Dist, false), \ 47 _M_message(__gnu_debug::__msg_valid_range) \ 48 ._M_iterator(_First, #_First) \ 49 ._M_iterator(_Last, #_Last)) 50 51 namespace __gnu_debug 52 { 53 /// Special iterators swap and invalidation for forward_list because of the 54 /// before_begin iterator. 55 template
56 class _Safe_forward_list 57 : public _Safe_sequence<_SafeSequence> 58 { 59 _SafeSequence& 60 _M_this() noexcept 61 { return *static_cast<_SafeSequence*>(this); } 62 63 static void 64 _M_swap_aux(_Safe_sequence_base& __lhs, 65 _Safe_iterator_base*& __lhs_iterators, 66 _Safe_sequence_base& __rhs, 67 _Safe_iterator_base*& __rhs_iterators); 68 69 void _M_swap_single(_Safe_sequence_base&) noexcept; 70 71 protected: 72 void 73 _M_invalidate_all() 74 { 75 using _Base_const_iterator = __decltype(_M_this()._M_base().cend()); 76 this->_M_invalidate_if([this](_Base_const_iterator __it) 77 { 78 return __it != _M_this()._M_base().cbefore_begin() 79 && __it != _M_this()._M_base().cend(); }); 80 } 81 82 void _M_swap(_Safe_sequence_base&) noexcept; 83 }; 84 85 template
86 void 87 _Safe_forward_list<_SafeSequence>:: 88 _M_swap_aux(_Safe_sequence_base& __lhs, 89 _Safe_iterator_base*& __lhs_iterators, 90 _Safe_sequence_base& __rhs, 91 _Safe_iterator_base*& __rhs_iterators) 92 { 93 using const_iterator = typename _SafeSequence::const_iterator; 94 _Safe_iterator_base* __bbegin_its = 0; 95 _Safe_iterator_base* __last_bbegin = 0; 96 _SafeSequence& __rseq = static_cast<_SafeSequence&>(__rhs); 97 98 for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;) 99 { 100 // Even iterator is cast to const_iterator, not a problem. 101 _Safe_iterator_base* __victim_base = __iter; 102 const_iterator* __victim = 103 static_cast
(__victim_base); 104 __iter = __iter->_M_next; 105 if (__victim->base() == __rseq._M_base().cbefore_begin()) 106 { 107 __victim->_M_unlink(); 108 if (__lhs_iterators == __victim_base) 109 __lhs_iterators = __victim_base->_M_next; 110 if (__bbegin_its) 111 { 112 __victim_base->_M_next = __bbegin_its; 113 __bbegin_its->_M_prior = __victim_base; 114 } 115 else 116 __last_bbegin = __victim_base; 117 __bbegin_its = __victim_base; 118 } 119 else 120 __victim_base->_M_sequence = std::__addressof(__lhs); 121 } 122 123 if (__bbegin_its) 124 { 125 if (__rhs_iterators) 126 { 127 __rhs_iterators->_M_prior = __last_bbegin; 128 __last_bbegin->_M_next = __rhs_iterators; 129 } 130 __rhs_iterators = __bbegin_its; 131 } 132 } 133 134 template
135 void 136 _Safe_forward_list<_SafeSequence>:: 137 _M_swap_single(_Safe_sequence_base& __other) noexcept 138 { 139 std::swap(_M_this()._M_iterators, __other._M_iterators); 140 std::swap(_M_this()._M_const_iterators, __other._M_const_iterators); 141 // Useless, always 1 on forward_list 142 //std::swap(_M_this()_M_version, __other._M_version); 143 _Safe_iterator_base* __this_its = _M_this()._M_iterators; 144 _M_swap_aux(__other, __other._M_iterators, 145 _M_this(), _M_this()._M_iterators); 146 _Safe_iterator_base* __this_const_its = _M_this()._M_const_iterators; 147 _M_swap_aux(__other, __other._M_const_iterators, 148 _M_this(), _M_this()._M_const_iterators); 149 _M_swap_aux(_M_this(), __this_its, 150 __other, __other._M_iterators); 151 _M_swap_aux(_M_this(), __this_const_its, 152 __other, __other._M_const_iterators); 153 } 154 155 /* Special forward_list _M_swap version that does not swap the 156 * before-begin ownership.*/ 157 template
158 void 159 _Safe_forward_list<_SafeSequence>:: 160 _M_swap(_Safe_sequence_base& __other) noexcept 161 { 162 // We need to lock both sequences to swap 163 using namespace __gnu_cxx; 164 __mutex *__this_mutex = &_M_this()._M_get_mutex(); 165 __mutex *__other_mutex = 166 &static_cast<_SafeSequence&>(__other)._M_get_mutex(); 167 if (__this_mutex == __other_mutex) 168 { 169 __scoped_lock __lock(*__this_mutex); 170 _M_swap_single(__other); 171 } 172 else 173 { 174 __scoped_lock __l1(__this_mutex < __other_mutex 175 ? *__this_mutex : *__other_mutex); 176 __scoped_lock __l2(__this_mutex < __other_mutex 177 ? *__other_mutex : *__this_mutex); 178 _M_swap_single(__other); 179 } 180 } 181 } 182 183 namespace std _GLIBCXX_VISIBILITY(default) 184 { 185 namespace __debug 186 { 187 /// Class std::forward_list with safety/checking/debug instrumentation. 188 template
> 189 class forward_list 190 : public __gnu_debug::_Safe_container< 191 forward_list<_Tp, _Alloc>, _Alloc, __gnu_debug::_Safe_forward_list>, 192 public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> 193 { 194 typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base; 195 typedef __gnu_debug::_Safe_container< 196 forward_list, _Alloc, __gnu_debug::_Safe_forward_list> _Safe; 197 198 typedef typename _Base::iterator _Base_iterator; 199 typedef typename _Base::const_iterator _Base_const_iterator; 200 201 template
202 friend class ::__gnu_debug::_Safe_iterator; 203 204 // Reference wrapper for base class. See PR libstdc++/90102. 205 struct _Base_ref 206 { 207 _Base_ref(const _Base& __r) : _M_ref(__r) { } 208 209 const _Base& _M_ref; 210 }; 211 212 public: 213 typedef typename _Base::reference reference; 214 typedef typename _Base::const_reference const_reference; 215 216 typedef __gnu_debug::_Safe_iterator< 217 _Base_iterator, forward_list> iterator; 218 typedef __gnu_debug::_Safe_iterator< 219 _Base_const_iterator, forward_list> const_iterator; 220 221 typedef typename _Base::size_type size_type; 222 typedef typename _Base::difference_type difference_type; 223 224 typedef _Tp value_type; 225 typedef typename _Base::allocator_type allocator_type; 226 typedef typename _Base::pointer pointer; 227 typedef typename _Base::const_pointer const_pointer; 228 229 // 23.2.3.1 construct/copy/destroy: 230 231 forward_list() = default; 232 233 explicit 234 forward_list(const allocator_type& __al) noexcept 235 : _Base(__al) { } 236 237 forward_list(const forward_list& __list, const allocator_type& __al) 238 : _Base(__list, __al) 239 { } 240 241 forward_list(forward_list&& __list, const allocator_type& __al) 242 noexcept( 243 std::is_nothrow_constructible<_Base, 244 _Base, const allocator_type&>::value ) 245 : _Safe(std::move(__list._M_safe()), __al), 246 _Base(std::move(__list._M_base()), __al) 247 { } 248 249 explicit 250 forward_list(size_type __n, const allocator_type& __al = allocator_type()) 251 : _Base(__n, __al) 252 { } 253 254 forward_list(size_type __n, const __type_identity_t<_Tp>& __value, 255 const allocator_type& __al = allocator_type()) 256 : _Base(__n, __value, __al) 257 { } 258 259 template
> 261 forward_list(_InputIterator __first, _InputIterator __last, 262 const allocator_type& __al = allocator_type()) 263 : _Base(__gnu_debug::__base( 264 __glibcxx_check_valid_constructor_range(__first, __last)), 265 __gnu_debug::__base(__last), __al) 266 { } 267 268 forward_list(const forward_list&) = default; 269 270 forward_list(forward_list&&) = default; 271 272 forward_list(std::initializer_list<_Tp> __il, 273 const allocator_type& __al = allocator_type()) 274 : _Base(__il, __al) 275 { } 276 277 ~forward_list() = default; 278 279 forward_list(_Base_ref __x) : _Base(__x._M_ref) { } 280 281 forward_list& 282 operator=(const forward_list&) = default; 283 284 forward_list& 285 operator=(forward_list&&) = default; 286 287 forward_list& 288 operator=(std::initializer_list<_Tp> __il) 289 { 290 _M_base() = __il; 291 this->_M_invalidate_all(); 292 return *this; 293 } 294 295 template
> 297 void 298 assign(_InputIterator __first, _InputIterator __last) 299 { 300 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 301 __glibcxx_check_valid_range2(__first, __last, __dist); 302 303 if (__dist.second >= __gnu_debug::__dp_sign) 304 _Base::assign(__gnu_debug::__unsafe(__first), 305 __gnu_debug::__unsafe(__last)); 306 else 307 _Base::assign(__first, __last); 308 309 this->_M_invalidate_all(); 310 } 311 312 void 313 assign(size_type __n, const _Tp& __val) 314 { 315 _Base::assign(__n, __val); 316 this->_M_invalidate_all(); 317 } 318 319 void 320 assign(std::initializer_list<_Tp> __il) 321 { 322 _Base::assign(__il); 323 this->_M_invalidate_all(); 324 } 325 326 using _Base::get_allocator; 327 328 // iterators: 329 330 iterator 331 before_begin() noexcept 332 { return { _Base::before_begin(), this }; } 333 334 const_iterator 335 before_begin() const noexcept 336 { return { _Base::before_begin(), this }; } 337 338 iterator 339 begin() noexcept 340 { return { _Base::begin(), this }; } 341 342 const_iterator 343 begin() const noexcept 344 { return { _Base::begin(), this }; } 345 346 iterator 347 end() noexcept 348 { return { _Base::end(), this }; } 349 350 const_iterator 351 end() const noexcept 352 { return { _Base::end(), this }; } 353 354 const_iterator 355 cbegin() const noexcept 356 { return { _Base::cbegin(), this }; } 357 358 const_iterator 359 cbefore_begin() const noexcept 360 { return { _Base::cbefore_begin(), this }; } 361 362 const_iterator 363 cend() const noexcept 364 { return { _Base::cend(), this }; } 365 366 using _Base::empty; 367 using _Base::max_size; 368 369 // element access: 370 371 reference 372 front() 373 { 374 __glibcxx_check_nonempty(); 375 return _Base::front(); 376 } 377 378 const_reference 379 front() const 380 { 381 __glibcxx_check_nonempty(); 382 return _Base::front(); 383 } 384 385 // modifiers: 386 387 using _Base::emplace_front; 388 using _Base::push_front; 389 390 void 391 pop_front() 392 { 393 __glibcxx_check_nonempty(); 394 this->_M_invalidate_if([this](_Base_const_iterator __it) 395 { return __it == this->_M_base().cbegin(); }); 396 _Base::pop_front(); 397 } 398 399 template
400 iterator 401 emplace_after(const_iterator __pos, _Args&&... __args) 402 { 403 __glibcxx_check_insert_after(__pos); 404 return { _Base::emplace_after(__pos.base(), 405 std::forward<_Args>(__args)...), 406 this }; 407 } 408 409 iterator 410 insert_after(const_iterator __pos, const _Tp& __val) 411 { 412 __glibcxx_check_insert_after(__pos); 413 return { _Base::insert_after(__pos.base(), __val), this }; 414 } 415 416 iterator 417 insert_after(const_iterator __pos, _Tp&& __val) 418 { 419 __glibcxx_check_insert_after(__pos); 420 return { _Base::insert_after(__pos.base(), std::move(__val)), this }; 421 } 422 423 iterator 424 insert_after(const_iterator __pos, size_type __n, const _Tp& __val) 425 { 426 __glibcxx_check_insert_after(__pos); 427 return { _Base::insert_after(__pos.base(), __n, __val), this }; 428 } 429 430 template
> 432 iterator 433 insert_after(const_iterator __pos, 434 _InputIterator __first, _InputIterator __last) 435 { 436 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 437 __glibcxx_check_insert_range_after(__pos, __first, __last, __dist); 438 439 if (__dist.second >= __gnu_debug::__dp_sign) 440 return 441 { 442 _Base::insert_after(__pos.base(), 443 __gnu_debug::__unsafe(__first), 444 __gnu_debug::__unsafe(__last)), 445 this 446 }; 447 else 448 return { _Base::insert_after(__pos.base(), __first, __last), this }; 449 } 450 451 iterator 452 insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) 453 { 454 __glibcxx_check_insert_after(__pos); 455 return { _Base::insert_after(__pos.base(), __il), this }; 456 } 457 458 iterator 459 erase_after(const_iterator __pos) 460 { 461 __glibcxx_check_erase_after(__pos); 462 463 _Base_const_iterator __next = std::next(__pos.base()); 464 this->_M_invalidate_if([__next](_Base_const_iterator __it) 465 { return __it == __next; }); 466 return { _Base::erase_after(__pos.base()), this }; 467 } 468 469 iterator 470 erase_after(const_iterator __pos, const_iterator __last) 471 { 472 __glibcxx_check_erase_range_after(__pos, __last); 473 for (_Base_const_iterator __victim = std::next(__pos.base()); 474 __victim != __last.base(); ++__victim) 475 { 476 _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(), 477 _M_message(__gnu_debug::__msg_valid_range2) 478 ._M_sequence(*this, "this") 479 ._M_iterator(__pos, "pos") 480 ._M_iterator(__last, "last")); 481 this->_M_invalidate_if([__victim](_Base_const_iterator __it) 482 { return __it == __victim; }); 483 } 484 485 return { _Base::erase_after(__pos.base(), __last.base()), this }; 486 } 487 488 void 489 swap(forward_list& __list) 490 noexcept( noexcept(declval<_Base&>().swap(__list)) ) 491 { 492 _Safe::_M_swap(__list); 493 _Base::swap(__list); 494 } 495 496 void 497 resize(size_type __sz) 498 { 499 this->_M_detach_singular(); 500 501 // if __sz < size(), invalidate all iterators in [begin+__sz, end() 502 _Base_iterator __victim = _Base::begin(); 503 _Base_iterator __end = _Base::end(); 504 for (size_type __i = __sz; __victim != __end && __i > 0; --__i) 505 ++__victim; 506 507 for (; __victim != __end; ++__victim) 508 { 509 this->_M_invalidate_if([__victim](_Base_const_iterator __it) 510 { return __it == __victim; }); 511 } 512 513 __try 514 { 515 _Base::resize(__sz); 516 } 517 __catch(...) 518 { 519 this->_M_revalidate_singular(); 520 __throw_exception_again; 521 } 522 } 523 524 void 525 resize(size_type __sz, const value_type& __val) 526 { 527 this->_M_detach_singular(); 528 529 // if __sz < size(), invalidate all iterators in [begin+__sz, end()) 530 _Base_iterator __victim = _Base::begin(); 531 _Base_iterator __end = _Base::end(); 532 for (size_type __i = __sz; __victim != __end && __i > 0; --__i) 533 ++__victim; 534 535 for (; __victim != __end; ++__victim) 536 { 537 this->_M_invalidate_if([__victim](_Base_const_iterator __it) 538 { return __it == __victim; }); 539 } 540 541 __try 542 { 543 _Base::resize(__sz, __val); 544 } 545 __catch(...) 546 { 547 this->_M_revalidate_singular(); 548 __throw_exception_again; 549 } 550 } 551 552 void 553 clear() noexcept 554 { 555 _Base::clear(); 556 this->_M_invalidate_all(); 557 } 558 559 // 23.2.3.5 forward_list operations: 560 void 561 splice_after(const_iterator __pos, forward_list&& __list) 562 { 563 __glibcxx_check_insert_after(__pos); 564 _GLIBCXX_DEBUG_VERIFY(std::__addressof(__list) != this, 565 _M_message(__gnu_debug::__msg_self_splice) 566 ._M_sequence(*this, "this")); 567 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(), 568 _M_message(__gnu_debug::__msg_splice_alloc) 569 ._M_sequence(*this) 570 ._M_sequence(__list, "__list")); 571 this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it) 572 { 573 return __it != __list._M_base().cbefore_begin() 574 && __it != __list._M_base().end(); 575 }); 576 _Base::splice_after(__pos.base(), std::move(__list._M_base())); 577 } 578 579 void 580 splice_after(const_iterator __pos, forward_list& __list) 581 { splice_after(__pos, std::move(__list)); } 582 583 void 584 splice_after(const_iterator __pos, forward_list&& __list, 585 const_iterator __i) 586 { 587 __glibcxx_check_insert_after(__pos); 588 _GLIBCXX_DEBUG_VERIFY(__i._M_before_dereferenceable(), 589 _M_message(__gnu_debug::__msg_splice_bad) 590 ._M_iterator(__i, "__i")); 591 _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(std::__addressof(__list)), 592 _M_message(__gnu_debug::__msg_splice_other) 593 ._M_iterator(__i, "__i") 594 ._M_sequence(__list, "__list")); 595 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(), 596 _M_message(__gnu_debug::__msg_splice_alloc) 597 ._M_sequence(*this) 598 ._M_sequence(__list, "__list")); 599 600 // _GLIBCXX_RESOLVE_LIB_DEFECTS 601 // 250. splicing invalidates iterators 602 _Base_const_iterator __next = std::next(__i.base()); 603 this->_M_transfer_from_if(__list, [__next](_Base_const_iterator __it) 604 { return __it == __next; }); 605 _Base::splice_after(__pos.base(), std::move(__list._M_base()), 606 __i.base()); 607 } 608 609 void 610 splice_after(const_iterator __pos, forward_list& __list, 611 const_iterator __i) 612 { splice_after(__pos, std::move(__list), __i); } 613 614 void 615 splice_after(const_iterator __pos, forward_list&& __list, 616 const_iterator __before, const_iterator __last) 617 { 618 typename __gnu_debug::_Distance_traits
::__type __dist; 619 auto __listptr = std::__addressof(__list); 620 __glibcxx_check_insert_after(__pos); 621 __glibcxx_check_valid_fl_range(__before, __last, __dist); 622 _GLIBCXX_DEBUG_VERIFY(__before._M_attached_to(__listptr), 623 _M_message(__gnu_debug::__msg_splice_other) 624 ._M_sequence(__list, "list") 625 ._M_iterator(__before, "before")); 626 _GLIBCXX_DEBUG_VERIFY(__before._M_dereferenceable() 627 || __before._M_is_before_begin(), 628 _M_message(__gnu_debug::__msg_valid_range2) 629 ._M_sequence(__list, "list") 630 ._M_iterator(__before, "before") 631 ._M_iterator(__last, "last")); 632 _GLIBCXX_DEBUG_VERIFY(__before != __last, 633 _M_message(__gnu_debug::__msg_valid_range2) 634 ._M_sequence(__list, "list") 635 ._M_iterator(__before, "before") 636 ._M_iterator(__last, "last")); 637 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(), 638 _M_message(__gnu_debug::__msg_splice_alloc) 639 ._M_sequence(*this) 640 ._M_sequence(__list, "__list")); 641 642 for (_Base_const_iterator __tmp = std::next(__before.base()); 643 __tmp != __last.base(); ++__tmp) 644 { 645 _GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(), 646 _M_message(__gnu_debug::__msg_valid_range2) 647 ._M_sequence(__list, "list") 648 ._M_iterator(__before, "before") 649 ._M_iterator(__last, "last")); 650 _GLIBCXX_DEBUG_VERIFY(__listptr != this || __tmp != __pos.base(), 651 _M_message(__gnu_debug::__msg_splice_overlap) 652 ._M_iterator(__tmp, "position") 653 ._M_iterator(__before, "before") 654 ._M_iterator(__last, "last")); 655 // _GLIBCXX_RESOLVE_LIB_DEFECTS 656 // 250. splicing invalidates iterators 657 this->_M_transfer_from_if(__list, [__tmp](_Base_const_iterator __it) 658 { return __it == __tmp; }); 659 } 660 661 _Base::splice_after(__pos.base(), std::move(__list._M_base()), 662 __before.base(), __last.base()); 663 } 664 665 void 666 splice_after(const_iterator __pos, forward_list& __list, 667 const_iterator __before, const_iterator __last) 668 { splice_after(__pos, std::move(__list), __before, __last); } 669 670 private: 671 #if __cplusplus > 201703L 672 using __remove_return_type = size_type; 673 # define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG \ 674 __attribute__((__abi_tag__("__cxx20"))) 675 # define _GLIBCXX20_ONLY(__expr) __expr 676 #else 677 using __remove_return_type = void; 678 # define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG 679 # define _GLIBCXX20_ONLY(__expr) 680 #endif 681 682 public: 683 _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG 684 __remove_return_type 685 remove(const _Tp& __val) 686 { 687 if (!this->_M_iterators && !this->_M_const_iterators) 688 return _Base::remove(__val); 689 690 size_type __removed __attribute__((__unused__)) = 0; 691 _Base __to_destroy(get_allocator()); 692 _Base_const_iterator __x = _Base::cbefore_begin(); 693 _Base_const_iterator __old = __x++; 694 while (__x != _Base::cend()) 695 { 696 if (*__x == __val) 697 { 698 _Base_const_iterator __next = std::next(__old); 699 this->_M_invalidate_if([__next](_Base_const_iterator __it) 700 { return __it == __next; }); 701 __to_destroy.splice_after(__to_destroy.cbefore_begin(), 702 _M_base(), __old); 703 __x = __old; 704 _GLIBCXX20_ONLY( __removed++ ); 705 } 706 707 __old = __x++; 708 } 709 710 return _GLIBCXX20_ONLY( __removed ); 711 } 712 713 template
714 __remove_return_type 715 remove_if(_Pred __pred) 716 { 717 if (!this->_M_iterators && !this->_M_const_iterators) 718 return _Base::remove_if(__pred); 719 720 size_type __removed __attribute__((__unused__)) = 0; 721 _Base __to_destroy(get_allocator()); 722 _Base_iterator __x = _Base::before_begin(); 723 _Base_iterator __old = __x++; 724 while (__x != _Base::end()) 725 { 726 if (__pred(*__x)) 727 { 728 this->_M_invalidate_if([__x](_Base_const_iterator __it) 729 { return __it == __x; }); 730 __to_destroy.splice_after(__to_destroy.cbefore_begin(), 731 _M_base(), __old); 732 __x = __old; 733 _GLIBCXX20_ONLY( __removed++ ); 734 } 735 736 __old = __x++; 737 } 738 739 return _GLIBCXX20_ONLY( __removed ); 740 } 741 742 _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG 743 __remove_return_type 744 unique() 745 { return unique(std::equal_to<_Tp>()); } 746 747 template
748 __remove_return_type 749 unique(_BinPred __binary_pred) 750 { 751 if (!this->_M_iterators && !this->_M_const_iterators) 752 return _Base::unique(__binary_pred); 753 754 _Base_const_iterator __first = _Base::cbegin(); 755 _Base_const_iterator __last = _Base::cend(); 756 if (__first == __last) 757 return _GLIBCXX20_ONLY(0); 758 759 size_type __removed __attribute__((__unused__)) = 0; 760 _Base __to_destroy(get_allocator()); 761 _Base_const_iterator __next = std::next(__first); 762 while (__next != __last) 763 { 764 if (__binary_pred(*__first, *__next)) 765 { 766 this->_M_invalidate_if([__next](_Base_const_iterator __it) 767 { return __it == __next; }); 768 __to_destroy.splice_after(__to_destroy.cbefore_begin(), 769 _M_base(), __first); 770 __next = __first; 771 _GLIBCXX20_ONLY( __removed++ ); 772 } 773 774 __first = __next++; 775 } 776 777 return _GLIBCXX20_ONLY( __removed ); 778 } 779 780 #undef _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG 781 #undef _GLIBCXX20_ONLY 782 783 void 784 merge(forward_list&& __list) 785 { 786 if (this != std::__addressof(__list)) 787 { 788 __glibcxx_check_sorted(_Base::begin(), _Base::end()); 789 __glibcxx_check_sorted(__list._M_base().begin(), 790 __list._M_base().end()); 791 this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it) 792 { 793 return __it != __list._M_base().cbefore_begin() 794 && __it != __list._M_base().cend(); 795 }); 796 _Base::merge(std::move(__list._M_base())); 797 } 798 } 799 800 void 801 merge(forward_list& __list) 802 { merge(std::move(__list)); } 803 804 template
805 void 806 merge(forward_list&& __list, _Comp __comp) 807 { 808 if (this != std::__addressof(__list)) 809 { 810 __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); 811 __glibcxx_check_sorted_pred(__list._M_base().begin(), 812 __list._M_base().end(), __comp); 813 this->_M_transfer_from_if(__list, 814 [&__list](_Base_const_iterator __it) 815 { 816 return __it != __list._M_base().cbefore_begin() 817 && __it != __list._M_base().cend(); 818 }); 819 _Base::merge(std::move(__list._M_base()), __comp); 820 } 821 } 822 823 template
824 void 825 merge(forward_list& __list, _Comp __comp) 826 { merge(std::move(__list), __comp); } 827 828 using _Base::sort; 829 using _Base::reverse; 830 831 _Base& 832 _M_base() noexcept { return *this; } 833 834 const _Base& 835 _M_base() const noexcept { return *this; } 836 }; 837 838 #if __cpp_deduction_guides >= 201606 839 template
::value_type, 841 typename _Allocator = allocator<_ValT>, 842 typename = _RequireInputIter<_InputIterator>, 843 typename = _RequireAllocator<_Allocator>> 844 forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator()) 845 -> forward_list<_ValT, _Allocator>; 846 847 template
, 848 typename = _RequireAllocator<_Allocator>> 849 forward_list(size_t, _Tp, _Allocator = _Allocator()) 850 -> forward_list<_Tp, _Allocator>; 851 #endif 852 853 template
854 bool 855 operator==(const forward_list<_Tp, _Alloc>& __lx, 856 const forward_list<_Tp, _Alloc>& __ly) 857 { return __lx._M_base() == __ly._M_base(); } 858 859 #if __cpp_lib_three_way_comparison 860 template
861 constexpr __detail::__synth3way_t<_Tp> 862 operator<=>(const forward_list<_Tp, _Alloc>& __x, 863 const forward_list<_Tp, _Alloc>& __y) 864 { return __x._M_base() <=> __y._M_base(); } 865 #else 866 template
867 inline bool 868 operator<(const forward_list<_Tp, _Alloc>& __lx, 869 const forward_list<_Tp, _Alloc>& __ly) 870 { return __lx._M_base() < __ly._M_base(); } 871 872 template
873 inline bool 874 operator!=(const forward_list<_Tp, _Alloc>& __lx, 875 const forward_list<_Tp, _Alloc>& __ly) 876 { return !(__lx == __ly); } 877 878 /// Based on operator< 879 template
880 inline bool 881 operator>(const forward_list<_Tp, _Alloc>& __lx, 882 const forward_list<_Tp, _Alloc>& __ly) 883 { return (__ly < __lx); } 884 885 /// Based on operator< 886 template
887 inline bool 888 operator>=(const forward_list<_Tp, _Alloc>& __lx, 889 const forward_list<_Tp, _Alloc>& __ly) 890 { return !(__lx < __ly); } 891 892 /// Based on operator< 893 template
894 inline bool 895 operator<=(const forward_list<_Tp, _Alloc>& __lx, 896 const forward_list<_Tp, _Alloc>& __ly) 897 { return !(__ly < __lx); } 898 #endif // three-way comparison 899 900 /// See std::forward_list::swap(). 901 template
902 inline void 903 swap(forward_list<_Tp, _Alloc>& __lx, forward_list<_Tp, _Alloc>& __ly) 904 noexcept(noexcept(__lx.swap(__ly))) 905 { __lx.swap(__ly); } 906 907 } // namespace __debug 908 } // namespace std 909 910 namespace __gnu_debug 911 { 912 template
913 struct _BeforeBeginHelper
> 914 { 915 typedef std::__debug::forward_list<_Tp, _Alloc> _Sequence; 916 917 template
918 static bool 919 _S_Is(const _Safe_iterator<_Iterator, _Sequence>& __it) 920 { 921 return 922 __it.base() == __it._M_get_sequence()->_M_base().before_begin(); 923 } 924 925 template
926 static bool 927 _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it) 928 { return _S_Is(__it); } 929 }; 930 931 template
932 struct _Sequence_traits
> 933 { 934 typedef typename std::__debug::forward_list<_Tp, _Alloc>::iterator _It; 935 936 static typename _Distance_traits<_It>::__type 937 _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq) 938 { 939 return __seq.empty() 940 ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign); 941 } 942 }; 943 944 #ifndef _GLIBCXX_DEBUG_PEDANTIC 945 template
946 struct _Insert_range_from_self_is_safe< 947 std::__debug::forward_list<_Tp, _Alloc> > 948 { enum { __value = 1 }; }; 949 #endif 950 } 951 952 #endif
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™