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