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