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