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