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