1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_LIST 11#define _LIBCPP_LIST 12 13/* 14 list synopsis 15 16namespace std 17{ 18 19template <class T, class Alloc = allocator<T> > 20class list 21{ 22public: 23 24 // types: 25 typedef T value_type; 26 typedef Alloc allocator_type; 27 typedef typename allocator_type::reference reference; 28 typedef typename allocator_type::const_reference const_reference; 29 typedef typename allocator_type::pointer pointer; 30 typedef typename allocator_type::const_pointer const_pointer; 31 typedef implementation-defined iterator; 32 typedef implementation-defined const_iterator; 33 typedef implementation-defined size_type; 34 typedef implementation-defined difference_type; 35 typedef reverse_iterator<iterator> reverse_iterator; 36 typedef reverse_iterator<const_iterator> const_reverse_iterator; 37 38 list() 39 noexcept(is_nothrow_default_constructible<allocator_type>::value); 40 explicit list(const allocator_type& a); 41 explicit list(size_type n); 42 explicit list(size_type n, const allocator_type& a); // C++14 43 list(size_type n, const value_type& value); 44 list(size_type n, const value_type& value, const allocator_type& a); 45 template <class Iter> 46 list(Iter first, Iter last); 47 template <class Iter> 48 list(Iter first, Iter last, const allocator_type& a); 49 list(const list& x); 50 list(const list&, const allocator_type& a); 51 list(list&& x) 52 noexcept(is_nothrow_move_constructible<allocator_type>::value); 53 list(list&&, const allocator_type& a); 54 list(initializer_list<value_type>); 55 list(initializer_list<value_type>, const allocator_type& a); 56 57 ~list(); 58 59 list& operator=(const list& x); 60 list& operator=(list&& x) 61 noexcept( 62 allocator_type::propagate_on_container_move_assignment::value && 63 is_nothrow_move_assignable<allocator_type>::value); 64 list& operator=(initializer_list<value_type>); 65 template <class Iter> 66 void assign(Iter first, Iter last); 67 void assign(size_type n, const value_type& t); 68 void assign(initializer_list<value_type>); 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 reverse_iterator rbegin() noexcept; 77 const_reverse_iterator rbegin() const noexcept; 78 reverse_iterator rend() noexcept; 79 const_reverse_iterator rend() const noexcept; 80 const_iterator cbegin() const noexcept; 81 const_iterator cend() const noexcept; 82 const_reverse_iterator crbegin() const noexcept; 83 const_reverse_iterator crend() const noexcept; 84 85 reference front(); 86 const_reference front() const; 87 reference back(); 88 const_reference back() const; 89 90 bool empty() const noexcept; 91 size_type size() const noexcept; 92 size_type max_size() const noexcept; 93 94 template <class... Args> 95 reference emplace_front(Args&&... args); // reference in C++17 96 void pop_front(); 97 template <class... Args> 98 reference emplace_back(Args&&... args); // reference in C++17 99 void pop_back(); 100 void push_front(const value_type& x); 101 void push_front(value_type&& x); 102 void push_back(const value_type& x); 103 void push_back(value_type&& x); 104 template <class... Args> 105 iterator emplace(const_iterator position, Args&&... args); 106 iterator insert(const_iterator position, const value_type& x); 107 iterator insert(const_iterator position, value_type&& x); 108 iterator insert(const_iterator position, size_type n, const value_type& x); 109 template <class Iter> 110 iterator insert(const_iterator position, Iter first, Iter last); 111 iterator insert(const_iterator position, initializer_list<value_type> il); 112 113 iterator erase(const_iterator position); 114 iterator erase(const_iterator position, const_iterator last); 115 116 void resize(size_type sz); 117 void resize(size_type sz, const value_type& c); 118 119 void swap(list&) 120 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17 121 void clear() noexcept; 122 123 void splice(const_iterator position, list& x); 124 void splice(const_iterator position, list&& x); 125 void splice(const_iterator position, list& x, const_iterator i); 126 void splice(const_iterator position, list&& x, const_iterator i); 127 void splice(const_iterator position, list& x, const_iterator first, 128 const_iterator last); 129 void splice(const_iterator position, list&& x, const_iterator first, 130 const_iterator last); 131 132 size_type remove(const value_type& value); // void before C++20 133 template <class Pred> 134 size_type remove_if(Pred pred); // void before C++20 135 size_type unique(); // void before C++20 136 template <class BinaryPredicate> 137 size_type unique(BinaryPredicate binary_pred); // void before C++20 138 void merge(list& x); 139 void merge(list&& x); 140 template <class Compare> 141 void merge(list& x, Compare comp); 142 template <class Compare> 143 void merge(list&& x, Compare comp); 144 void sort(); 145 template <class Compare> 146 void sort(Compare comp); 147 void reverse() noexcept; 148}; 149 150 151template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> 152 list(InputIterator, InputIterator, Allocator = Allocator()) 153 -> list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 154 155template <class T, class Alloc> 156 bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y); 157template <class T, class Alloc> 158 bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y); 159template <class T, class Alloc> 160 bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y); 161template <class T, class Alloc> 162 bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y); 163template <class T, class Alloc> 164 bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y); 165template <class T, class Alloc> 166 bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y); 167 168template <class T, class Alloc> 169 void swap(list<T,Alloc>& x, list<T,Alloc>& y) 170 noexcept(noexcept(x.swap(y))); 171 172template <class T, class Allocator, class U> 173 typename list<T, Allocator>::size_type 174 erase(list<T, Allocator>& c, const U& value); // C++20 175template <class T, class Allocator, class Predicate> 176 typename list<T, Allocator>::size_type 177 erase_if(list<T, Allocator>& c, Predicate pred); // C++20 178 179} // std 180 181*/ 182 183#include <__config> 184#include <__debug> 185#include <__utility/forward.h> 186#include <algorithm> 187#include <initializer_list> 188#include <iterator> 189#include <limits> 190#include <memory> 191#include <type_traits> 192#include <version> 193 194#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 195#pragma GCC system_header 196#endif 197 198_LIBCPP_PUSH_MACROS 199#include <__undef_macros> 200 201 202_LIBCPP_BEGIN_NAMESPACE_STD 203 204template <class _Tp, class _VoidPtr> struct __list_node; 205template <class _Tp, class _VoidPtr> struct __list_node_base; 206 207template <class _Tp, class _VoidPtr> 208struct __list_node_pointer_traits { 209 typedef typename __rebind_pointer<_VoidPtr, __list_node<_Tp, _VoidPtr> >::type 210 __node_pointer; 211 typedef typename __rebind_pointer<_VoidPtr, __list_node_base<_Tp, _VoidPtr> >::type 212 __base_pointer; 213 214#if defined(_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB) 215 typedef __base_pointer __link_pointer; 216#else 217 typedef typename conditional< 218 is_pointer<_VoidPtr>::value, 219 __base_pointer, 220 __node_pointer 221 >::type __link_pointer; 222#endif 223 224 typedef typename conditional< 225 is_same<__link_pointer, __node_pointer>::value, 226 __base_pointer, 227 __node_pointer 228 >::type __non_link_pointer; 229 230 static _LIBCPP_INLINE_VISIBILITY 231 __link_pointer __unsafe_link_pointer_cast(__link_pointer __p) { 232 return __p; 233 } 234 235 static _LIBCPP_INLINE_VISIBILITY 236 __link_pointer __unsafe_link_pointer_cast(__non_link_pointer __p) { 237 return static_cast<__link_pointer>(static_cast<_VoidPtr>(__p)); 238 } 239 240}; 241 242template <class _Tp, class _VoidPtr> 243struct __list_node_base 244{ 245 typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits; 246 typedef typename _NodeTraits::__node_pointer __node_pointer; 247 typedef typename _NodeTraits::__base_pointer __base_pointer; 248 typedef typename _NodeTraits::__link_pointer __link_pointer; 249 250 __link_pointer __prev_; 251 __link_pointer __next_; 252 253 _LIBCPP_INLINE_VISIBILITY 254 __list_node_base() : __prev_(_NodeTraits::__unsafe_link_pointer_cast(__self())), 255 __next_(_NodeTraits::__unsafe_link_pointer_cast(__self())) {} 256 257 _LIBCPP_INLINE_VISIBILITY 258 __base_pointer __self() { 259 return pointer_traits<__base_pointer>::pointer_to(*this); 260 } 261 262 _LIBCPP_INLINE_VISIBILITY 263 __node_pointer __as_node() { 264 return static_cast<__node_pointer>(__self()); 265 } 266}; 267 268template <class _Tp, class _VoidPtr> 269struct _LIBCPP_STANDALONE_DEBUG __list_node 270 : public __list_node_base<_Tp, _VoidPtr> 271{ 272 _Tp __value_; 273 274 typedef __list_node_base<_Tp, _VoidPtr> __base; 275 typedef typename __base::__link_pointer __link_pointer; 276 277 _LIBCPP_INLINE_VISIBILITY 278 __link_pointer __as_link() { 279 return static_cast<__link_pointer>(__base::__self()); 280 } 281}; 282 283template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS list; 284template <class _Tp, class _Alloc> class __list_imp; 285template <class _Tp, class _VoidPtr> class _LIBCPP_TEMPLATE_VIS __list_const_iterator; 286 287template <class _Tp, class _VoidPtr> 288class _LIBCPP_TEMPLATE_VIS __list_iterator 289{ 290 typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits; 291 typedef typename _NodeTraits::__link_pointer __link_pointer; 292 293 __link_pointer __ptr_; 294 295#if _LIBCPP_DEBUG_LEVEL == 2 296 _LIBCPP_INLINE_VISIBILITY 297 explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT 298 : __ptr_(__p) 299 { 300 __get_db()->__insert_ic(this, __c); 301 } 302#else 303 _LIBCPP_INLINE_VISIBILITY 304 explicit __list_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {} 305#endif 306 307 308 309 template<class, class> friend class list; 310 template<class, class> friend class __list_imp; 311 template<class, class> friend class __list_const_iterator; 312public: 313 typedef bidirectional_iterator_tag iterator_category; 314 typedef _Tp value_type; 315 typedef value_type& reference; 316 typedef typename __rebind_pointer<_VoidPtr, value_type>::type pointer; 317 typedef typename pointer_traits<pointer>::difference_type difference_type; 318 319 _LIBCPP_INLINE_VISIBILITY 320 __list_iterator() _NOEXCEPT : __ptr_(nullptr) 321 { 322#if _LIBCPP_DEBUG_LEVEL == 2 323 __get_db()->__insert_i(this); 324#endif 325 } 326 327#if _LIBCPP_DEBUG_LEVEL == 2 328 329 _LIBCPP_INLINE_VISIBILITY 330 __list_iterator(const __list_iterator& __p) 331 : __ptr_(__p.__ptr_) 332 { 333 __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); 334 } 335 336 _LIBCPP_INLINE_VISIBILITY 337 ~__list_iterator() 338 { 339 __get_db()->__erase_i(this); 340 } 341 342 _LIBCPP_INLINE_VISIBILITY 343 __list_iterator& operator=(const __list_iterator& __p) 344 { 345 if (this != _VSTD::addressof(__p)) 346 { 347 __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); 348 __ptr_ = __p.__ptr_; 349 } 350 return *this; 351 } 352 353#endif // _LIBCPP_DEBUG_LEVEL == 2 354 355 _LIBCPP_INLINE_VISIBILITY 356 reference operator*() const 357 { 358#if _LIBCPP_DEBUG_LEVEL == 2 359 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 360 "Attempted to dereference a non-dereferenceable list::iterator"); 361#endif 362 return __ptr_->__as_node()->__value_; 363 } 364 _LIBCPP_INLINE_VISIBILITY 365 pointer operator->() const 366 { 367#if _LIBCPP_DEBUG_LEVEL == 2 368 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 369 "Attempted to dereference a non-dereferenceable list::iterator"); 370#endif 371 return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); 372 } 373 374 _LIBCPP_INLINE_VISIBILITY 375 __list_iterator& operator++() 376 { 377#if _LIBCPP_DEBUG_LEVEL == 2 378 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 379 "Attempted to increment a non-incrementable list::iterator"); 380#endif 381 __ptr_ = __ptr_->__next_; 382 return *this; 383 } 384 _LIBCPP_INLINE_VISIBILITY 385 __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;} 386 387 _LIBCPP_INLINE_VISIBILITY 388 __list_iterator& operator--() 389 { 390#if _LIBCPP_DEBUG_LEVEL == 2 391 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), 392 "Attempted to decrement a non-decrementable list::iterator"); 393#endif 394 __ptr_ = __ptr_->__prev_; 395 return *this; 396 } 397 _LIBCPP_INLINE_VISIBILITY 398 __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;} 399 400 friend _LIBCPP_INLINE_VISIBILITY 401 bool operator==(const __list_iterator& __x, const __list_iterator& __y) 402 { 403 return __x.__ptr_ == __y.__ptr_; 404 } 405 friend _LIBCPP_INLINE_VISIBILITY 406 bool operator!=(const __list_iterator& __x, const __list_iterator& __y) 407 {return !(__x == __y);} 408}; 409 410template <class _Tp, class _VoidPtr> 411class _LIBCPP_TEMPLATE_VIS __list_const_iterator 412{ 413 typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits; 414 typedef typename _NodeTraits::__link_pointer __link_pointer; 415 416 __link_pointer __ptr_; 417 418#if _LIBCPP_DEBUG_LEVEL == 2 419 _LIBCPP_INLINE_VISIBILITY 420 explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT 421 : __ptr_(__p) 422 { 423 __get_db()->__insert_ic(this, __c); 424 } 425#else 426 _LIBCPP_INLINE_VISIBILITY 427 explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {} 428#endif 429 430 template<class, class> friend class list; 431 template<class, class> friend class __list_imp; 432public: 433 typedef bidirectional_iterator_tag iterator_category; 434 typedef _Tp value_type; 435 typedef const value_type& reference; 436 typedef typename __rebind_pointer<_VoidPtr, const value_type>::type pointer; 437 typedef typename pointer_traits<pointer>::difference_type difference_type; 438 439 _LIBCPP_INLINE_VISIBILITY 440 __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) 441 { 442#if _LIBCPP_DEBUG_LEVEL == 2 443 __get_db()->__insert_i(this); 444#endif 445 } 446 _LIBCPP_INLINE_VISIBILITY 447 __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT 448 : __ptr_(__p.__ptr_) 449 { 450#if _LIBCPP_DEBUG_LEVEL == 2 451 __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); 452#endif 453 } 454 455#if _LIBCPP_DEBUG_LEVEL == 2 456 457 _LIBCPP_INLINE_VISIBILITY 458 __list_const_iterator(const __list_const_iterator& __p) 459 : __ptr_(__p.__ptr_) 460 { 461 __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); 462 } 463 464 _LIBCPP_INLINE_VISIBILITY 465 ~__list_const_iterator() 466 { 467 __get_db()->__erase_i(this); 468 } 469 470 _LIBCPP_INLINE_VISIBILITY 471 __list_const_iterator& operator=(const __list_const_iterator& __p) 472 { 473 if (this != _VSTD::addressof(__p)) 474 { 475 __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); 476 __ptr_ = __p.__ptr_; 477 } 478 return *this; 479 } 480 481#endif // _LIBCPP_DEBUG_LEVEL == 2 482 _LIBCPP_INLINE_VISIBILITY 483 reference operator*() const 484 { 485#if _LIBCPP_DEBUG_LEVEL == 2 486 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 487 "Attempted to dereference a non-dereferenceable list::const_iterator"); 488#endif 489 return __ptr_->__as_node()->__value_; 490 } 491 _LIBCPP_INLINE_VISIBILITY 492 pointer operator->() const 493 { 494#if _LIBCPP_DEBUG_LEVEL == 2 495 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 496 "Attempted to dereference a non-dereferenceable list::const_iterator"); 497#endif 498 return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); 499 } 500 501 _LIBCPP_INLINE_VISIBILITY 502 __list_const_iterator& operator++() 503 { 504#if _LIBCPP_DEBUG_LEVEL == 2 505 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), 506 "Attempted to increment a non-incrementable list::const_iterator"); 507#endif 508 __ptr_ = __ptr_->__next_; 509 return *this; 510 } 511 _LIBCPP_INLINE_VISIBILITY 512 __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;} 513 514 _LIBCPP_INLINE_VISIBILITY 515 __list_const_iterator& operator--() 516 { 517#if _LIBCPP_DEBUG_LEVEL == 2 518 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), 519 "Attempted to decrement a non-decrementable list::const_iterator"); 520#endif 521 __ptr_ = __ptr_->__prev_; 522 return *this; 523 } 524 _LIBCPP_INLINE_VISIBILITY 525 __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;} 526 527 friend _LIBCPP_INLINE_VISIBILITY 528 bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y) 529 { 530 return __x.__ptr_ == __y.__ptr_; 531 } 532 friend _LIBCPP_INLINE_VISIBILITY 533 bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y) 534 {return !(__x == __y);} 535}; 536 537template <class _Tp, class _Alloc> 538class __list_imp 539{ 540 __list_imp(const __list_imp&); 541 __list_imp& operator=(const __list_imp&); 542public: 543 typedef _Alloc allocator_type; 544 typedef allocator_traits<allocator_type> __alloc_traits; 545 typedef typename __alloc_traits::size_type size_type; 546protected: 547 typedef _Tp value_type; 548 typedef typename __alloc_traits::void_pointer __void_pointer; 549 typedef __list_iterator<value_type, __void_pointer> iterator; 550 typedef __list_const_iterator<value_type, __void_pointer> const_iterator; 551 typedef __list_node_base<value_type, __void_pointer> __node_base; 552 typedef __list_node<value_type, __void_pointer> __node; 553 typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; 554 typedef allocator_traits<__node_allocator> __node_alloc_traits; 555 typedef typename __node_alloc_traits::pointer __node_pointer; 556 typedef typename __node_alloc_traits::pointer __node_const_pointer; 557 typedef __list_node_pointer_traits<value_type, __void_pointer> __node_pointer_traits; 558 typedef typename __node_pointer_traits::__link_pointer __link_pointer; 559 typedef __link_pointer __link_const_pointer; 560 typedef typename __alloc_traits::pointer pointer; 561 typedef typename __alloc_traits::const_pointer const_pointer; 562 typedef typename __alloc_traits::difference_type difference_type; 563 564 typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator; 565 typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer; 566 static_assert((!is_same<allocator_type, __node_allocator>::value), 567 "internal allocator type must differ from user-specified " 568 "type; otherwise overload resolution breaks"); 569 570 __node_base __end_; 571 __compressed_pair<size_type, __node_allocator> __size_alloc_; 572 573 _LIBCPP_INLINE_VISIBILITY 574 __link_pointer __end_as_link() const _NOEXCEPT { 575 return __node_pointer_traits::__unsafe_link_pointer_cast( 576 const_cast<__node_base&>(__end_).__self()); 577 } 578 579 _LIBCPP_INLINE_VISIBILITY 580 size_type& __sz() _NOEXCEPT {return __size_alloc_.first();} 581 _LIBCPP_INLINE_VISIBILITY 582 const size_type& __sz() const _NOEXCEPT 583 {return __size_alloc_.first();} 584 _LIBCPP_INLINE_VISIBILITY 585 __node_allocator& __node_alloc() _NOEXCEPT 586 {return __size_alloc_.second();} 587 _LIBCPP_INLINE_VISIBILITY 588 const __node_allocator& __node_alloc() const _NOEXCEPT 589 {return __size_alloc_.second();} 590 591 _LIBCPP_INLINE_VISIBILITY 592 size_type __node_alloc_max_size() const _NOEXCEPT { 593 return __node_alloc_traits::max_size(__node_alloc()); 594 } 595 _LIBCPP_INLINE_VISIBILITY 596 static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT; 597 598 _LIBCPP_INLINE_VISIBILITY 599 __list_imp() 600 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); 601 _LIBCPP_INLINE_VISIBILITY 602 __list_imp(const allocator_type& __a); 603 _LIBCPP_INLINE_VISIBILITY 604 __list_imp(const __node_allocator& __a); 605#ifndef _LIBCPP_CXX03_LANG 606 __list_imp(__node_allocator&& __a) _NOEXCEPT; 607#endif 608 ~__list_imp(); 609 void clear() _NOEXCEPT; 610 _LIBCPP_INLINE_VISIBILITY 611 bool empty() const _NOEXCEPT {return __sz() == 0;} 612 613 _LIBCPP_INLINE_VISIBILITY 614 iterator begin() _NOEXCEPT 615 { 616#if _LIBCPP_DEBUG_LEVEL == 2 617 return iterator(__end_.__next_, this); 618#else 619 return iterator(__end_.__next_); 620#endif 621 } 622 _LIBCPP_INLINE_VISIBILITY 623 const_iterator begin() const _NOEXCEPT 624 { 625#if _LIBCPP_DEBUG_LEVEL == 2 626 return const_iterator(__end_.__next_, this); 627#else 628 return const_iterator(__end_.__next_); 629#endif 630 } 631 _LIBCPP_INLINE_VISIBILITY 632 iterator end() _NOEXCEPT 633 { 634#if _LIBCPP_DEBUG_LEVEL == 2 635 return iterator(__end_as_link(), this); 636#else 637 return iterator(__end_as_link()); 638#endif 639 } 640 _LIBCPP_INLINE_VISIBILITY 641 const_iterator end() const _NOEXCEPT 642 { 643#if _LIBCPP_DEBUG_LEVEL == 2 644 return const_iterator(__end_as_link(), this); 645#else 646 return const_iterator(__end_as_link()); 647#endif 648 } 649 650 void swap(__list_imp& __c) 651#if _LIBCPP_STD_VER >= 14 652 _NOEXCEPT; 653#else 654 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 655 __is_nothrow_swappable<allocator_type>::value); 656#endif 657 658 _LIBCPP_INLINE_VISIBILITY 659 void __copy_assign_alloc(const __list_imp& __c) 660 {__copy_assign_alloc(__c, integral_constant<bool, 661 __node_alloc_traits::propagate_on_container_copy_assignment::value>());} 662 663 _LIBCPP_INLINE_VISIBILITY 664 void __move_assign_alloc(__list_imp& __c) 665 _NOEXCEPT_( 666 !__node_alloc_traits::propagate_on_container_move_assignment::value || 667 is_nothrow_move_assignable<__node_allocator>::value) 668 {__move_assign_alloc(__c, integral_constant<bool, 669 __node_alloc_traits::propagate_on_container_move_assignment::value>());} 670 671private: 672 _LIBCPP_INLINE_VISIBILITY 673 void __copy_assign_alloc(const __list_imp& __c, true_type) 674 { 675 if (__node_alloc() != __c.__node_alloc()) 676 clear(); 677 __node_alloc() = __c.__node_alloc(); 678 } 679 680 _LIBCPP_INLINE_VISIBILITY 681 void __copy_assign_alloc(const __list_imp&, false_type) 682 {} 683 684 _LIBCPP_INLINE_VISIBILITY 685 void __move_assign_alloc(__list_imp& __c, true_type) 686 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) 687 { 688 __node_alloc() = _VSTD::move(__c.__node_alloc()); 689 } 690 691 _LIBCPP_INLINE_VISIBILITY 692 void __move_assign_alloc(__list_imp&, false_type) 693 _NOEXCEPT 694 {} 695 696 _LIBCPP_INLINE_VISIBILITY 697 void __invalidate_all_iterators() { 698#if _LIBCPP_DEBUG_LEVEL == 2 699 __get_db()->__invalidate_all(this); 700#endif 701 } 702}; 703 704// Unlink nodes [__f, __l] 705template <class _Tp, class _Alloc> 706inline 707void 708__list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) 709 _NOEXCEPT 710{ 711 __f->__prev_->__next_ = __l->__next_; 712 __l->__next_->__prev_ = __f->__prev_; 713} 714 715template <class _Tp, class _Alloc> 716inline 717__list_imp<_Tp, _Alloc>::__list_imp() 718 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) 719 : __size_alloc_(0, __default_init_tag()) 720{ 721} 722 723template <class _Tp, class _Alloc> 724inline 725__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) 726 : __size_alloc_(0, __node_allocator(__a)) 727{ 728} 729 730template <class _Tp, class _Alloc> 731inline __list_imp<_Tp, _Alloc>::__list_imp(const __node_allocator& __a) 732 : __size_alloc_(0, __a) {} 733 734#ifndef _LIBCPP_CXX03_LANG 735template <class _Tp, class _Alloc> 736inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT 737 : __size_alloc_(0, _VSTD::move(__a)) {} 738#endif 739 740template <class _Tp, class _Alloc> 741__list_imp<_Tp, _Alloc>::~__list_imp() { 742 clear(); 743#if _LIBCPP_DEBUG_LEVEL == 2 744 __get_db()->__erase_c(this); 745#endif 746} 747 748template <class _Tp, class _Alloc> 749void 750__list_imp<_Tp, _Alloc>::clear() _NOEXCEPT 751{ 752 if (!empty()) 753 { 754 __node_allocator& __na = __node_alloc(); 755 __link_pointer __f = __end_.__next_; 756 __link_pointer __l = __end_as_link(); 757 __unlink_nodes(__f, __l->__prev_); 758 __sz() = 0; 759 while (__f != __l) 760 { 761 __node_pointer __np = __f->__as_node(); 762 __f = __f->__next_; 763 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); 764 __node_alloc_traits::deallocate(__na, __np, 1); 765 } 766 __invalidate_all_iterators(); 767 } 768} 769 770template <class _Tp, class _Alloc> 771void 772__list_imp<_Tp, _Alloc>::swap(__list_imp& __c) 773#if _LIBCPP_STD_VER >= 14 774 _NOEXCEPT 775#else 776 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || 777 __is_nothrow_swappable<allocator_type>::value) 778#endif 779{ 780 _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || 781 this->__node_alloc() == __c.__node_alloc(), 782 "list::swap: Either propagate_on_container_swap must be true" 783 " or the allocators must compare equal"); 784 using _VSTD::swap; 785 _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc()); 786 swap(__sz(), __c.__sz()); 787 swap(__end_, __c.__end_); 788 if (__sz() == 0) 789 __end_.__next_ = __end_.__prev_ = __end_as_link(); 790 else 791 __end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_as_link(); 792 if (__c.__sz() == 0) 793 __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link(); 794 else 795 __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link(); 796 797#if _LIBCPP_DEBUG_LEVEL == 2 798 __libcpp_db* __db = __get_db(); 799 __c_node* __cn1 = __db->__find_c_and_lock(this); 800 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); 801 _VSTD::swap(__cn1->beg_, __cn2->beg_); 802 _VSTD::swap(__cn1->end_, __cn2->end_); 803 _VSTD::swap(__cn1->cap_, __cn2->cap_); 804 for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;) 805 { 806 --__p; 807 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 808 if (__i->__ptr_ == __c.__end_as_link()) 809 { 810 __cn2->__add(*__p); 811 if (--__cn1->end_ != __p) 812 _VSTD::memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*)); 813 } 814 else 815 (*__p)->__c_ = __cn1; 816 } 817 for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) 818 { 819 --__p; 820 const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); 821 if (__i->__ptr_ == __end_as_link()) 822 { 823 __cn1->__add(*__p); 824 if (--__cn2->end_ != __p) 825 _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); 826 } 827 else 828 (*__p)->__c_ = __cn2; 829 } 830 __db->unlock(); 831#endif 832} 833 834template <class _Tp, class _Alloc /*= allocator<_Tp>*/> 835class _LIBCPP_TEMPLATE_VIS list 836 : private __list_imp<_Tp, _Alloc> 837{ 838 typedef __list_imp<_Tp, _Alloc> base; 839 typedef typename base::__node __node; 840 typedef typename base::__node_allocator __node_allocator; 841 typedef typename base::__node_pointer __node_pointer; 842 typedef typename base::__node_alloc_traits __node_alloc_traits; 843 typedef typename base::__node_base __node_base; 844 typedef typename base::__node_base_pointer __node_base_pointer; 845 typedef typename base::__link_pointer __link_pointer; 846 847public: 848 typedef _Tp value_type; 849 typedef _Alloc allocator_type; 850 static_assert((is_same<value_type, typename allocator_type::value_type>::value), 851 "Invalid allocator::value_type"); 852 typedef value_type& reference; 853 typedef const value_type& const_reference; 854 typedef typename base::pointer pointer; 855 typedef typename base::const_pointer const_pointer; 856 typedef typename base::size_type size_type; 857 typedef typename base::difference_type difference_type; 858 typedef typename base::iterator iterator; 859 typedef typename base::const_iterator const_iterator; 860 typedef _VSTD::reverse_iterator<iterator> reverse_iterator; 861 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; 862#if _LIBCPP_STD_VER > 17 863 typedef size_type __remove_return_type; 864#else 865 typedef void __remove_return_type; 866#endif 867 868 _LIBCPP_INLINE_VISIBILITY 869 list() 870 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) 871 { 872#if _LIBCPP_DEBUG_LEVEL == 2 873 __get_db()->__insert_c(this); 874#endif 875 } 876 _LIBCPP_INLINE_VISIBILITY 877 explicit list(const allocator_type& __a) : base(__a) 878 { 879#if _LIBCPP_DEBUG_LEVEL == 2 880 __get_db()->__insert_c(this); 881#endif 882 } 883 explicit list(size_type __n); 884#if _LIBCPP_STD_VER > 11 885 explicit list(size_type __n, const allocator_type& __a); 886#endif 887 list(size_type __n, const value_type& __x); 888 template <class = __enable_if_t<__is_allocator<_Alloc>::value> > 889 list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) 890 { 891#if _LIBCPP_DEBUG_LEVEL == 2 892 __get_db()->__insert_c(this); 893#endif 894 for (; __n > 0; --__n) 895 push_back(__x); 896 } 897 898 template <class _InpIter> 899 list(_InpIter __f, _InpIter __l, 900 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); 901 template <class _InpIter> 902 list(_InpIter __f, _InpIter __l, const allocator_type& __a, 903 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); 904 905 list(const list& __c); 906 list(const list& __c, const __identity_t<allocator_type>& __a); 907 _LIBCPP_INLINE_VISIBILITY 908 list& operator=(const list& __c); 909#ifndef _LIBCPP_CXX03_LANG 910 list(initializer_list<value_type> __il); 911 list(initializer_list<value_type> __il, const allocator_type& __a); 912 913 _LIBCPP_INLINE_VISIBILITY 914 list(list&& __c) 915 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); 916 _LIBCPP_INLINE_VISIBILITY 917 list(list&& __c, const __identity_t<allocator_type>& __a); 918 _LIBCPP_INLINE_VISIBILITY 919 list& operator=(list&& __c) 920 _NOEXCEPT_( 921 __node_alloc_traits::propagate_on_container_move_assignment::value && 922 is_nothrow_move_assignable<__node_allocator>::value); 923 924 _LIBCPP_INLINE_VISIBILITY 925 list& operator=(initializer_list<value_type> __il) 926 {assign(__il.begin(), __il.end()); return *this;} 927 928 _LIBCPP_INLINE_VISIBILITY 929 void assign(initializer_list<value_type> __il) 930 {assign(__il.begin(), __il.end());} 931#endif // _LIBCPP_CXX03_LANG 932 933 template <class _InpIter> 934 void assign(_InpIter __f, _InpIter __l, 935 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); 936 void assign(size_type __n, const value_type& __x); 937 938 _LIBCPP_INLINE_VISIBILITY 939 allocator_type get_allocator() const _NOEXCEPT; 940 941 _LIBCPP_INLINE_VISIBILITY 942 size_type size() const _NOEXCEPT {return base::__sz();} 943 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 944 bool empty() const _NOEXCEPT {return base::empty();} 945 _LIBCPP_INLINE_VISIBILITY 946 size_type max_size() const _NOEXCEPT 947 { 948 return _VSTD::min<size_type>( 949 base::__node_alloc_max_size(), 950 numeric_limits<difference_type >::max()); 951 } 952 953 _LIBCPP_INLINE_VISIBILITY 954 iterator begin() _NOEXCEPT {return base::begin();} 955 _LIBCPP_INLINE_VISIBILITY 956 const_iterator begin() const _NOEXCEPT {return base::begin();} 957 _LIBCPP_INLINE_VISIBILITY 958 iterator end() _NOEXCEPT {return base::end();} 959 _LIBCPP_INLINE_VISIBILITY 960 const_iterator end() const _NOEXCEPT {return base::end();} 961 _LIBCPP_INLINE_VISIBILITY 962 const_iterator cbegin() const _NOEXCEPT {return base::begin();} 963 _LIBCPP_INLINE_VISIBILITY 964 const_iterator cend() const _NOEXCEPT {return base::end();} 965 966 _LIBCPP_INLINE_VISIBILITY 967 reverse_iterator rbegin() _NOEXCEPT 968 {return reverse_iterator(end());} 969 _LIBCPP_INLINE_VISIBILITY 970 const_reverse_iterator rbegin() const _NOEXCEPT 971 {return const_reverse_iterator(end());} 972 _LIBCPP_INLINE_VISIBILITY 973 reverse_iterator rend() _NOEXCEPT 974 {return reverse_iterator(begin());} 975 _LIBCPP_INLINE_VISIBILITY 976 const_reverse_iterator rend() const _NOEXCEPT 977 {return const_reverse_iterator(begin());} 978 _LIBCPP_INLINE_VISIBILITY 979 const_reverse_iterator crbegin() const _NOEXCEPT 980 {return const_reverse_iterator(end());} 981 _LIBCPP_INLINE_VISIBILITY 982 const_reverse_iterator crend() const _NOEXCEPT 983 {return const_reverse_iterator(begin());} 984 985 _LIBCPP_INLINE_VISIBILITY 986 reference front() 987 { 988 _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); 989 return base::__end_.__next_->__as_node()->__value_; 990 } 991 _LIBCPP_INLINE_VISIBILITY 992 const_reference front() const 993 { 994 _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); 995 return base::__end_.__next_->__as_node()->__value_; 996 } 997 _LIBCPP_INLINE_VISIBILITY 998 reference back() 999 { 1000 _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); 1001 return base::__end_.__prev_->__as_node()->__value_; 1002 } 1003 _LIBCPP_INLINE_VISIBILITY 1004 const_reference back() const 1005 { 1006 _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); 1007 return base::__end_.__prev_->__as_node()->__value_; 1008 } 1009 1010#ifndef _LIBCPP_CXX03_LANG 1011 void push_front(value_type&& __x); 1012 void push_back(value_type&& __x); 1013 1014 template <class... _Args> 1015#if _LIBCPP_STD_VER > 14 1016 reference emplace_front(_Args&&... __args); 1017#else 1018 void emplace_front(_Args&&... __args); 1019#endif 1020 template <class... _Args> 1021#if _LIBCPP_STD_VER > 14 1022 reference emplace_back(_Args&&... __args); 1023#else 1024 void emplace_back(_Args&&... __args); 1025#endif 1026 template <class... _Args> 1027 iterator emplace(const_iterator __p, _Args&&... __args); 1028 1029 iterator insert(const_iterator __p, value_type&& __x); 1030 1031 _LIBCPP_INLINE_VISIBILITY 1032 iterator insert(const_iterator __p, initializer_list<value_type> __il) 1033 {return insert(__p, __il.begin(), __il.end());} 1034#endif // _LIBCPP_CXX03_LANG 1035 1036 void push_front(const value_type& __x); 1037 void push_back(const value_type& __x); 1038 1039#ifndef _LIBCPP_CXX03_LANG 1040 template <class _Arg> 1041 _LIBCPP_INLINE_VISIBILITY 1042 void __emplace_back(_Arg&& __arg) { emplace_back(_VSTD::forward<_Arg>(__arg)); } 1043#else 1044 _LIBCPP_INLINE_VISIBILITY 1045 void __emplace_back(value_type const& __arg) { push_back(__arg); } 1046#endif 1047 1048 iterator insert(const_iterator __p, const value_type& __x); 1049 iterator insert(const_iterator __p, size_type __n, const value_type& __x); 1050 template <class _InpIter> 1051 iterator insert(const_iterator __p, _InpIter __f, _InpIter __l, 1052 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); 1053 1054 _LIBCPP_INLINE_VISIBILITY 1055 void swap(list& __c) 1056#if _LIBCPP_STD_VER >= 14 1057 _NOEXCEPT 1058#else 1059 _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || 1060 __is_nothrow_swappable<__node_allocator>::value) 1061#endif 1062 {base::swap(__c);} 1063 _LIBCPP_INLINE_VISIBILITY 1064 void clear() _NOEXCEPT {base::clear();} 1065 1066 void pop_front(); 1067 void pop_back(); 1068 1069 iterator erase(const_iterator __p); 1070 iterator erase(const_iterator __f, const_iterator __l); 1071 1072 void resize(size_type __n); 1073 void resize(size_type __n, const value_type& __x); 1074 1075 void splice(const_iterator __p, list& __c); 1076#ifndef _LIBCPP_CXX03_LANG 1077 _LIBCPP_INLINE_VISIBILITY 1078 void splice(const_iterator __p, list&& __c) {splice(__p, __c);} 1079 _LIBCPP_INLINE_VISIBILITY 1080 void splice(const_iterator __p, list&& __c, const_iterator __i) 1081 {splice(__p, __c, __i);} 1082 _LIBCPP_INLINE_VISIBILITY 1083 void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l) 1084 {splice(__p, __c, __f, __l);} 1085#endif 1086 void splice(const_iterator __p, list& __c, const_iterator __i); 1087 void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); 1088 1089 __remove_return_type remove(const value_type& __x); 1090 template <class _Pred> __remove_return_type remove_if(_Pred __pred); 1091 _LIBCPP_INLINE_VISIBILITY 1092 __remove_return_type unique() { return unique(__equal_to<value_type>()); } 1093 template <class _BinaryPred> 1094 __remove_return_type unique(_BinaryPred __binary_pred); 1095 _LIBCPP_INLINE_VISIBILITY 1096 void merge(list& __c); 1097#ifndef _LIBCPP_CXX03_LANG 1098 _LIBCPP_INLINE_VISIBILITY 1099 void merge(list&& __c) {merge(__c);} 1100 1101 template <class _Comp> 1102 _LIBCPP_INLINE_VISIBILITY 1103 void merge(list&& __c, _Comp __comp) {merge(__c, __comp);} 1104#endif 1105 template <class _Comp> 1106 void merge(list& __c, _Comp __comp); 1107 1108 _LIBCPP_INLINE_VISIBILITY 1109 void sort(); 1110 template <class _Comp> 1111 _LIBCPP_INLINE_VISIBILITY 1112 void sort(_Comp __comp); 1113 1114 void reverse() _NOEXCEPT; 1115 1116 bool __invariants() const; 1117 1118 typedef __allocator_destructor<__node_allocator> __node_destructor; 1119 typedef unique_ptr<__node, __node_destructor> __hold_pointer; 1120 1121 _LIBCPP_INLINE_VISIBILITY 1122 __hold_pointer __allocate_node(__node_allocator& __na) { 1123 __node_pointer __p = __node_alloc_traits::allocate(__na, 1); 1124 __p->__prev_ = nullptr; 1125 return __hold_pointer(__p, __node_destructor(__na, 1)); 1126 } 1127 1128#if _LIBCPP_DEBUG_LEVEL == 2 1129 1130 bool __dereferenceable(const const_iterator* __i) const; 1131 bool __decrementable(const const_iterator* __i) const; 1132 bool __addable(const const_iterator* __i, ptrdiff_t __n) const; 1133 bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; 1134 1135#endif // _LIBCPP_DEBUG_LEVEL == 2 1136 1137private: 1138 _LIBCPP_INLINE_VISIBILITY 1139 static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l); 1140 _LIBCPP_INLINE_VISIBILITY 1141 void __link_nodes_at_front(__link_pointer __f, __link_pointer __l); 1142 _LIBCPP_INLINE_VISIBILITY 1143 void __link_nodes_at_back (__link_pointer __f, __link_pointer __l); 1144 iterator __iterator(size_type __n); 1145 template <class _Comp> 1146 static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); 1147 1148 void __move_assign(list& __c, true_type) 1149 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value); 1150 void __move_assign(list& __c, false_type); 1151}; 1152 1153#if _LIBCPP_STD_VER >= 17 1154template<class _InputIterator, 1155 class _Alloc = allocator<__iter_value_type<_InputIterator>>, 1156 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, 1157 class = enable_if_t<__is_allocator<_Alloc>::value> 1158 > 1159list(_InputIterator, _InputIterator) 1160 -> list<__iter_value_type<_InputIterator>, _Alloc>; 1161 1162template<class _InputIterator, 1163 class _Alloc, 1164 class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, 1165 class = enable_if_t<__is_allocator<_Alloc>::value> 1166 > 1167list(_InputIterator, _InputIterator, _Alloc) 1168 -> list<__iter_value_type<_InputIterator>, _Alloc>; 1169#endif 1170 1171// Link in nodes [__f, __l] just prior to __p 1172template <class _Tp, class _Alloc> 1173inline 1174void 1175list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l) 1176{ 1177 __p->__prev_->__next_ = __f; 1178 __f->__prev_ = __p->__prev_; 1179 __p->__prev_ = __l; 1180 __l->__next_ = __p; 1181} 1182 1183// Link in nodes [__f, __l] at the front of the list 1184template <class _Tp, class _Alloc> 1185inline 1186void 1187list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) 1188{ 1189 __f->__prev_ = base::__end_as_link(); 1190 __l->__next_ = base::__end_.__next_; 1191 __l->__next_->__prev_ = __l; 1192 base::__end_.__next_ = __f; 1193} 1194 1195// Link in nodes [__f, __l] at the back of the list 1196template <class _Tp, class _Alloc> 1197inline 1198void 1199list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) 1200{ 1201 __l->__next_ = base::__end_as_link(); 1202 __f->__prev_ = base::__end_.__prev_; 1203 __f->__prev_->__next_ = __f; 1204 base::__end_.__prev_ = __l; 1205} 1206 1207 1208template <class _Tp, class _Alloc> 1209inline 1210typename list<_Tp, _Alloc>::iterator 1211list<_Tp, _Alloc>::__iterator(size_type __n) 1212{ 1213 return __n <= base::__sz() / 2 ? _VSTD::next(begin(), __n) 1214 : _VSTD::prev(end(), base::__sz() - __n); 1215} 1216 1217template <class _Tp, class _Alloc> 1218list<_Tp, _Alloc>::list(size_type __n) 1219{ 1220#if _LIBCPP_DEBUG_LEVEL == 2 1221 __get_db()->__insert_c(this); 1222#endif 1223 for (; __n > 0; --__n) 1224#ifndef _LIBCPP_CXX03_LANG 1225 emplace_back(); 1226#else 1227 push_back(value_type()); 1228#endif 1229} 1230 1231#if _LIBCPP_STD_VER > 11 1232template <class _Tp, class _Alloc> 1233list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) 1234{ 1235#if _LIBCPP_DEBUG_LEVEL == 2 1236 __get_db()->__insert_c(this); 1237#endif 1238 for (; __n > 0; --__n) 1239 emplace_back(); 1240} 1241#endif 1242 1243template <class _Tp, class _Alloc> 1244list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) 1245{ 1246#if _LIBCPP_DEBUG_LEVEL == 2 1247 __get_db()->__insert_c(this); 1248#endif 1249 for (; __n > 0; --__n) 1250 push_back(__x); 1251} 1252 1253template <class _Tp, class _Alloc> 1254template <class _InpIter> 1255list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, 1256 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) 1257{ 1258#if _LIBCPP_DEBUG_LEVEL == 2 1259 __get_db()->__insert_c(this); 1260#endif 1261 for (; __f != __l; ++__f) 1262 __emplace_back(*__f); 1263} 1264 1265template <class _Tp, class _Alloc> 1266template <class _InpIter> 1267list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, 1268 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) 1269 : base(__a) 1270{ 1271#if _LIBCPP_DEBUG_LEVEL == 2 1272 __get_db()->__insert_c(this); 1273#endif 1274 for (; __f != __l; ++__f) 1275 __emplace_back(*__f); 1276} 1277 1278template <class _Tp, class _Alloc> 1279list<_Tp, _Alloc>::list(const list& __c) 1280 : base(__node_alloc_traits::select_on_container_copy_construction( 1281 __c.__node_alloc())) { 1282#if _LIBCPP_DEBUG_LEVEL == 2 1283 __get_db()->__insert_c(this); 1284#endif 1285 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) 1286 push_back(*__i); 1287} 1288 1289template <class _Tp, class _Alloc> 1290list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a) 1291 : base(__a) 1292{ 1293#if _LIBCPP_DEBUG_LEVEL == 2 1294 __get_db()->__insert_c(this); 1295#endif 1296 for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) 1297 push_back(*__i); 1298} 1299 1300#ifndef _LIBCPP_CXX03_LANG 1301 1302template <class _Tp, class _Alloc> 1303list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a) 1304 : base(__a) 1305{ 1306#if _LIBCPP_DEBUG_LEVEL == 2 1307 __get_db()->__insert_c(this); 1308#endif 1309 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), 1310 __e = __il.end(); __i != __e; ++__i) 1311 push_back(*__i); 1312} 1313 1314template <class _Tp, class _Alloc> 1315list<_Tp, _Alloc>::list(initializer_list<value_type> __il) 1316{ 1317#if _LIBCPP_DEBUG_LEVEL == 2 1318 __get_db()->__insert_c(this); 1319#endif 1320 for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), 1321 __e = __il.end(); __i != __e; ++__i) 1322 push_back(*__i); 1323} 1324 1325template <class _Tp, class _Alloc> 1326inline list<_Tp, _Alloc>::list(list&& __c) 1327 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) 1328 : base(_VSTD::move(__c.__node_alloc())) { 1329#if _LIBCPP_DEBUG_LEVEL == 2 1330 __get_db()->__insert_c(this); 1331#endif 1332 splice(end(), __c); 1333} 1334 1335template <class _Tp, class _Alloc> 1336inline 1337list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a) 1338 : base(__a) 1339{ 1340#if _LIBCPP_DEBUG_LEVEL == 2 1341 __get_db()->__insert_c(this); 1342#endif 1343 if (__a == __c.get_allocator()) 1344 splice(end(), __c); 1345 else 1346 { 1347 typedef move_iterator<iterator> _Ip; 1348 assign(_Ip(__c.begin()), _Ip(__c.end())); 1349 } 1350} 1351 1352template <class _Tp, class _Alloc> 1353inline 1354list<_Tp, _Alloc>& 1355list<_Tp, _Alloc>::operator=(list&& __c) 1356 _NOEXCEPT_( 1357 __node_alloc_traits::propagate_on_container_move_assignment::value && 1358 is_nothrow_move_assignable<__node_allocator>::value) 1359{ 1360 __move_assign(__c, integral_constant<bool, 1361 __node_alloc_traits::propagate_on_container_move_assignment::value>()); 1362 return *this; 1363} 1364 1365template <class _Tp, class _Alloc> 1366void 1367list<_Tp, _Alloc>::__move_assign(list& __c, false_type) 1368{ 1369 if (base::__node_alloc() != __c.__node_alloc()) 1370 { 1371 typedef move_iterator<iterator> _Ip; 1372 assign(_Ip(__c.begin()), _Ip(__c.end())); 1373 } 1374 else 1375 __move_assign(__c, true_type()); 1376} 1377 1378template <class _Tp, class _Alloc> 1379void 1380list<_Tp, _Alloc>::__move_assign(list& __c, true_type) 1381 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) 1382{ 1383 clear(); 1384 base::__move_assign_alloc(__c); 1385 splice(end(), __c); 1386} 1387 1388#endif // _LIBCPP_CXX03_LANG 1389 1390template <class _Tp, class _Alloc> 1391inline 1392list<_Tp, _Alloc>& 1393list<_Tp, _Alloc>::operator=(const list& __c) 1394{ 1395 if (this != _VSTD::addressof(__c)) 1396 { 1397 base::__copy_assign_alloc(__c); 1398 assign(__c.begin(), __c.end()); 1399 } 1400 return *this; 1401} 1402 1403template <class _Tp, class _Alloc> 1404template <class _InpIter> 1405void 1406list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l, 1407 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) 1408{ 1409 iterator __i = begin(); 1410 iterator __e = end(); 1411 for (; __f != __l && __i != __e; ++__f, (void) ++__i) 1412 *__i = *__f; 1413 if (__i == __e) 1414 insert(__e, __f, __l); 1415 else 1416 erase(__i, __e); 1417#if _LIBCPP_DEBUG_LEVEL == 2 1418 __get_db()->__invalidate_all(this); 1419#endif 1420} 1421 1422template <class _Tp, class _Alloc> 1423void 1424list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) 1425{ 1426 iterator __i = begin(); 1427 iterator __e = end(); 1428 for (; __n > 0 && __i != __e; --__n, (void) ++__i) 1429 *__i = __x; 1430 if (__i == __e) 1431 insert(__e, __n, __x); 1432 else 1433 erase(__i, __e); 1434#if _LIBCPP_DEBUG_LEVEL == 2 1435 __get_db()->__invalidate_all(this); 1436#endif 1437} 1438 1439template <class _Tp, class _Alloc> 1440inline 1441_Alloc 1442list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT 1443{ 1444 return allocator_type(base::__node_alloc()); 1445} 1446 1447template <class _Tp, class _Alloc> 1448typename list<_Tp, _Alloc>::iterator 1449list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) 1450{ 1451#if _LIBCPP_DEBUG_LEVEL == 2 1452 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 1453 "list::insert(iterator, x) called with an iterator not" 1454 " referring to this list"); 1455#endif 1456 __node_allocator& __na = base::__node_alloc(); 1457 __hold_pointer __hold = __allocate_node(__na); 1458 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1459 __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link()); 1460 ++base::__sz(); 1461#if _LIBCPP_DEBUG_LEVEL == 2 1462 return iterator(__hold.release()->__as_link(), this); 1463#else 1464 return iterator(__hold.release()->__as_link()); 1465#endif 1466} 1467 1468template <class _Tp, class _Alloc> 1469typename list<_Tp, _Alloc>::iterator 1470list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) 1471{ 1472#if _LIBCPP_DEBUG_LEVEL == 2 1473 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 1474 "list::insert(iterator, n, x) called with an iterator not" 1475 " referring to this list"); 1476 iterator __r(__p.__ptr_, this); 1477#else 1478 iterator __r(__p.__ptr_); 1479#endif 1480 if (__n > 0) 1481 { 1482 size_type __ds = 0; 1483 __node_allocator& __na = base::__node_alloc(); 1484 __hold_pointer __hold = __allocate_node(__na); 1485 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1486 ++__ds; 1487#if _LIBCPP_DEBUG_LEVEL == 2 1488 __r = iterator(__hold->__as_link(), this); 1489#else 1490 __r = iterator(__hold->__as_link()); 1491#endif 1492 __hold.release(); 1493 iterator __e = __r; 1494#ifndef _LIBCPP_NO_EXCEPTIONS 1495 try 1496 { 1497#endif // _LIBCPP_NO_EXCEPTIONS 1498 for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) 1499 { 1500 __hold.reset(__node_alloc_traits::allocate(__na, 1)); 1501 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1502 __e.__ptr_->__next_ = __hold->__as_link(); 1503 __hold->__prev_ = __e.__ptr_; 1504 __hold.release(); 1505 } 1506#ifndef _LIBCPP_NO_EXCEPTIONS 1507 } 1508 catch (...) 1509 { 1510 while (true) 1511 { 1512 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); 1513 __link_pointer __prev = __e.__ptr_->__prev_; 1514 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); 1515 if (__prev == 0) 1516 break; 1517#if _LIBCPP_DEBUG_LEVEL == 2 1518 __e = iterator(__prev, this); 1519#else 1520 __e = iterator(__prev); 1521#endif 1522 } 1523 throw; 1524 } 1525#endif // _LIBCPP_NO_EXCEPTIONS 1526 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); 1527 base::__sz() += __ds; 1528 } 1529 return __r; 1530} 1531 1532template <class _Tp, class _Alloc> 1533template <class _InpIter> 1534typename list<_Tp, _Alloc>::iterator 1535list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, 1536 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) 1537{ 1538#if _LIBCPP_DEBUG_LEVEL == 2 1539 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 1540 "list::insert(iterator, range) called with an iterator not" 1541 " referring to this list"); 1542 iterator __r(__p.__ptr_, this); 1543#else 1544 iterator __r(__p.__ptr_); 1545#endif 1546 if (__f != __l) 1547 { 1548 size_type __ds = 0; 1549 __node_allocator& __na = base::__node_alloc(); 1550 __hold_pointer __hold = __allocate_node(__na); 1551 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); 1552 ++__ds; 1553#if _LIBCPP_DEBUG_LEVEL == 2 1554 __r = iterator(__hold.get()->__as_link(), this); 1555#else 1556 __r = iterator(__hold.get()->__as_link()); 1557#endif 1558 __hold.release(); 1559 iterator __e = __r; 1560#ifndef _LIBCPP_NO_EXCEPTIONS 1561 try 1562 { 1563#endif // _LIBCPP_NO_EXCEPTIONS 1564 for (++__f; __f != __l; ++__f, (void) ++__e, ++__ds) 1565 { 1566 __hold.reset(__node_alloc_traits::allocate(__na, 1)); 1567 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); 1568 __e.__ptr_->__next_ = __hold.get()->__as_link(); 1569 __hold->__prev_ = __e.__ptr_; 1570 __hold.release(); 1571 } 1572#ifndef _LIBCPP_NO_EXCEPTIONS 1573 } 1574 catch (...) 1575 { 1576 while (true) 1577 { 1578 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); 1579 __link_pointer __prev = __e.__ptr_->__prev_; 1580 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); 1581 if (__prev == 0) 1582 break; 1583#if _LIBCPP_DEBUG_LEVEL == 2 1584 __e = iterator(__prev, this); 1585#else 1586 __e = iterator(__prev); 1587#endif 1588 } 1589 throw; 1590 } 1591#endif // _LIBCPP_NO_EXCEPTIONS 1592 __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); 1593 base::__sz() += __ds; 1594 } 1595 return __r; 1596} 1597 1598template <class _Tp, class _Alloc> 1599void 1600list<_Tp, _Alloc>::push_front(const value_type& __x) 1601{ 1602 __node_allocator& __na = base::__node_alloc(); 1603 __hold_pointer __hold = __allocate_node(__na); 1604 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1605 __link_pointer __nl = __hold->__as_link(); 1606 __link_nodes_at_front(__nl, __nl); 1607 ++base::__sz(); 1608 __hold.release(); 1609} 1610 1611template <class _Tp, class _Alloc> 1612void 1613list<_Tp, _Alloc>::push_back(const value_type& __x) 1614{ 1615 __node_allocator& __na = base::__node_alloc(); 1616 __hold_pointer __hold = __allocate_node(__na); 1617 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1618 __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); 1619 ++base::__sz(); 1620 __hold.release(); 1621} 1622 1623#ifndef _LIBCPP_CXX03_LANG 1624 1625template <class _Tp, class _Alloc> 1626void 1627list<_Tp, _Alloc>::push_front(value_type&& __x) 1628{ 1629 __node_allocator& __na = base::__node_alloc(); 1630 __hold_pointer __hold = __allocate_node(__na); 1631 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); 1632 __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); 1633 ++base::__sz(); 1634 __hold.release(); 1635} 1636 1637template <class _Tp, class _Alloc> 1638void 1639list<_Tp, _Alloc>::push_back(value_type&& __x) 1640{ 1641 __node_allocator& __na = base::__node_alloc(); 1642 __hold_pointer __hold = __allocate_node(__na); 1643 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); 1644 __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); 1645 ++base::__sz(); 1646 __hold.release(); 1647} 1648 1649template <class _Tp, class _Alloc> 1650template <class... _Args> 1651#if _LIBCPP_STD_VER > 14 1652typename list<_Tp, _Alloc>::reference 1653#else 1654void 1655#endif 1656list<_Tp, _Alloc>::emplace_front(_Args&&... __args) 1657{ 1658 __node_allocator& __na = base::__node_alloc(); 1659 __hold_pointer __hold = __allocate_node(__na); 1660 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); 1661 __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); 1662 ++base::__sz(); 1663#if _LIBCPP_STD_VER > 14 1664 return __hold.release()->__value_; 1665#else 1666 __hold.release(); 1667#endif 1668} 1669 1670template <class _Tp, class _Alloc> 1671template <class... _Args> 1672#if _LIBCPP_STD_VER > 14 1673typename list<_Tp, _Alloc>::reference 1674#else 1675void 1676#endif 1677list<_Tp, _Alloc>::emplace_back(_Args&&... __args) 1678{ 1679 __node_allocator& __na = base::__node_alloc(); 1680 __hold_pointer __hold = __allocate_node(__na); 1681 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); 1682 __link_pointer __nl = __hold->__as_link(); 1683 __link_nodes_at_back(__nl, __nl); 1684 ++base::__sz(); 1685#if _LIBCPP_STD_VER > 14 1686 return __hold.release()->__value_; 1687#else 1688 __hold.release(); 1689#endif 1690} 1691 1692template <class _Tp, class _Alloc> 1693template <class... _Args> 1694typename list<_Tp, _Alloc>::iterator 1695list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) 1696{ 1697#if _LIBCPP_DEBUG_LEVEL == 2 1698 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 1699 "list::emplace(iterator, args...) called with an iterator not" 1700 " referring to this list"); 1701#endif 1702 __node_allocator& __na = base::__node_alloc(); 1703 __hold_pointer __hold = __allocate_node(__na); 1704 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); 1705 __link_pointer __nl = __hold.get()->__as_link(); 1706 __link_nodes(__p.__ptr_, __nl, __nl); 1707 ++base::__sz(); 1708 __hold.release(); 1709#if _LIBCPP_DEBUG_LEVEL == 2 1710 return iterator(__nl, this); 1711#else 1712 return iterator(__nl); 1713#endif 1714} 1715 1716template <class _Tp, class _Alloc> 1717typename list<_Tp, _Alloc>::iterator 1718list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) 1719{ 1720#if _LIBCPP_DEBUG_LEVEL == 2 1721 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 1722 "list::insert(iterator, x) called with an iterator not" 1723 " referring to this list"); 1724#endif 1725 __node_allocator& __na = base::__node_alloc(); 1726 __hold_pointer __hold = __allocate_node(__na); 1727 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); 1728 __link_pointer __nl = __hold->__as_link(); 1729 __link_nodes(__p.__ptr_, __nl, __nl); 1730 ++base::__sz(); 1731 __hold.release(); 1732#if _LIBCPP_DEBUG_LEVEL == 2 1733 return iterator(__nl, this); 1734#else 1735 return iterator(__nl); 1736#endif 1737} 1738 1739#endif // _LIBCPP_CXX03_LANG 1740 1741template <class _Tp, class _Alloc> 1742void 1743list<_Tp, _Alloc>::pop_front() 1744{ 1745 _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list"); 1746 __node_allocator& __na = base::__node_alloc(); 1747 __link_pointer __n = base::__end_.__next_; 1748 base::__unlink_nodes(__n, __n); 1749 --base::__sz(); 1750#if _LIBCPP_DEBUG_LEVEL == 2 1751 __c_node* __c = __get_db()->__find_c_and_lock(this); 1752 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1753 { 1754 --__p; 1755 iterator* __i = static_cast<iterator*>((*__p)->__i_); 1756 if (__i->__ptr_ == __n) 1757 { 1758 (*__p)->__c_ = nullptr; 1759 if (--__c->end_ != __p) 1760 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1761 } 1762 } 1763 __get_db()->unlock(); 1764#endif 1765 __node_pointer __np = __n->__as_node(); 1766 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); 1767 __node_alloc_traits::deallocate(__na, __np, 1); 1768} 1769 1770template <class _Tp, class _Alloc> 1771void 1772list<_Tp, _Alloc>::pop_back() 1773{ 1774 _LIBCPP_ASSERT(!empty(), "list::pop_back() called on an empty list"); 1775 __node_allocator& __na = base::__node_alloc(); 1776 __link_pointer __n = base::__end_.__prev_; 1777 base::__unlink_nodes(__n, __n); 1778 --base::__sz(); 1779#if _LIBCPP_DEBUG_LEVEL == 2 1780 __c_node* __c = __get_db()->__find_c_and_lock(this); 1781 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1782 { 1783 --__p; 1784 iterator* __i = static_cast<iterator*>((*__p)->__i_); 1785 if (__i->__ptr_ == __n) 1786 { 1787 (*__p)->__c_ = nullptr; 1788 if (--__c->end_ != __p) 1789 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1790 } 1791 } 1792 __get_db()->unlock(); 1793#endif 1794 __node_pointer __np = __n->__as_node(); 1795 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); 1796 __node_alloc_traits::deallocate(__na, __np, 1); 1797} 1798 1799template <class _Tp, class _Alloc> 1800typename list<_Tp, _Alloc>::iterator 1801list<_Tp, _Alloc>::erase(const_iterator __p) 1802{ 1803#if _LIBCPP_DEBUG_LEVEL == 2 1804 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 1805 "list::erase(iterator) called with an iterator not" 1806 " referring to this list"); 1807#endif 1808 _LIBCPP_ASSERT(__p != end(), 1809 "list::erase(iterator) called with a non-dereferenceable iterator"); 1810 __node_allocator& __na = base::__node_alloc(); 1811 __link_pointer __n = __p.__ptr_; 1812 __link_pointer __r = __n->__next_; 1813 base::__unlink_nodes(__n, __n); 1814 --base::__sz(); 1815#if _LIBCPP_DEBUG_LEVEL == 2 1816 __c_node* __c = __get_db()->__find_c_and_lock(this); 1817 for (__i_node** __ip = __c->end_; __ip != __c->beg_; ) 1818 { 1819 --__ip; 1820 iterator* __i = static_cast<iterator*>((*__ip)->__i_); 1821 if (__i->__ptr_ == __n) 1822 { 1823 (*__ip)->__c_ = nullptr; 1824 if (--__c->end_ != __ip) 1825 _VSTD::memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*)); 1826 } 1827 } 1828 __get_db()->unlock(); 1829#endif 1830 __node_pointer __np = __n->__as_node(); 1831 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); 1832 __node_alloc_traits::deallocate(__na, __np, 1); 1833#if _LIBCPP_DEBUG_LEVEL == 2 1834 return iterator(__r, this); 1835#else 1836 return iterator(__r); 1837#endif 1838} 1839 1840template <class _Tp, class _Alloc> 1841typename list<_Tp, _Alloc>::iterator 1842list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) 1843{ 1844#if _LIBCPP_DEBUG_LEVEL == 2 1845 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, 1846 "list::erase(iterator, iterator) called with an iterator not" 1847 " referring to this list"); 1848 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, 1849 "list::erase(iterator, iterator) called with an iterator not" 1850 " referring to this list"); 1851#endif 1852 if (__f != __l) 1853 { 1854 __node_allocator& __na = base::__node_alloc(); 1855 base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_); 1856 while (__f != __l) 1857 { 1858 __link_pointer __n = __f.__ptr_; 1859 ++__f; 1860 --base::__sz(); 1861#if _LIBCPP_DEBUG_LEVEL == 2 1862 __c_node* __c = __get_db()->__find_c_and_lock(this); 1863 for (__i_node** __p = __c->end_; __p != __c->beg_; ) 1864 { 1865 --__p; 1866 iterator* __i = static_cast<iterator*>((*__p)->__i_); 1867 if (__i->__ptr_ == __n) 1868 { 1869 (*__p)->__c_ = nullptr; 1870 if (--__c->end_ != __p) 1871 _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); 1872 } 1873 } 1874 __get_db()->unlock(); 1875#endif 1876 __node_pointer __np = __n->__as_node(); 1877 __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); 1878 __node_alloc_traits::deallocate(__na, __np, 1); 1879 } 1880 } 1881#if _LIBCPP_DEBUG_LEVEL == 2 1882 return iterator(__l.__ptr_, this); 1883#else 1884 return iterator(__l.__ptr_); 1885#endif 1886} 1887 1888template <class _Tp, class _Alloc> 1889void 1890list<_Tp, _Alloc>::resize(size_type __n) 1891{ 1892 if (__n < base::__sz()) 1893 erase(__iterator(__n), end()); 1894 else if (__n > base::__sz()) 1895 { 1896 __n -= base::__sz(); 1897 size_type __ds = 0; 1898 __node_allocator& __na = base::__node_alloc(); 1899 __hold_pointer __hold = __allocate_node(__na); 1900 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); 1901 ++__ds; 1902#if _LIBCPP_DEBUG_LEVEL == 2 1903 iterator __r = iterator(__hold.release()->__as_link(), this); 1904#else 1905 iterator __r = iterator(__hold.release()->__as_link()); 1906#endif 1907 iterator __e = __r; 1908#ifndef _LIBCPP_NO_EXCEPTIONS 1909 try 1910 { 1911#endif // _LIBCPP_NO_EXCEPTIONS 1912 for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) 1913 { 1914 __hold.reset(__node_alloc_traits::allocate(__na, 1)); 1915 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); 1916 __e.__ptr_->__next_ = __hold.get()->__as_link(); 1917 __hold->__prev_ = __e.__ptr_; 1918 __hold.release(); 1919 } 1920#ifndef _LIBCPP_NO_EXCEPTIONS 1921 } 1922 catch (...) 1923 { 1924 while (true) 1925 { 1926 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); 1927 __link_pointer __prev = __e.__ptr_->__prev_; 1928 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); 1929 if (__prev == 0) 1930 break; 1931#if _LIBCPP_DEBUG_LEVEL == 2 1932 __e = iterator(__prev, this); 1933#else 1934 __e = iterator(__prev); 1935#endif 1936 } 1937 throw; 1938 } 1939#endif // _LIBCPP_NO_EXCEPTIONS 1940 __link_nodes_at_back(__r.__ptr_, __e.__ptr_); 1941 base::__sz() += __ds; 1942 } 1943} 1944 1945template <class _Tp, class _Alloc> 1946void 1947list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) 1948{ 1949 if (__n < base::__sz()) 1950 erase(__iterator(__n), end()); 1951 else if (__n > base::__sz()) 1952 { 1953 __n -= base::__sz(); 1954 size_type __ds = 0; 1955 __node_allocator& __na = base::__node_alloc(); 1956 __hold_pointer __hold = __allocate_node(__na); 1957 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1958 ++__ds; 1959 __link_pointer __nl = __hold.release()->__as_link(); 1960#if _LIBCPP_DEBUG_LEVEL == 2 1961 iterator __r = iterator(__nl, this); 1962#else 1963 iterator __r = iterator(__nl); 1964#endif 1965 iterator __e = __r; 1966#ifndef _LIBCPP_NO_EXCEPTIONS 1967 try 1968 { 1969#endif // _LIBCPP_NO_EXCEPTIONS 1970 for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) 1971 { 1972 __hold.reset(__node_alloc_traits::allocate(__na, 1)); 1973 __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); 1974 __e.__ptr_->__next_ = __hold.get()->__as_link(); 1975 __hold->__prev_ = __e.__ptr_; 1976 __hold.release(); 1977 } 1978#ifndef _LIBCPP_NO_EXCEPTIONS 1979 } 1980 catch (...) 1981 { 1982 while (true) 1983 { 1984 __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); 1985 __link_pointer __prev = __e.__ptr_->__prev_; 1986 __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); 1987 if (__prev == 0) 1988 break; 1989#if _LIBCPP_DEBUG_LEVEL == 2 1990 __e = iterator(__prev, this); 1991#else 1992 __e = iterator(__prev); 1993#endif 1994 } 1995 throw; 1996 } 1997#endif // _LIBCPP_NO_EXCEPTIONS 1998 __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_); 1999 base::__sz() += __ds; 2000 } 2001} 2002 2003template <class _Tp, class _Alloc> 2004void 2005list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) 2006{ 2007 _LIBCPP_ASSERT(this != _VSTD::addressof(__c), 2008 "list::splice(iterator, list) called with this == &list"); 2009#if _LIBCPP_DEBUG_LEVEL == 2 2010 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 2011 "list::splice(iterator, list) called with an iterator not" 2012 " referring to this list"); 2013#endif 2014 if (!__c.empty()) 2015 { 2016 __link_pointer __f = __c.__end_.__next_; 2017 __link_pointer __l = __c.__end_.__prev_; 2018 base::__unlink_nodes(__f, __l); 2019 __link_nodes(__p.__ptr_, __f, __l); 2020 base::__sz() += __c.__sz(); 2021 __c.__sz() = 0; 2022#if _LIBCPP_DEBUG_LEVEL == 2 2023 if (_VSTD::addressof(__c) != this) { 2024 __libcpp_db* __db = __get_db(); 2025 __c_node* __cn1 = __db->__find_c_and_lock(this); 2026 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); 2027 for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) 2028 { 2029 --__ip; 2030 iterator* __i = static_cast<iterator*>((*__ip)->__i_); 2031 if (__i->__ptr_ != __c.__end_as_link()) 2032 { 2033 __cn1->__add(*__ip); 2034 (*__ip)->__c_ = __cn1; 2035 if (--__cn2->end_ != __ip) 2036 _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); 2037 } 2038 } 2039 __db->unlock(); 2040 } 2041#endif 2042 } 2043} 2044 2045template <class _Tp, class _Alloc> 2046void 2047list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) 2048{ 2049#if _LIBCPP_DEBUG_LEVEL == 2 2050 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 2051 "list::splice(iterator, list, iterator) called with the first iterator" 2052 " not referring to this list"); 2053 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), 2054 "list::splice(iterator, list, iterator) called with the second iterator" 2055 " not referring to the list argument"); 2056 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), 2057 "list::splice(iterator, list, iterator) called with the second iterator" 2058 " not dereferenceable"); 2059#endif 2060 if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) 2061 { 2062 __link_pointer __f = __i.__ptr_; 2063 base::__unlink_nodes(__f, __f); 2064 __link_nodes(__p.__ptr_, __f, __f); 2065 --__c.__sz(); 2066 ++base::__sz(); 2067#if _LIBCPP_DEBUG_LEVEL == 2 2068 if (_VSTD::addressof(__c) != this) { 2069 __libcpp_db* __db = __get_db(); 2070 __c_node* __cn1 = __db->__find_c_and_lock(this); 2071 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); 2072 for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) 2073 { 2074 --__ip; 2075 iterator* __j = static_cast<iterator*>((*__ip)->__i_); 2076 if (__j->__ptr_ == __f) 2077 { 2078 __cn1->__add(*__ip); 2079 (*__ip)->__c_ = __cn1; 2080 if (--__cn2->end_ != __ip) 2081 _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); 2082 } 2083 } 2084 __db->unlock(); 2085 } 2086#endif 2087 } 2088} 2089 2090template <class _Tp, class _Alloc> 2091void 2092list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) 2093{ 2094#if _LIBCPP_DEBUG_LEVEL == 2 2095 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, 2096 "list::splice(iterator, list, iterator, iterator) called with first iterator not" 2097 " referring to this list"); 2098 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), 2099 "list::splice(iterator, list, iterator, iterator) called with second iterator not" 2100 " referring to the list argument"); 2101 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), 2102 "list::splice(iterator, list, iterator, iterator) called with third iterator not" 2103 " referring to the list argument"); 2104 if (this == _VSTD::addressof(__c)) 2105 { 2106 for (const_iterator __i = __f; __i != __l; ++__i) 2107 _LIBCPP_ASSERT(__i != __p, 2108 "list::splice(iterator, list, iterator, iterator)" 2109 " called with the first iterator within the range" 2110 " of the second and third iterators"); 2111 } 2112#endif 2113 if (__f != __l) 2114 { 2115 __link_pointer __first = __f.__ptr_; 2116 --__l; 2117 __link_pointer __last = __l.__ptr_; 2118 if (this != _VSTD::addressof(__c)) 2119 { 2120 size_type __s = _VSTD::distance(__f, __l) + 1; 2121 __c.__sz() -= __s; 2122 base::__sz() += __s; 2123 } 2124 base::__unlink_nodes(__first, __last); 2125 __link_nodes(__p.__ptr_, __first, __last); 2126#if _LIBCPP_DEBUG_LEVEL == 2 2127 if (_VSTD::addressof(__c) != this) { 2128 __libcpp_db* __db = __get_db(); 2129 __c_node* __cn1 = __db->__find_c_and_lock(this); 2130 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); 2131 for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) 2132 { 2133 --__ip; 2134 iterator* __j = static_cast<iterator*>((*__ip)->__i_); 2135 for (__link_pointer __k = __f.__ptr_; 2136 __k != __l.__ptr_; __k = __k->__next_) 2137 { 2138 if (__j->__ptr_ == __k) 2139 { 2140 __cn1->__add(*__ip); 2141 (*__ip)->__c_ = __cn1; 2142 if (--__cn2->end_ != __ip) 2143 _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); 2144 } 2145 } 2146 } 2147 __db->unlock(); 2148 } 2149#endif 2150 } 2151} 2152 2153template <class _Tp, class _Alloc> 2154typename list<_Tp, _Alloc>::__remove_return_type 2155list<_Tp, _Alloc>::remove(const value_type& __x) 2156{ 2157 list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing 2158 for (const_iterator __i = begin(), __e = end(); __i != __e;) 2159 { 2160 if (*__i == __x) 2161 { 2162 const_iterator __j = _VSTD::next(__i); 2163 for (; __j != __e && *__j == __x; ++__j) 2164 ; 2165 __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); 2166 __i = __j; 2167 if (__i != __e) 2168 ++__i; 2169 } 2170 else 2171 ++__i; 2172 } 2173 2174 return (__remove_return_type) __deleted_nodes.size(); 2175} 2176 2177template <class _Tp, class _Alloc> 2178template <class _Pred> 2179typename list<_Tp, _Alloc>::__remove_return_type 2180list<_Tp, _Alloc>::remove_if(_Pred __pred) 2181{ 2182 list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing 2183 for (iterator __i = begin(), __e = end(); __i != __e;) 2184 { 2185 if (__pred(*__i)) 2186 { 2187 iterator __j = _VSTD::next(__i); 2188 for (; __j != __e && __pred(*__j); ++__j) 2189 ; 2190 __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); 2191 __i = __j; 2192 if (__i != __e) 2193 ++__i; 2194 } 2195 else 2196 ++__i; 2197 } 2198 2199 return (__remove_return_type) __deleted_nodes.size(); 2200} 2201 2202template <class _Tp, class _Alloc> 2203template <class _BinaryPred> 2204typename list<_Tp, _Alloc>::__remove_return_type 2205list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) 2206{ 2207 list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing 2208 for (iterator __i = begin(), __e = end(); __i != __e;) 2209 { 2210 iterator __j = _VSTD::next(__i); 2211 for (; __j != __e && __binary_pred(*__i, *__j); ++__j) 2212 ; 2213 if (++__i != __j) { 2214 __deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j); 2215 __i = __j; 2216 } 2217 } 2218 2219 return (__remove_return_type) __deleted_nodes.size(); 2220} 2221 2222template <class _Tp, class _Alloc> 2223inline 2224void 2225list<_Tp, _Alloc>::merge(list& __c) 2226{ 2227 merge(__c, __less<value_type>()); 2228} 2229 2230template <class _Tp, class _Alloc> 2231template <class _Comp> 2232void 2233list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) 2234{ 2235 if (this != _VSTD::addressof(__c)) 2236 { 2237 iterator __f1 = begin(); 2238 iterator __e1 = end(); 2239 iterator __f2 = __c.begin(); 2240 iterator __e2 = __c.end(); 2241 while (__f1 != __e1 && __f2 != __e2) 2242 { 2243 if (__comp(*__f2, *__f1)) 2244 { 2245 size_type __ds = 1; 2246 iterator __m2 = _VSTD::next(__f2); 2247 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, (void) ++__ds) 2248 ; 2249 base::__sz() += __ds; 2250 __c.__sz() -= __ds; 2251 __link_pointer __f = __f2.__ptr_; 2252 __link_pointer __l = __m2.__ptr_->__prev_; 2253 __f2 = __m2; 2254 base::__unlink_nodes(__f, __l); 2255 __m2 = _VSTD::next(__f1); 2256 __link_nodes(__f1.__ptr_, __f, __l); 2257 __f1 = __m2; 2258 } 2259 else 2260 ++__f1; 2261 } 2262 splice(__e1, __c); 2263#if _LIBCPP_DEBUG_LEVEL == 2 2264 __libcpp_db* __db = __get_db(); 2265 __c_node* __cn1 = __db->__find_c_and_lock(this); 2266 __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); 2267 for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) 2268 { 2269 --__p; 2270 iterator* __i = static_cast<iterator*>((*__p)->__i_); 2271 if (__i->__ptr_ != __c.__end_as_link()) 2272 { 2273 __cn1->__add(*__p); 2274 (*__p)->__c_ = __cn1; 2275 if (--__cn2->end_ != __p) 2276 _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); 2277 } 2278 } 2279 __db->unlock(); 2280#endif 2281 } 2282} 2283 2284template <class _Tp, class _Alloc> 2285inline 2286void 2287list<_Tp, _Alloc>::sort() 2288{ 2289 sort(__less<value_type>()); 2290} 2291 2292template <class _Tp, class _Alloc> 2293template <class _Comp> 2294inline 2295void 2296list<_Tp, _Alloc>::sort(_Comp __comp) 2297{ 2298 __sort(begin(), end(), base::__sz(), __comp); 2299} 2300 2301template <class _Tp, class _Alloc> 2302template <class _Comp> 2303typename list<_Tp, _Alloc>::iterator 2304list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp) 2305{ 2306 switch (__n) 2307 { 2308 case 0: 2309 case 1: 2310 return __f1; 2311 case 2: 2312 if (__comp(*--__e2, *__f1)) 2313 { 2314 __link_pointer __f = __e2.__ptr_; 2315 base::__unlink_nodes(__f, __f); 2316 __link_nodes(__f1.__ptr_, __f, __f); 2317 return __e2; 2318 } 2319 return __f1; 2320 } 2321 size_type __n2 = __n / 2; 2322 iterator __e1 = _VSTD::next(__f1, __n2); 2323 iterator __r = __f1 = __sort(__f1, __e1, __n2, __comp); 2324 iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp); 2325 if (__comp(*__f2, *__f1)) 2326 { 2327 iterator __m2 = _VSTD::next(__f2); 2328 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2) 2329 ; 2330 __link_pointer __f = __f2.__ptr_; 2331 __link_pointer __l = __m2.__ptr_->__prev_; 2332 __r = __f2; 2333 __e1 = __f2 = __m2; 2334 base::__unlink_nodes(__f, __l); 2335 __m2 = _VSTD::next(__f1); 2336 __link_nodes(__f1.__ptr_, __f, __l); 2337 __f1 = __m2; 2338 } 2339 else 2340 ++__f1; 2341 while (__f1 != __e1 && __f2 != __e2) 2342 { 2343 if (__comp(*__f2, *__f1)) 2344 { 2345 iterator __m2 = _VSTD::next(__f2); 2346 for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2) 2347 ; 2348 __link_pointer __f = __f2.__ptr_; 2349 __link_pointer __l = __m2.__ptr_->__prev_; 2350 if (__e1 == __f2) 2351 __e1 = __m2; 2352 __f2 = __m2; 2353 base::__unlink_nodes(__f, __l); 2354 __m2 = _VSTD::next(__f1); 2355 __link_nodes(__f1.__ptr_, __f, __l); 2356 __f1 = __m2; 2357 } 2358 else 2359 ++__f1; 2360 } 2361 return __r; 2362} 2363 2364template <class _Tp, class _Alloc> 2365void 2366list<_Tp, _Alloc>::reverse() _NOEXCEPT 2367{ 2368 if (base::__sz() > 1) 2369 { 2370 iterator __e = end(); 2371 for (iterator __i = begin(); __i.__ptr_ != __e.__ptr_;) 2372 { 2373 _VSTD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_); 2374 __i.__ptr_ = __i.__ptr_->__prev_; 2375 } 2376 _VSTD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_); 2377 } 2378} 2379 2380template <class _Tp, class _Alloc> 2381bool 2382list<_Tp, _Alloc>::__invariants() const 2383{ 2384 return size() == _VSTD::distance(begin(), end()); 2385} 2386 2387#if _LIBCPP_DEBUG_LEVEL == 2 2388 2389template <class _Tp, class _Alloc> 2390bool 2391list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const 2392{ 2393 return __i->__ptr_ != this->__end_as_link(); 2394} 2395 2396template <class _Tp, class _Alloc> 2397bool 2398list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const 2399{ 2400 return !empty() && __i->__ptr_ != base::__end_.__next_; 2401} 2402 2403template <class _Tp, class _Alloc> 2404bool 2405list<_Tp, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const 2406{ 2407 return false; 2408} 2409 2410template <class _Tp, class _Alloc> 2411bool 2412list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const 2413{ 2414 return false; 2415} 2416 2417#endif // _LIBCPP_DEBUG_LEVEL == 2 2418 2419template <class _Tp, class _Alloc> 2420inline _LIBCPP_INLINE_VISIBILITY 2421bool 2422operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 2423{ 2424 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); 2425} 2426 2427template <class _Tp, class _Alloc> 2428inline _LIBCPP_INLINE_VISIBILITY 2429bool 2430operator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 2431{ 2432 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 2433} 2434 2435template <class _Tp, class _Alloc> 2436inline _LIBCPP_INLINE_VISIBILITY 2437bool 2438operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 2439{ 2440 return !(__x == __y); 2441} 2442 2443template <class _Tp, class _Alloc> 2444inline _LIBCPP_INLINE_VISIBILITY 2445bool 2446operator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 2447{ 2448 return __y < __x; 2449} 2450 2451template <class _Tp, class _Alloc> 2452inline _LIBCPP_INLINE_VISIBILITY 2453bool 2454operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 2455{ 2456 return !(__x < __y); 2457} 2458 2459template <class _Tp, class _Alloc> 2460inline _LIBCPP_INLINE_VISIBILITY 2461bool 2462operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) 2463{ 2464 return !(__y < __x); 2465} 2466 2467template <class _Tp, class _Alloc> 2468inline _LIBCPP_INLINE_VISIBILITY 2469void 2470swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) 2471 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 2472{ 2473 __x.swap(__y); 2474} 2475 2476#if _LIBCPP_STD_VER > 17 2477template <class _Tp, class _Allocator, class _Predicate> 2478inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type 2479erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) { 2480 return __c.remove_if(__pred); 2481} 2482 2483template <class _Tp, class _Allocator, class _Up> 2484inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type 2485erase(list<_Tp, _Allocator>& __c, const _Up& __v) { 2486 return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); 2487} 2488#endif 2489 2490_LIBCPP_END_NAMESPACE_STD 2491 2492_LIBCPP_POP_MACROS 2493 2494#endif // _LIBCPP_LIST 2495