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