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