1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_FORWARD_LIST 11#define _LIBCPP_FORWARD_LIST 12 13/* 14 forward_list synopsis 15 16namespace std 17{ 18 19template <class T, class Allocator = allocator<T>> 20class forward_list 21{ 22public: 23 typedef T value_type; 24 typedef Allocator allocator_type; 25 26 typedef value_type& reference; 27 typedef const value_type& const_reference; 28 typedef typename allocator_traits<allocator_type>::pointer pointer; 29 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 30 typedef typename allocator_traits<allocator_type>::size_type size_type; 31 typedef typename allocator_traits<allocator_type>::difference_type difference_type; 32 33 typedef <details> iterator; 34 typedef <details> const_iterator; 35 36 forward_list() 37 noexcept(is_nothrow_default_constructible<allocator_type>::value); 38 explicit forward_list(const allocator_type& a); 39 explicit forward_list(size_type n); 40 explicit forward_list(size_type n, const allocator_type& a); // C++14 41 forward_list(size_type n, const value_type& v); 42 forward_list(size_type n, const value_type& v, const allocator_type& a); 43 template <class InputIterator> 44 forward_list(InputIterator first, InputIterator last); 45 template <class InputIterator> 46 forward_list(InputIterator first, InputIterator last, const allocator_type& a); 47 template<container-compatible-range<T> R> 48 forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 49 forward_list(const forward_list& x); 50 forward_list(const forward_list& x, const allocator_type& a); 51 forward_list(forward_list&& x) 52 noexcept(is_nothrow_move_constructible<allocator_type>::value); 53 forward_list(forward_list&& x, const allocator_type& a); 54 forward_list(initializer_list<value_type> il); 55 forward_list(initializer_list<value_type> il, const allocator_type& a); 56 57 ~forward_list(); 58 59 forward_list& operator=(const forward_list& x); 60 forward_list& operator=(forward_list&& x) 61 noexcept( 62 allocator_type::propagate_on_container_move_assignment::value && 63 is_nothrow_move_assignable<allocator_type>::value); 64 forward_list& operator=(initializer_list<value_type> il); 65 66 template <class InputIterator> 67 void assign(InputIterator first, InputIterator last); 68 template<container-compatible-range<T> R> 69 void assign_range(R&& rg); // C++23 70 void assign(size_type n, const value_type& v); 71 void assign(initializer_list<value_type> il); 72 73 allocator_type get_allocator() const noexcept; 74 75 iterator begin() noexcept; 76 const_iterator begin() const noexcept; 77 iterator end() noexcept; 78 const_iterator end() const noexcept; 79 80 const_iterator cbegin() const noexcept; 81 const_iterator cend() const noexcept; 82 83 iterator before_begin() noexcept; 84 const_iterator before_begin() const noexcept; 85 const_iterator cbefore_begin() const noexcept; 86 87 bool empty() const noexcept; 88 size_type max_size() const noexcept; 89 90 reference front(); 91 const_reference front() const; 92 93 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 94 void push_front(const value_type& v); 95 void push_front(value_type&& v); 96 template<container-compatible-range<T> R> 97 void prepend_range(R&& rg); // C++23 98 99 void pop_front(); 100 101 template <class... Args> 102 iterator emplace_after(const_iterator p, Args&&... args); 103 iterator insert_after(const_iterator p, const value_type& v); 104 iterator insert_after(const_iterator p, value_type&& v); 105 iterator insert_after(const_iterator p, size_type n, const value_type& v); 106 template <class InputIterator> 107 iterator insert_after(const_iterator p, 108 InputIterator first, InputIterator last); 109 template<container-compatible-range<T> R> 110 iterator insert_range_after(const_iterator position, R&& rg); // C++23 111 iterator insert_after(const_iterator p, initializer_list<value_type> il); 112 113 iterator erase_after(const_iterator p); 114 iterator erase_after(const_iterator first, const_iterator last); 115 116 void swap(forward_list& x) 117 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 118 119 void resize(size_type n); 120 void resize(size_type n, const value_type& v); 121 void clear() noexcept; 122 123 void splice_after(const_iterator p, forward_list& x); 124 void splice_after(const_iterator p, forward_list&& x); 125 void splice_after(const_iterator p, forward_list& x, const_iterator i); 126 void splice_after(const_iterator p, forward_list&& x, const_iterator i); 127 void splice_after(const_iterator p, forward_list& x, 128 const_iterator first, const_iterator last); 129 void splice_after(const_iterator p, forward_list&& x, 130 const_iterator first, const_iterator last); 131 size_type remove(const value_type& v); // void before C++20 132 template <class Predicate> 133 size_type remove_if(Predicate pred); // void before C++20 134 size_type unique(); // void before C++20 135 template <class BinaryPredicate> 136 size_type unique(BinaryPredicate binary_pred); // void before C++20 137 void merge(forward_list& x); 138 void merge(forward_list&& x); 139 template <class Compare> void merge(forward_list& x, Compare comp); 140 template <class Compare> void merge(forward_list&& x, Compare comp); 141 void sort(); 142 template <class Compare> void sort(Compare comp); 143 void reverse() noexcept; 144}; 145 146 147template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 148 forward_list(InputIterator, InputIterator, Allocator = Allocator()) 149 -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 150 151template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> 152 forward_list(from_range_t, R&&, Allocator = Allocator()) 153 -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23 154 155template <class T, class Allocator> 156 bool operator==(const forward_list<T, Allocator>& x, 157 const forward_list<T, Allocator>& y); 158 159template <class T, class Allocator> 160 bool operator< (const forward_list<T, Allocator>& x, 161 const forward_list<T, Allocator>& y); // removed in C++20 162 163template <class T, class Allocator> 164 bool operator!=(const forward_list<T, Allocator>& x, 165 const forward_list<T, Allocator>& y); // removed in C++20 166 167template <class T, class Allocator> 168 bool operator> (const forward_list<T, Allocator>& x, 169 const forward_list<T, Allocator>& y); // removed in C++20 170 171template <class T, class Allocator> 172 bool operator>=(const forward_list<T, Allocator>& x, 173 const forward_list<T, Allocator>& y); // removed in C++20 174 175template <class T, class Allocator> 176 bool operator<=(const forward_list<T, Allocator>& x, 177 const forward_list<T, Allocator>& y); // removed in C++20 178 179template<class T, class Allocator> 180 synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x, 181 const forward_list<T, Allocator>& y); // since C++20 182 183template <class T, class Allocator> 184 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) 185 noexcept(noexcept(x.swap(y))); 186 187template <class T, class Allocator, class U> 188 typename forward_list<T, Allocator>::size_type 189 erase(forward_list<T, Allocator>& c, const U& value); // C++20 190template <class T, class Allocator, class Predicate> 191 typename forward_list<T, Allocator>::size_type 192 erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20 193 194} // std 195 196*/ 197 198#include <__algorithm/comp.h> 199#include <__algorithm/lexicographical_compare.h> 200#include <__algorithm/lexicographical_compare_three_way.h> 201#include <__algorithm/min.h> 202#include <__assert> // all public C++ headers provide the assertion handler 203#include <__availability> 204#include <__config> 205#include <__iterator/distance.h> 206#include <__iterator/iterator_traits.h> 207#include <__iterator/move_iterator.h> 208#include <__iterator/next.h> 209#include <__memory/addressof.h> 210#include <__memory/allocation_guard.h> 211#include <__memory/allocator.h> 212#include <__memory/allocator_destructor.h> 213#include <__memory/allocator_traits.h> 214#include <__memory/compressed_pair.h> 215#include <__memory/pointer_traits.h> 216#include <__memory/swap_allocator.h> 217#include <__memory/unique_ptr.h> 218#include <__memory_resource/polymorphic_allocator.h> 219#include <__ranges/access.h> 220#include <__ranges/concepts.h> 221#include <__ranges/container_compatible_range.h> 222#include <__ranges/from_range.h> 223#include <__type_traits/conditional.h> 224#include <__type_traits/is_allocator.h> 225#include <__type_traits/is_const.h> 226#include <__type_traits/is_nothrow_default_constructible.h> 227#include <__type_traits/is_nothrow_move_assignable.h> 228#include <__type_traits/is_nothrow_move_constructible.h> 229#include <__type_traits/is_pointer.h> 230#include <__type_traits/is_same.h> 231#include <__type_traits/type_identity.h> 232#include <__utility/forward.h> 233#include <__utility/move.h> 234#include <limits> 235#include <version> 236 237// standard-mandated includes 238 239// [iterator.range] 240#include <__iterator/access.h> 241#include <__iterator/data.h> 242#include <__iterator/empty.h> 243#include <__iterator/reverse_access.h> 244#include <__iterator/size.h> 245 246// [forward.list.syn] 247#include <compare> 248#include <initializer_list> 249 250#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 251# pragma GCC system_header 252#endif 253 254_LIBCPP_PUSH_MACROS 255#include <__undef_macros> 256 257 258_LIBCPP_BEGIN_NAMESPACE_STD 259 260template <class _Tp, class _VoidPtr> struct __forward_list_node; 261template <class _NodePtr> struct __forward_begin_node; 262 263 264template <class> 265struct __forward_list_node_value_type; 266 267template <class _Tp, class _VoidPtr> 268struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > { 269 typedef _Tp type; 270}; 271 272template <class _NodePtr> 273struct __forward_node_traits { 274 275 typedef __remove_cv_t< 276 typename pointer_traits<_NodePtr>::element_type> __node; 277 typedef typename __forward_list_node_value_type<__node>::type __node_value_type; 278 typedef _NodePtr __node_pointer; 279 typedef __forward_begin_node<_NodePtr> __begin_node; 280 typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer; 281 typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; 282 283#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB) 284 typedef __begin_node_pointer __iter_node_pointer; 285#else 286 typedef __conditional_t<is_pointer<__void_pointer>::value, __begin_node_pointer, __node_pointer> 287 __iter_node_pointer; 288#endif 289 290 typedef __conditional_t<is_same<__iter_node_pointer, __node_pointer>::value, __begin_node_pointer, __node_pointer> 291 __non_iter_node_pointer; 292 293 _LIBCPP_INLINE_VISIBILITY 294 static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { 295 return __p; 296 } 297 _LIBCPP_INLINE_VISIBILITY 298 static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) { 299 return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p)); 300 } 301}; 302 303template <class _NodePtr> 304struct __forward_begin_node 305{ 306 typedef _NodePtr pointer; 307 typedef __rebind_pointer_t<_NodePtr, __forward_begin_node> __begin_node_pointer; 308 309 pointer __next_; 310 311 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} 312 _LIBCPP_INLINE_VISIBILITY explicit __forward_begin_node(pointer __n) : __next_(__n) {} 313 314 _LIBCPP_INLINE_VISIBILITY 315 __begin_node_pointer __next_as_begin() const { 316 return static_cast<__begin_node_pointer>(__next_); 317 } 318}; 319 320template <class _Tp, class _VoidPtr> 321using __begin_node_of = __forward_begin_node<__rebind_pointer_t<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> > >; 322 323template <class _Tp, class _VoidPtr> 324struct _LIBCPP_STANDALONE_DEBUG __forward_list_node 325 : public __begin_node_of<_Tp, _VoidPtr> 326{ 327 typedef _Tp value_type; 328 typedef __begin_node_of<_Tp, _VoidPtr> _Base; 329 typedef typename _Base::pointer _NodePtr; 330 331 value_type __value_; 332 333 _LIBCPP_HIDE_FROM_ABI __forward_list_node() = default; 334 _LIBCPP_HIDE_FROM_ABI __forward_list_node(const value_type& __v, _NodePtr __next) : _Base(__next), __value_(__v) {} 335}; 336 337 338template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list; 339template<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; 340 341template <class _NodePtr> 342class _LIBCPP_TEMPLATE_VIS __forward_list_iterator 343{ 344 typedef __forward_node_traits<_NodePtr> __traits; 345 typedef typename __traits::__node_pointer __node_pointer; 346 typedef typename __traits::__begin_node_pointer __begin_node_pointer; 347 typedef typename __traits::__iter_node_pointer __iter_node_pointer; 348 typedef typename __traits::__void_pointer __void_pointer; 349 350 __iter_node_pointer __ptr_; 351 352 _LIBCPP_INLINE_VISIBILITY 353 __begin_node_pointer __get_begin() const { 354 return static_cast<__begin_node_pointer>( 355 static_cast<__void_pointer>(__ptr_)); 356 } 357 _LIBCPP_INLINE_VISIBILITY 358 __node_pointer __get_unsafe_node_pointer() const { 359 return static_cast<__node_pointer>( 360 static_cast<__void_pointer>(__ptr_)); 361 } 362 363 _LIBCPP_INLINE_VISIBILITY 364 explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {} 365 366 _LIBCPP_INLINE_VISIBILITY 367 explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT 368 : __ptr_(__traits::__as_iter_node(__p)) {} 369 370 _LIBCPP_INLINE_VISIBILITY 371 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT 372 : __ptr_(__traits::__as_iter_node(__p)) {} 373 374 template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list; 375 template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator; 376 377public: 378 typedef forward_iterator_tag iterator_category; 379 typedef typename __traits::__node_value_type value_type; 380 typedef value_type& reference; 381 typedef typename pointer_traits<__node_pointer>::difference_type 382 difference_type; 383 typedef __rebind_pointer_t<__node_pointer, value_type> pointer; 384 385 _LIBCPP_INLINE_VISIBILITY 386 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {} 387 388 _LIBCPP_INLINE_VISIBILITY 389 reference operator*() const {return __get_unsafe_node_pointer()->__value_;} 390 _LIBCPP_INLINE_VISIBILITY 391 pointer operator->() const { 392 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_); 393 } 394 395 _LIBCPP_INLINE_VISIBILITY 396 __forward_list_iterator& operator++() 397 { 398 __ptr_ = __traits::__as_iter_node(__ptr_->__next_); 399 return *this; 400 } 401 _LIBCPP_INLINE_VISIBILITY 402 __forward_list_iterator operator++(int) 403 { 404 __forward_list_iterator __t(*this); 405 ++(*this); 406 return __t; 407 } 408 409 friend _LIBCPP_INLINE_VISIBILITY 410 bool operator==(const __forward_list_iterator& __x, 411 const __forward_list_iterator& __y) 412 {return __x.__ptr_ == __y.__ptr_;} 413 friend _LIBCPP_INLINE_VISIBILITY 414 bool operator!=(const __forward_list_iterator& __x, 415 const __forward_list_iterator& __y) 416 {return !(__x == __y);} 417}; 418 419template <class _NodeConstPtr> 420class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator 421{ 422 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), ""); 423 typedef _NodeConstPtr _NodePtr; 424 425 typedef __forward_node_traits<_NodePtr> __traits; 426 typedef typename __traits::__node __node; 427 typedef typename __traits::__node_pointer __node_pointer; 428 typedef typename __traits::__begin_node_pointer __begin_node_pointer; 429 typedef typename __traits::__iter_node_pointer __iter_node_pointer; 430 typedef typename __traits::__void_pointer __void_pointer; 431 432 __iter_node_pointer __ptr_; 433 434 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const { 435 return static_cast<__begin_node_pointer>( 436 static_cast<__void_pointer>(__ptr_)); 437 } 438 _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const { 439 return static_cast<__node_pointer>( 440 static_cast<__void_pointer>(__ptr_)); 441 } 442 443 _LIBCPP_INLINE_VISIBILITY 444 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT 445 : __ptr_(nullptr) {} 446 447 _LIBCPP_INLINE_VISIBILITY 448 explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT 449 : __ptr_(__traits::__as_iter_node(__p)) {} 450 451 _LIBCPP_INLINE_VISIBILITY 452 explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT 453 : __ptr_(__traits::__as_iter_node(__p)) {} 454 455 456 template<class, class> friend class forward_list; 457 458public: 459 typedef forward_iterator_tag iterator_category; 460 typedef typename __traits::__node_value_type value_type; 461 typedef const value_type& reference; 462 typedef typename pointer_traits<__node_pointer>::difference_type 463 difference_type; 464 typedef __rebind_pointer_t<__node_pointer, const value_type> 465 pointer; 466 467 _LIBCPP_INLINE_VISIBILITY 468 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} 469 _LIBCPP_INLINE_VISIBILITY 470 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT 471 : __ptr_(__p.__ptr_) {} 472 473 _LIBCPP_INLINE_VISIBILITY 474 reference operator*() const {return __get_unsafe_node_pointer()->__value_;} 475 _LIBCPP_INLINE_VISIBILITY 476 pointer operator->() const {return pointer_traits<pointer>::pointer_to( 477 __get_unsafe_node_pointer()->__value_);} 478 479 _LIBCPP_INLINE_VISIBILITY 480 __forward_list_const_iterator& operator++() 481 { 482 __ptr_ = __traits::__as_iter_node(__ptr_->__next_); 483 return *this; 484 } 485 _LIBCPP_INLINE_VISIBILITY 486 __forward_list_const_iterator operator++(int) 487 { 488 __forward_list_const_iterator __t(*this); 489 ++(*this); 490 return __t; 491 } 492 493 friend _LIBCPP_INLINE_VISIBILITY 494 bool operator==(const __forward_list_const_iterator& __x, 495 const __forward_list_const_iterator& __y) 496 {return __x.__ptr_ == __y.__ptr_;} 497 friend _LIBCPP_INLINE_VISIBILITY 498 bool operator!=(const __forward_list_const_iterator& __x, 499 const __forward_list_const_iterator& __y) 500 {return !(__x == __y);} 501}; 502 503template <class _Tp, class _Alloc> 504class __forward_list_base 505{ 506protected: 507 typedef _Tp value_type; 508 typedef _Alloc allocator_type; 509 510 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer; 511 typedef __forward_list_node<value_type, void_pointer> __node; 512 typedef __begin_node_of<value_type, void_pointer> __begin_node; 513 typedef __rebind_alloc<allocator_traits<allocator_type>, __node> __node_allocator; 514 typedef allocator_traits<__node_allocator> __node_traits; 515 typedef typename __node_traits::pointer __node_pointer; 516 517 typedef __rebind_alloc<allocator_traits<allocator_type>, __begin_node> __begin_node_allocator; 518 typedef typename allocator_traits<__begin_node_allocator>::pointer 519 __begin_node_pointer; 520 521 __compressed_pair<__begin_node, __node_allocator> __before_begin_; 522 523 _LIBCPP_INLINE_VISIBILITY 524 __begin_node_pointer __before_begin() _NOEXCEPT 525 {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());} 526 _LIBCPP_INLINE_VISIBILITY 527 __begin_node_pointer __before_begin() const _NOEXCEPT 528 {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));} 529 530 _LIBCPP_INLINE_VISIBILITY 531 __node_allocator& __alloc() _NOEXCEPT 532 {return __before_begin_.second();} 533 _LIBCPP_INLINE_VISIBILITY 534 const __node_allocator& __alloc() const _NOEXCEPT 535 {return __before_begin_.second();} 536 537 typedef __forward_list_iterator<__node_pointer> iterator; 538 typedef __forward_list_const_iterator<__node_pointer> const_iterator; 539 540 _LIBCPP_INLINE_VISIBILITY 541 __forward_list_base() 542 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) 543 : __before_begin_(__begin_node(), __default_init_tag()) {} 544 _LIBCPP_INLINE_VISIBILITY 545 explicit __forward_list_base(const allocator_type& __a) 546 : __before_begin_(__begin_node(), __node_allocator(__a)) {} 547 _LIBCPP_INLINE_VISIBILITY 548 explicit __forward_list_base(const __node_allocator& __a) 549 : __before_begin_(__begin_node(), __a) {} 550#ifndef _LIBCPP_CXX03_LANG 551public: 552 _LIBCPP_INLINE_VISIBILITY 553 __forward_list_base(__forward_list_base&& __x) 554 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); 555 _LIBCPP_INLINE_VISIBILITY 556 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); 557#endif // _LIBCPP_CXX03_LANG 558 559private: 560 __forward_list_base(const __forward_list_base&); 561 __forward_list_base& operator=(const __forward_list_base&); 562 563public: 564 _LIBCPP_HIDE_FROM_ABI ~__forward_list_base(); 565 566protected: 567 _LIBCPP_INLINE_VISIBILITY 568 void __copy_assign_alloc(const __forward_list_base& __x) 569 {__copy_assign_alloc(__x, integral_constant<bool, 570 __node_traits::propagate_on_container_copy_assignment::value>());} 571 572 _LIBCPP_INLINE_VISIBILITY 573 void __move_assign_alloc(__forward_list_base& __x) 574 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || 575 is_nothrow_move_assignable<__node_allocator>::value) 576 {__move_assign_alloc(__x, integral_constant<bool, 577 __node_traits::propagate_on_container_move_assignment::value>());} 578 579public: 580 _LIBCPP_INLINE_VISIBILITY 581 void swap(__forward_list_base& __x) 582#if _LIBCPP_STD_VER >= 14 583 _NOEXCEPT; 584#else 585 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || 586 __is_nothrow_swappable<__node_allocator>::value); 587#endif 588protected: 589 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; 590 591private: 592 _LIBCPP_INLINE_VISIBILITY 593 void __copy_assign_alloc(const __forward_list_base&, false_type) {} 594 _LIBCPP_INLINE_VISIBILITY 595 void __copy_assign_alloc(const __forward_list_base& __x, true_type) 596 { 597 if (__alloc() != __x.__alloc()) 598 clear(); 599 __alloc() = __x.__alloc(); 600 } 601 602 _LIBCPP_INLINE_VISIBILITY 603 void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT 604 {} 605 _LIBCPP_INLINE_VISIBILITY 606 void __move_assign_alloc(__forward_list_base& __x, true_type) 607 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) 608 {__alloc() = _VSTD::move(__x.__alloc());} 609}; 610 611#ifndef _LIBCPP_CXX03_LANG 612 613template <class _Tp, class _Alloc> 614inline 615__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) 616 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) 617 : __before_begin_(_VSTD::move(__x.__before_begin_)) 618{ 619 __x.__before_begin()->__next_ = nullptr; 620} 621 622template <class _Tp, class _Alloc> 623inline 624__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, 625 const allocator_type& __a) 626 : __before_begin_(__begin_node(), __node_allocator(__a)) 627{ 628 if (__alloc() == __x.__alloc()) 629 { 630 __before_begin()->__next_ = __x.__before_begin()->__next_; 631 __x.__before_begin()->__next_ = nullptr; 632 } 633} 634 635#endif // _LIBCPP_CXX03_LANG 636 637template <class _Tp, class _Alloc> 638__forward_list_base<_Tp, _Alloc>::~__forward_list_base() 639{ 640 clear(); 641} 642 643template <class _Tp, class _Alloc> 644inline 645void 646__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) 647#if _LIBCPP_STD_VER >= 14 648 _NOEXCEPT 649#else 650 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || 651 __is_nothrow_swappable<__node_allocator>::value) 652#endif 653{ 654 _VSTD::__swap_allocator(__alloc(), __x.__alloc(), 655 integral_constant<bool, __node_traits::propagate_on_container_swap::value>()); 656 using _VSTD::swap; 657 swap(__before_begin()->__next_, __x.__before_begin()->__next_); 658} 659 660template <class _Tp, class _Alloc> 661void 662__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT 663{ 664 __node_allocator& __a = __alloc(); 665 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) 666 { 667 __node_pointer __next = __p->__next_; 668 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); 669 __node_traits::deallocate(__a, __p, 1); 670 __p = __next; 671 } 672 __before_begin()->__next_ = nullptr; 673} 674 675template <class _Tp, class _Alloc /*= allocator<_Tp>*/> 676class _LIBCPP_TEMPLATE_VIS forward_list 677 : private __forward_list_base<_Tp, _Alloc> 678{ 679 typedef __forward_list_base<_Tp, _Alloc> base; 680 typedef typename base::__node_allocator __node_allocator; 681 typedef typename base::__node __node; 682 typedef typename base::__node_traits __node_traits; 683 typedef typename base::__node_pointer __node_pointer; 684 typedef typename base::__begin_node_pointer __begin_node_pointer; 685 686public: 687 typedef _Tp value_type; 688 typedef _Alloc allocator_type; 689 690 static_assert(is_same<value_type, typename allocator_type::value_type>::value, 691 "Allocator::value_type must be same type as value_type"); 692 693 static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value, 694 "[allocator.requirements] states that rebinding an allocator to the same type should result in the " 695 "original allocator"); 696 697 static_assert((!is_same<allocator_type, __node_allocator>::value), 698 "internal allocator type must differ from user-specified " 699 "type; otherwise overload resolution breaks"); 700 701 typedef value_type& reference; 702 typedef const value_type& const_reference; 703 typedef typename allocator_traits<allocator_type>::pointer pointer; 704 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 705 typedef typename allocator_traits<allocator_type>::size_type size_type; 706 typedef typename allocator_traits<allocator_type>::difference_type difference_type; 707 708 typedef typename base::iterator iterator; 709 typedef typename base::const_iterator const_iterator; 710#if _LIBCPP_STD_VER >= 20 711 typedef size_type __remove_return_type; 712#else 713 typedef void __remove_return_type; 714#endif 715 716 _LIBCPP_INLINE_VISIBILITY 717 forward_list() 718 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) 719 {} // = default; 720 _LIBCPP_INLINE_VISIBILITY 721 explicit forward_list(const allocator_type& __a); 722 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n); 723#if _LIBCPP_STD_VER >= 14 724 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a); 725#endif 726 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v); 727 728 template <class = __enable_if_t<__is_allocator<_Alloc>::value> > 729 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) 730 { 731 insert_after(cbefore_begin(), __n, __v); 732 } 733 734 template <class _InputIterator> 735 _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l, 736 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr); 737 template <class _InputIterator> 738 _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l, 739 const allocator_type& __a, 740 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr); 741 742#if _LIBCPP_STD_VER >= 23 743 template <_ContainerCompatibleRange<_Tp> _Range> 744 _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range, 745 const allocator_type& __a = allocator_type()) : base(__a) { 746 prepend_range(std::forward<_Range>(__range)); 747 } 748#endif 749 750 _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x); 751 _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a); 752 753 _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x); 754 755#ifndef _LIBCPP_CXX03_LANG 756 _LIBCPP_INLINE_VISIBILITY 757 forward_list(forward_list&& __x) 758 _NOEXCEPT_(is_nothrow_move_constructible<base>::value) 759 : base(_VSTD::move(__x)) {} 760 _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a); 761 762 _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il); 763 _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a); 764 765 _LIBCPP_INLINE_VISIBILITY 766 forward_list& operator=(forward_list&& __x) 767 _NOEXCEPT_( 768 __node_traits::propagate_on_container_move_assignment::value && 769 is_nothrow_move_assignable<allocator_type>::value); 770 771 _LIBCPP_INLINE_VISIBILITY 772 forward_list& operator=(initializer_list<value_type> __il); 773 774 _LIBCPP_INLINE_VISIBILITY 775 void assign(initializer_list<value_type> __il); 776#endif // _LIBCPP_CXX03_LANG 777 778 // ~forward_list() = default; 779 780 template <class _InputIterator> 781 __enable_if_t<__has_input_iterator_category<_InputIterator>::value, void> 782 _LIBCPP_HIDE_FROM_ABI assign(_InputIterator __f, _InputIterator __l); 783 784#if _LIBCPP_STD_VER >= 23 785 template <_ContainerCompatibleRange<_Tp> _Range> 786 _LIBCPP_HIDE_FROM_ABI 787 void assign_range(_Range&& __range) { 788 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 789 } 790#endif 791 792 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); 793 794 _LIBCPP_INLINE_VISIBILITY 795 allocator_type get_allocator() const _NOEXCEPT 796 {return allocator_type(base::__alloc());} 797 798 _LIBCPP_INLINE_VISIBILITY 799 iterator begin() _NOEXCEPT 800 {return iterator(base::__before_begin()->__next_);} 801 _LIBCPP_INLINE_VISIBILITY 802 const_iterator begin() const _NOEXCEPT 803 {return const_iterator(base::__before_begin()->__next_);} 804 _LIBCPP_INLINE_VISIBILITY 805 iterator end() _NOEXCEPT 806 {return iterator(nullptr);} 807 _LIBCPP_INLINE_VISIBILITY 808 const_iterator end() const _NOEXCEPT 809 {return const_iterator(nullptr);} 810 811 _LIBCPP_INLINE_VISIBILITY 812 const_iterator cbegin() const _NOEXCEPT 813 {return const_iterator(base::__before_begin()->__next_);} 814 _LIBCPP_INLINE_VISIBILITY 815 const_iterator cend() const _NOEXCEPT 816 {return const_iterator(nullptr);} 817 818 _LIBCPP_INLINE_VISIBILITY 819 iterator before_begin() _NOEXCEPT 820 {return iterator(base::__before_begin());} 821 _LIBCPP_INLINE_VISIBILITY 822 const_iterator before_begin() const _NOEXCEPT 823 {return const_iterator(base::__before_begin());} 824 _LIBCPP_INLINE_VISIBILITY 825 const_iterator cbefore_begin() const _NOEXCEPT 826 {return const_iterator(base::__before_begin());} 827 828 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 829 bool empty() const _NOEXCEPT 830 {return base::__before_begin()->__next_ == nullptr;} 831 _LIBCPP_INLINE_VISIBILITY 832 size_type max_size() const _NOEXCEPT { 833 return _VSTD::min<size_type>( 834 __node_traits::max_size(base::__alloc()), 835 numeric_limits<difference_type>::max()); 836 } 837 838 _LIBCPP_INLINE_VISIBILITY 839 reference front() {return base::__before_begin()->__next_->__value_;} 840 _LIBCPP_INLINE_VISIBILITY 841 const_reference front() const {return base::__before_begin()->__next_->__value_;} 842 843#ifndef _LIBCPP_CXX03_LANG 844#if _LIBCPP_STD_VER >= 17 845 template <class... _Args> 846 _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); 847#else 848 template <class... _Args> 849 _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); 850#endif 851 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); 852#endif // _LIBCPP_CXX03_LANG 853 _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); 854 855#if _LIBCPP_STD_VER >= 23 856 template <_ContainerCompatibleRange<_Tp> _Range> 857 _LIBCPP_HIDE_FROM_ABI 858 void prepend_range(_Range&& __range) { 859 insert_range_after(cbefore_begin(), std::forward<_Range>(__range)); 860 } 861#endif 862 863 _LIBCPP_HIDE_FROM_ABI void pop_front(); 864 865#ifndef _LIBCPP_CXX03_LANG 866 template <class... _Args> 867 _LIBCPP_HIDE_FROM_ABI iterator emplace_after(const_iterator __p, _Args&&... __args); 868 869 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, value_type&& __v); 870 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, initializer_list<value_type> __il) 871 {return insert_after(__p, __il.begin(), __il.end());} 872#endif // _LIBCPP_CXX03_LANG 873 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, const value_type& __v); 874 _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); 875 template <class _InputIterator> 876 _LIBCPP_INLINE_VISIBILITY 877 __enable_if_t<__has_input_iterator_category<_InputIterator>::value, iterator> 878 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); 879 880#if _LIBCPP_STD_VER >= 23 881 template <_ContainerCompatibleRange<_Tp> _Range> 882 _LIBCPP_HIDE_FROM_ABI 883 iterator insert_range_after(const_iterator __position, _Range&& __range) { 884 return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 885 } 886#endif 887 888 template <class _InputIterator, class _Sentinel> 889 _LIBCPP_HIDE_FROM_ABI 890 iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l); 891 892 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p); 893 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l); 894 895 _LIBCPP_INLINE_VISIBILITY 896 void swap(forward_list& __x) 897#if _LIBCPP_STD_VER >= 14 898 _NOEXCEPT 899#else 900 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || 901 __is_nothrow_swappable<__node_allocator>::value) 902#endif 903 {base::swap(__x);} 904 905 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); 906 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); 907 _LIBCPP_INLINE_VISIBILITY 908 void clear() _NOEXCEPT {base::clear();} 909 910 _LIBCPP_INLINE_VISIBILITY 911 void splice_after(const_iterator __p, forward_list&& __x); 912 _LIBCPP_INLINE_VISIBILITY 913 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i); 914 _LIBCPP_INLINE_VISIBILITY 915 void splice_after(const_iterator __p, forward_list&& __x, 916 const_iterator __f, const_iterator __l); 917 _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x); 918 _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); 919 _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, 920 const_iterator __f, const_iterator __l); 921 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __v); 922 template <class _Predicate> 923 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Predicate __pred); 924 _LIBCPP_INLINE_VISIBILITY 925 __remove_return_type unique() { return unique(__equal_to()); } 926 template <class _BinaryPredicate> 927 _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred); 928#ifndef _LIBCPP_CXX03_LANG 929 _LIBCPP_INLINE_VISIBILITY 930 void merge(forward_list&& __x) {merge(__x, __less<>());} 931 template <class _Compare> 932 _LIBCPP_INLINE_VISIBILITY 933 void merge(forward_list&& __x, _Compare __comp) 934 {merge(__x, _VSTD::move(__comp));} 935#endif // _LIBCPP_CXX03_LANG 936 _LIBCPP_INLINE_VISIBILITY 937 void merge(forward_list& __x) {merge(__x, __less<>());} 938 template <class _Compare> 939 _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp); 940 _LIBCPP_INLINE_VISIBILITY 941 void sort() {sort(__less<>());} 942 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp); 943 _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT; 944 945private: 946 947#ifndef _LIBCPP_CXX03_LANG 948 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type) 949 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 950 _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type); 951#endif // _LIBCPP_CXX03_LANG 952 953 template <class _Iter, class _Sent> 954 _LIBCPP_HIDE_FROM_ABI 955 void __assign_with_sentinel(_Iter __f, _Sent __l); 956 957 template <class _Compare> 958 static _LIBCPP_HIDE_FROM_ABI 959 __node_pointer 960 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp); 961 962 // TODO: Make this _LIBCPP_HIDE_FROM_ABI 963 template <class _Compare> 964 static _LIBCPP_HIDDEN 965 __node_pointer 966 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp); 967}; 968 969 970#if _LIBCPP_STD_VER >= 17 971template<class _InputIterator, 972 class _Alloc = allocator<__iter_value_type<_InputIterator>>, 973 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 974 class = enable_if_t<__is_allocator<_Alloc>::value> 975 > 976forward_list(_InputIterator, _InputIterator) 977 -> forward_list<__iter_value_type<_InputIterator>, _Alloc>; 978 979template<class _InputIterator, 980 class _Alloc, 981 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, 982 class = enable_if_t<__is_allocator<_Alloc>::value> 983 > 984forward_list(_InputIterator, _InputIterator, _Alloc) 985 -> forward_list<__iter_value_type<_InputIterator>, _Alloc>; 986#endif 987 988#if _LIBCPP_STD_VER >= 23 989template <ranges::input_range _Range, 990 class _Alloc = allocator<ranges::range_value_t<_Range>>, 991 class = enable_if_t<__is_allocator<_Alloc>::value> 992 > 993forward_list(from_range_t, _Range&&, _Alloc = _Alloc()) 994 -> forward_list<ranges::range_value_t<_Range>, _Alloc>; 995#endif 996 997template <class _Tp, class _Alloc> 998inline 999forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) 1000 : base(__a) 1001{ 1002} 1003 1004template <class _Tp, class _Alloc> 1005forward_list<_Tp, _Alloc>::forward_list(size_type __n) 1006{ 1007 if (__n > 0) 1008 { 1009 __node_allocator& __a = base::__alloc(); 1010 typedef __allocator_destructor<__node_allocator> _Dp; 1011 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); 1012 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, 1013 __p = __p->__next_as_begin()) 1014 { 1015 __h.reset(__node_traits::allocate(__a, 1)); 1016 __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); 1017 __h->__next_ = nullptr; 1018 __p->__next_ = __h.release(); 1019 } 1020 } 1021} 1022 1023#if _LIBCPP_STD_VER >= 14 1024template <class _Tp, class _Alloc> 1025forward_list<_Tp, _Alloc>::forward_list(size_type __n, 1026 const allocator_type& __base_alloc) 1027 : base ( __base_alloc ) 1028{ 1029 if (__n > 0) 1030 { 1031 __node_allocator& __a = base::__alloc(); 1032 typedef __allocator_destructor<__node_allocator> _Dp; 1033 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); 1034 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, 1035 __p = __p->__next_as_begin()) 1036 { 1037 __h.reset(__node_traits::allocate(__a, 1)); 1038 __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); 1039 __h->__next_ = nullptr; 1040 __p->__next_ = __h.release(); 1041 } 1042 } 1043} 1044#endif 1045 1046template <class _Tp, class _Alloc> 1047forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) 1048{ 1049 insert_after(cbefore_begin(), __n, __v); 1050} 1051 1052template <class _Tp, class _Alloc> 1053template <class _InputIterator> 1054forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, 1055 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*) 1056{ 1057 insert_after(cbefore_begin(), __f, __l); 1058} 1059 1060template <class _Tp, class _Alloc> 1061template <class _InputIterator> 1062forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, 1063 const allocator_type& __a, 1064 __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*) 1065 : base(__a) 1066{ 1067 insert_after(cbefore_begin(), __f, __l); 1068} 1069 1070template <class _Tp, class _Alloc> 1071forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x) 1072 : base( 1073 __node_traits::select_on_container_copy_construction(__x.__alloc())) { 1074 insert_after(cbefore_begin(), __x.begin(), __x.end()); 1075} 1076 1077template <class _Tp, class _Alloc> 1078forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, 1079 const __type_identity_t<allocator_type>& __a) 1080 : base(__a) 1081{ 1082 insert_after(cbefore_begin(), __x.begin(), __x.end()); 1083} 1084 1085template <class _Tp, class _Alloc> 1086forward_list<_Tp, _Alloc>& 1087forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) 1088{ 1089 if (this != _VSTD::addressof(__x)) 1090 { 1091 base::__copy_assign_alloc(__x); 1092 assign(__x.begin(), __x.end()); 1093 } 1094 return *this; 1095} 1096 1097#ifndef _LIBCPP_CXX03_LANG 1098template <class _Tp, class _Alloc> 1099forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, 1100 const __type_identity_t<allocator_type>& __a) 1101 : base(_VSTD::move(__x), __a) 1102{ 1103 if (base::__alloc() != __x.__alloc()) 1104 { 1105 typedef move_iterator<iterator> _Ip; 1106 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end())); 1107 } 1108} 1109 1110template <class _Tp, class _Alloc> 1111forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il) 1112{ 1113 insert_after(cbefore_begin(), __il.begin(), __il.end()); 1114} 1115 1116template <class _Tp, class _Alloc> 1117forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, 1118 const allocator_type& __a) 1119 : base(__a) 1120{ 1121 insert_after(cbefore_begin(), __il.begin(), __il.end()); 1122} 1123 1124template <class _Tp, class _Alloc> 1125void 1126forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type) 1127 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 1128{ 1129 clear(); 1130 base::__move_assign_alloc(__x); 1131 base::__before_begin()->__next_ = __x.__before_begin()->__next_; 1132 __x.__before_begin()->__next_ = nullptr; 1133} 1134 1135template <class _Tp, class _Alloc> 1136void 1137forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) 1138{ 1139 if (base::__alloc() == __x.__alloc()) 1140 __move_assign(__x, true_type()); 1141 else 1142 { 1143 typedef move_iterator<iterator> _Ip; 1144 assign(_Ip(__x.begin()), _Ip(__x.end())); 1145 } 1146} 1147 1148template <class _Tp, class _Alloc> 1149inline 1150forward_list<_Tp, _Alloc>& 1151forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) 1152 _NOEXCEPT_( 1153 __node_traits::propagate_on_container_move_assignment::value && 1154 is_nothrow_move_assignable<allocator_type>::value) 1155{ 1156 __move_assign(__x, integral_constant<bool, 1157 __node_traits::propagate_on_container_move_assignment::value>()); 1158 return *this; 1159} 1160 1161template <class _Tp, class _Alloc> 1162inline 1163forward_list<_Tp, _Alloc>& 1164forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) 1165{ 1166 assign(__il.begin(), __il.end()); 1167 return *this; 1168} 1169 1170#endif // _LIBCPP_CXX03_LANG 1171 1172template <class _Tp, class _Alloc> 1173template <class _InputIterator> 1174__enable_if_t<__has_input_iterator_category<_InputIterator>::value, void> 1175forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) 1176{ 1177 __assign_with_sentinel(__f, __l); 1178} 1179 1180template <class _Tp, class _Alloc> 1181template <class _Iter, class _Sent> 1182_LIBCPP_HIDE_FROM_ABI 1183void forward_list<_Tp, _Alloc>::__assign_with_sentinel(_Iter __f, _Sent __l) { 1184 iterator __i = before_begin(); 1185 iterator __j = _VSTD::next(__i); 1186 iterator __e = end(); 1187 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f) 1188 *__j = *__f; 1189 if (__j == __e) 1190 __insert_after_with_sentinel(__i, std::move(__f), std::move(__l)); 1191 else 1192 erase_after(__i, __e); 1193} 1194 1195template <class _Tp, class _Alloc> 1196void 1197forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) 1198{ 1199 iterator __i = before_begin(); 1200 iterator __j = _VSTD::next(__i); 1201 iterator __e = end(); 1202 for (; __j != __e && __n > 0; --__n, ++__i, ++__j) 1203 *__j = __v; 1204 if (__j == __e) 1205 insert_after(__i, __n, __v); 1206 else 1207 erase_after(__i, __e); 1208} 1209 1210#ifndef _LIBCPP_CXX03_LANG 1211 1212template <class _Tp, class _Alloc> 1213inline 1214void 1215forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) 1216{ 1217 assign(__il.begin(), __il.end()); 1218} 1219 1220template <class _Tp, class _Alloc> 1221template <class... _Args> 1222#if _LIBCPP_STD_VER >= 17 1223typename forward_list<_Tp, _Alloc>::reference 1224#else 1225void 1226#endif 1227forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) 1228{ 1229 __node_allocator& __a = base::__alloc(); 1230 typedef __allocator_destructor<__node_allocator> _Dp; 1231 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); 1232 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), 1233 _VSTD::forward<_Args>(__args)...); 1234 __h->__next_ = base::__before_begin()->__next_; 1235 base::__before_begin()->__next_ = __h.release(); 1236#if _LIBCPP_STD_VER >= 17 1237 return base::__before_begin()->__next_->__value_; 1238#endif 1239} 1240 1241template <class _Tp, class _Alloc> 1242void 1243forward_list<_Tp, _Alloc>::push_front(value_type&& __v) 1244{ 1245 __node_allocator& __a = base::__alloc(); 1246 typedef __allocator_destructor<__node_allocator> _Dp; 1247 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); 1248 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); 1249 __h->__next_ = base::__before_begin()->__next_; 1250 base::__before_begin()->__next_ = __h.release(); 1251} 1252 1253#endif // _LIBCPP_CXX03_LANG 1254 1255template <class _Tp, class _Alloc> 1256void 1257forward_list<_Tp, _Alloc>::push_front(const value_type& __v) 1258{ 1259 __node_allocator& __a = base::__alloc(); 1260 typedef __allocator_destructor<__node_allocator> _Dp; 1261 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); 1262 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); 1263 __h->__next_ = base::__before_begin()->__next_; 1264 base::__before_begin()->__next_ = __h.release(); 1265} 1266 1267template <class _Tp, class _Alloc> 1268void 1269forward_list<_Tp, _Alloc>::pop_front() 1270{ 1271 __node_allocator& __a = base::__alloc(); 1272 __node_pointer __p = base::__before_begin()->__next_; 1273 base::__before_begin()->__next_ = __p->__next_; 1274 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_)); 1275 __node_traits::deallocate(__a, __p, 1); 1276} 1277 1278#ifndef _LIBCPP_CXX03_LANG 1279 1280template <class _Tp, class _Alloc> 1281template <class... _Args> 1282typename forward_list<_Tp, _Alloc>::iterator 1283forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) 1284{ 1285 __begin_node_pointer const __r = __p.__get_begin(); 1286 __node_allocator& __a = base::__alloc(); 1287 typedef __allocator_destructor<__node_allocator> _Dp; 1288 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); 1289 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), 1290 _VSTD::forward<_Args>(__args)...); 1291 __h->__next_ = __r->__next_; 1292 __r->__next_ = __h.release(); 1293 return iterator(__r->__next_); 1294} 1295 1296template <class _Tp, class _Alloc> 1297typename forward_list<_Tp, _Alloc>::iterator 1298forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) 1299{ 1300 __begin_node_pointer const __r = __p.__get_begin(); 1301 __node_allocator& __a = base::__alloc(); 1302 typedef __allocator_destructor<__node_allocator> _Dp; 1303 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); 1304 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); 1305 __h->__next_ = __r->__next_; 1306 __r->__next_ = __h.release(); 1307 return iterator(__r->__next_); 1308} 1309 1310#endif // _LIBCPP_CXX03_LANG 1311 1312template <class _Tp, class _Alloc> 1313typename forward_list<_Tp, _Alloc>::iterator 1314forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) 1315{ 1316 __begin_node_pointer const __r = __p.__get_begin(); 1317 __node_allocator& __a = base::__alloc(); 1318 typedef __allocator_destructor<__node_allocator> _Dp; 1319 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); 1320 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); 1321 __h->__next_ = __r->__next_; 1322 __r->__next_ = __h.release(); 1323 return iterator(__r->__next_); 1324} 1325 1326template <class _Tp, class _Alloc> 1327typename forward_list<_Tp, _Alloc>::iterator 1328forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, 1329 const value_type& __v) 1330{ 1331 using _Guard = __allocation_guard<__node_allocator>; 1332 1333 __begin_node_pointer __r = __p.__get_begin(); 1334 if (__n > 0) 1335 { 1336 __node_allocator& __a = base::__alloc(); 1337 1338 __node_pointer __first = nullptr; 1339 { 1340 _Guard __h(__a, 1); 1341 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v); 1342 __h.__get()->__next_ = nullptr; 1343 __first = __h.__release_ptr(); 1344 } 1345 __node_pointer __last = __first; 1346#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1347 try 1348 { 1349#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1350 for (--__n; __n != 0; --__n, __last = __last->__next_) 1351 { 1352 _Guard __h(__a, 1); 1353 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v); 1354 __h.__get()->__next_ = nullptr; 1355 __last->__next_ = __h.__release_ptr(); 1356 } 1357#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1358 } 1359 catch (...) 1360 { 1361 while (__first != nullptr) 1362 { 1363 __node_pointer __next = __first->__next_; 1364 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); 1365 __node_traits::deallocate(__a, __first, 1); 1366 __first = __next; 1367 } 1368 throw; 1369 } 1370#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1371 __last->__next_ = __r->__next_; 1372 __r->__next_ = __first; 1373 __r = static_cast<__begin_node_pointer>(__last); 1374 } 1375 return iterator(__r); 1376} 1377 1378template <class _Tp, class _Alloc> 1379template <class _InputIterator> 1380__enable_if_t<__has_input_iterator_category<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator> 1381forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, 1382 _InputIterator __f, _InputIterator __l) 1383{ 1384 return __insert_after_with_sentinel(__p, std::move(__f), std::move(__l)); 1385} 1386 1387template <class _Tp, class _Alloc> 1388template <class _InputIterator, class _Sentinel> 1389_LIBCPP_HIDE_FROM_ABI 1390typename forward_list<_Tp, _Alloc>::iterator 1391forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) { 1392 using _Guard = __allocation_guard<__node_allocator>; 1393 __begin_node_pointer __r = __p.__get_begin(); 1394 1395 if (__f != __l) 1396 { 1397 __node_allocator& __a = base::__alloc(); 1398 __node_pointer __first = nullptr; 1399 { 1400 _Guard __h(__a, 1); 1401 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f); 1402 __h.__get()->__next_ = nullptr; 1403 __first = __h.__release_ptr(); 1404 } 1405 __node_pointer __last = __first; 1406 1407#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1408 try 1409 { 1410#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1411 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) 1412 { 1413 _Guard __h(__a, 1); 1414 __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f); 1415 __h.__get()->__next_ = nullptr; 1416 __last->__next_ = __h.__release_ptr(); 1417 } 1418#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1419 } 1420 catch (...) 1421 { 1422 while (__first != nullptr) 1423 { 1424 __node_pointer __next = __first->__next_; 1425 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_)); 1426 __node_traits::deallocate(__a, __first, 1); 1427 __first = __next; 1428 } 1429 throw; 1430 } 1431#endif // _LIBCPP_HAS_NO_EXCEPTIONS 1432 1433 __last->__next_ = __r->__next_; 1434 __r->__next_ = __first; 1435 __r = static_cast<__begin_node_pointer>(__last); 1436 } 1437 1438 return iterator(__r); 1439} 1440 1441template <class _Tp, class _Alloc> 1442typename forward_list<_Tp, _Alloc>::iterator 1443forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) 1444{ 1445 __begin_node_pointer __p = __f.__get_begin(); 1446 __node_pointer __n = __p->__next_; 1447 __p->__next_ = __n->__next_; 1448 __node_allocator& __a = base::__alloc(); 1449 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); 1450 __node_traits::deallocate(__a, __n, 1); 1451 return iterator(__p->__next_); 1452} 1453 1454template <class _Tp, class _Alloc> 1455typename forward_list<_Tp, _Alloc>::iterator 1456forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) 1457{ 1458 __node_pointer __e = __l.__get_unsafe_node_pointer(); 1459 if (__f != __l) 1460 { 1461 __begin_node_pointer __bp = __f.__get_begin(); 1462 1463 __node_pointer __n = __bp->__next_; 1464 if (__n != __e) 1465 { 1466 __bp->__next_ = __e; 1467 __node_allocator& __a = base::__alloc(); 1468 do 1469 { 1470 __node_pointer __tmp = __n->__next_; 1471 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); 1472 __node_traits::deallocate(__a, __n, 1); 1473 __n = __tmp; 1474 } while (__n != __e); 1475 } 1476 } 1477 return iterator(__e); 1478} 1479 1480template <class _Tp, class _Alloc> 1481void 1482forward_list<_Tp, _Alloc>::resize(size_type __n) 1483{ 1484 size_type __sz = 0; 1485 iterator __p = before_begin(); 1486 iterator __i = begin(); 1487 iterator __e = end(); 1488 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) 1489 ; 1490 if (__i != __e) 1491 erase_after(__p, __e); 1492 else 1493 { 1494 __n -= __sz; 1495 if (__n > 0) 1496 { 1497 __node_allocator& __a = base::__alloc(); 1498 typedef __allocator_destructor<__node_allocator> _Dp; 1499 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); 1500 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, 1501 __ptr = __ptr->__next_as_begin()) 1502 { 1503 __h.reset(__node_traits::allocate(__a, 1)); 1504 __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); 1505 __h->__next_ = nullptr; 1506 __ptr->__next_ = __h.release(); 1507 } 1508 } 1509 } 1510} 1511 1512template <class _Tp, class _Alloc> 1513void 1514forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) 1515{ 1516 size_type __sz = 0; 1517 iterator __p = before_begin(); 1518 iterator __i = begin(); 1519 iterator __e = end(); 1520 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) 1521 ; 1522 if (__i != __e) 1523 erase_after(__p, __e); 1524 else 1525 { 1526 __n -= __sz; 1527 if (__n > 0) 1528 { 1529 __node_allocator& __a = base::__alloc(); 1530 typedef __allocator_destructor<__node_allocator> _Dp; 1531 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); 1532 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, 1533 __ptr = __ptr->__next_as_begin()) 1534 { 1535 __h.reset(__node_traits::allocate(__a, 1)); 1536 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); 1537 __h->__next_ = nullptr; 1538 __ptr->__next_ = __h.release(); 1539 } 1540 } 1541 } 1542} 1543 1544template <class _Tp, class _Alloc> 1545void 1546forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, 1547 forward_list& __x) 1548{ 1549 if (!__x.empty()) 1550 { 1551 if (__p.__get_begin()->__next_ != nullptr) 1552 { 1553 const_iterator __lm1 = __x.before_begin(); 1554 while (__lm1.__get_begin()->__next_ != nullptr) 1555 ++__lm1; 1556 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; 1557 } 1558 __p.__get_begin()->__next_ = __x.__before_begin()->__next_; 1559 __x.__before_begin()->__next_ = nullptr; 1560 } 1561} 1562 1563template <class _Tp, class _Alloc> 1564void 1565forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, 1566 forward_list& /*__other*/, 1567 const_iterator __i) 1568{ 1569 const_iterator __lm1 = _VSTD::next(__i); 1570 if (__p != __i && __p != __lm1) 1571 { 1572 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_; 1573 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; 1574 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer(); 1575 } 1576} 1577 1578template <class _Tp, class _Alloc> 1579void 1580forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, 1581 forward_list& /*__other*/, 1582 const_iterator __f, const_iterator __l) 1583{ 1584 if (__f != __l && __p != __f) 1585 { 1586 const_iterator __lm1 = __f; 1587 while (__lm1.__get_begin()->__next_ != __l.__get_begin()) 1588 ++__lm1; 1589 if (__f != __lm1) 1590 { 1591 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; 1592 __p.__get_begin()->__next_ = __f.__get_begin()->__next_; 1593 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer(); 1594 } 1595 } 1596} 1597 1598template <class _Tp, class _Alloc> 1599inline _LIBCPP_INLINE_VISIBILITY 1600void 1601forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, 1602 forward_list&& __x) 1603{ 1604 splice_after(__p, __x); 1605} 1606 1607template <class _Tp, class _Alloc> 1608inline _LIBCPP_INLINE_VISIBILITY 1609void 1610forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, 1611 forward_list&& __x, 1612 const_iterator __i) 1613{ 1614 splice_after(__p, __x, __i); 1615} 1616 1617template <class _Tp, class _Alloc> 1618inline _LIBCPP_INLINE_VISIBILITY 1619void 1620forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, 1621 forward_list&& __x, 1622 const_iterator __f, const_iterator __l) 1623{ 1624 splice_after(__p, __x, __f, __l); 1625} 1626 1627template <class _Tp, class _Alloc> 1628typename forward_list<_Tp, _Alloc>::__remove_return_type 1629forward_list<_Tp, _Alloc>::remove(const value_type& __v) 1630{ 1631 forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing 1632 typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; 1633 const iterator __e = end(); 1634 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) 1635 { 1636 if (__i.__get_begin()->__next_->__value_ == __v) 1637 { 1638 ++__count_removed; 1639 iterator __j = _VSTD::next(__i, 2); 1640 for (; __j != __e && *__j == __v; ++__j) 1641 ++__count_removed; 1642 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); 1643 if (__j == __e) 1644 break; 1645 __i = __j; 1646 } 1647 else 1648 ++__i; 1649 } 1650 1651 return (__remove_return_type) __count_removed; 1652} 1653 1654template <class _Tp, class _Alloc> 1655template <class _Predicate> 1656typename forward_list<_Tp, _Alloc>::__remove_return_type 1657forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) 1658{ 1659 forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing 1660 typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; 1661 const iterator __e = end(); 1662 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) 1663 { 1664 if (__pred(__i.__get_begin()->__next_->__value_)) 1665 { 1666 ++__count_removed; 1667 iterator __j = _VSTD::next(__i, 2); 1668 for (; __j != __e && __pred(*__j); ++__j) 1669 ++__count_removed; 1670 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); 1671 if (__j == __e) 1672 break; 1673 __i = __j; 1674 } 1675 else 1676 ++__i; 1677 } 1678 1679 return (__remove_return_type) __count_removed; 1680} 1681 1682template <class _Tp, class _Alloc> 1683template <class _BinaryPredicate> 1684typename forward_list<_Tp, _Alloc>::__remove_return_type 1685forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) 1686{ 1687 forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing 1688 typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0; 1689 for (iterator __i = begin(), __e = end(); __i != __e;) 1690 { 1691 iterator __j = _VSTD::next(__i); 1692 for (; __j != __e && __binary_pred(*__i, *__j); ++__j) 1693 ++__count_removed; 1694 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer()) 1695 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); 1696 __i = __j; 1697 } 1698 1699 return (__remove_return_type) __count_removed; 1700} 1701 1702template <class _Tp, class _Alloc> 1703template <class _Compare> 1704void 1705forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) 1706{ 1707 if (this != _VSTD::addressof(__x)) 1708 { 1709 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_, 1710 __x.__before_begin()->__next_, 1711 __comp); 1712 __x.__before_begin()->__next_ = nullptr; 1713 } 1714} 1715 1716template <class _Tp, class _Alloc> 1717template <class _Compare> 1718typename forward_list<_Tp, _Alloc>::__node_pointer 1719forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, 1720 _Compare& __comp) 1721{ 1722 if (__f1 == nullptr) 1723 return __f2; 1724 if (__f2 == nullptr) 1725 return __f1; 1726 __node_pointer __r; 1727 if (__comp(__f2->__value_, __f1->__value_)) 1728 { 1729 __node_pointer __t = __f2; 1730 while (__t->__next_ != nullptr && 1731 __comp(__t->__next_->__value_, __f1->__value_)) 1732 __t = __t->__next_; 1733 __r = __f2; 1734 __f2 = __t->__next_; 1735 __t->__next_ = __f1; 1736 } 1737 else 1738 __r = __f1; 1739 __node_pointer __p = __f1; 1740 __f1 = __f1->__next_; 1741 while (__f1 != nullptr && __f2 != nullptr) 1742 { 1743 if (__comp(__f2->__value_, __f1->__value_)) 1744 { 1745 __node_pointer __t = __f2; 1746 while (__t->__next_ != nullptr && 1747 __comp(__t->__next_->__value_, __f1->__value_)) 1748 __t = __t->__next_; 1749 __p->__next_ = __f2; 1750 __f2 = __t->__next_; 1751 __t->__next_ = __f1; 1752 } 1753 __p = __f1; 1754 __f1 = __f1->__next_; 1755 } 1756 if (__f2 != nullptr) 1757 __p->__next_ = __f2; 1758 return __r; 1759} 1760 1761template <class _Tp, class _Alloc> 1762template <class _Compare> 1763inline 1764void 1765forward_list<_Tp, _Alloc>::sort(_Compare __comp) 1766{ 1767 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_, 1768 _VSTD::distance(begin(), end()), __comp); 1769} 1770 1771template <class _Tp, class _Alloc> 1772template <class _Compare> 1773typename forward_list<_Tp, _Alloc>::__node_pointer 1774forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, 1775 _Compare& __comp) 1776{ 1777 switch (__sz) 1778 { 1779 case 0: 1780 case 1: 1781 return __f1; 1782 case 2: 1783 if (__comp(__f1->__next_->__value_, __f1->__value_)) 1784 { 1785 __node_pointer __t = __f1->__next_; 1786 __t->__next_ = __f1; 1787 __f1->__next_ = nullptr; 1788 __f1 = __t; 1789 } 1790 return __f1; 1791 } 1792 difference_type __sz1 = __sz / 2; 1793 difference_type __sz2 = __sz - __sz1; 1794 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer(); 1795 __node_pointer __f2 = __t->__next_; 1796 __t->__next_ = nullptr; 1797 return __merge(__sort(__f1, __sz1, __comp), 1798 __sort(__f2, __sz2, __comp), __comp); 1799} 1800 1801template <class _Tp, class _Alloc> 1802void 1803forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT 1804{ 1805 __node_pointer __p = base::__before_begin()->__next_; 1806 if (__p != nullptr) 1807 { 1808 __node_pointer __f = __p->__next_; 1809 __p->__next_ = nullptr; 1810 while (__f != nullptr) 1811 { 1812 __node_pointer __t = __f->__next_; 1813 __f->__next_ = __p; 1814 __p = __f; 1815 __f = __t; 1816 } 1817 base::__before_begin()->__next_ = __p; 1818 } 1819} 1820 1821template <class _Tp, class _Alloc> 1822_LIBCPP_HIDE_FROM_ABI 1823bool operator==(const forward_list<_Tp, _Alloc>& __x, 1824 const forward_list<_Tp, _Alloc>& __y) 1825{ 1826 typedef forward_list<_Tp, _Alloc> _Cp; 1827 typedef typename _Cp::const_iterator _Ip; 1828 _Ip __ix = __x.begin(); 1829 _Ip __ex = __x.end(); 1830 _Ip __iy = __y.begin(); 1831 _Ip __ey = __y.end(); 1832 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy) 1833 if (!(*__ix == *__iy)) 1834 return false; 1835 return (__ix == __ex) == (__iy == __ey); 1836} 1837 1838#if _LIBCPP_STD_VER <= 17 1839 1840template <class _Tp, class _Alloc> 1841inline _LIBCPP_INLINE_VISIBILITY 1842bool operator!=(const forward_list<_Tp, _Alloc>& __x, 1843 const forward_list<_Tp, _Alloc>& __y) 1844{ 1845 return !(__x == __y); 1846} 1847 1848template <class _Tp, class _Alloc> 1849inline _LIBCPP_INLINE_VISIBILITY 1850bool operator< (const forward_list<_Tp, _Alloc>& __x, 1851 const forward_list<_Tp, _Alloc>& __y) 1852{ 1853 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), 1854 __y.begin(), __y.end()); 1855} 1856 1857template <class _Tp, class _Alloc> 1858inline _LIBCPP_INLINE_VISIBILITY 1859bool operator> (const forward_list<_Tp, _Alloc>& __x, 1860 const forward_list<_Tp, _Alloc>& __y) 1861{ 1862 return __y < __x; 1863} 1864 1865template <class _Tp, class _Alloc> 1866inline _LIBCPP_INLINE_VISIBILITY 1867bool operator>=(const forward_list<_Tp, _Alloc>& __x, 1868 const forward_list<_Tp, _Alloc>& __y) 1869{ 1870 return !(__x < __y); 1871} 1872 1873template <class _Tp, class _Alloc> 1874inline _LIBCPP_INLINE_VISIBILITY 1875bool operator<=(const forward_list<_Tp, _Alloc>& __x, 1876 const forward_list<_Tp, _Alloc>& __y) 1877{ 1878 return !(__y < __x); 1879} 1880 1881#else // #if _LIBCPP_STD_VER <= 17 1882 1883template <class _Tp, class _Allocator> 1884_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> 1885operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _Allocator>& __y) { 1886 return std::lexicographical_compare_three_way( 1887 __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); 1888} 1889 1890#endif // #if _LIBCPP_STD_VER <= 17 1891 1892template <class _Tp, class _Alloc> 1893inline _LIBCPP_INLINE_VISIBILITY 1894void 1895swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) 1896 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 1897{ 1898 __x.swap(__y); 1899} 1900 1901#if _LIBCPP_STD_VER >= 20 1902template <class _Tp, class _Allocator, class _Predicate> 1903inline _LIBCPP_INLINE_VISIBILITY 1904 typename forward_list<_Tp, _Allocator>::size_type 1905 erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) { 1906 return __c.remove_if(__pred); 1907} 1908 1909template <class _Tp, class _Allocator, class _Up> 1910inline _LIBCPP_INLINE_VISIBILITY 1911 typename forward_list<_Tp, _Allocator>::size_type 1912 erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) { 1913 return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); 1914} 1915#endif 1916 1917_LIBCPP_END_NAMESPACE_STD 1918 1919#if _LIBCPP_STD_VER >= 17 1920_LIBCPP_BEGIN_NAMESPACE_STD 1921namespace pmr { 1922template <class _ValueT> 1923using forward_list _LIBCPP_AVAILABILITY_PMR = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>; 1924} // namespace pmr 1925_LIBCPP_END_NAMESPACE_STD 1926#endif 1927 1928_LIBCPP_POP_MACROS 1929 1930#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1931# include <algorithm> 1932# include <atomic> 1933# include <concepts> 1934# include <cstdlib> 1935# include <functional> 1936# include <iosfwd> 1937# include <iterator> 1938# include <type_traits> 1939# include <typeinfo> 1940#endif 1941 1942#endif // _LIBCPP_FORWARD_LIST 1943