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