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