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