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