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