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