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