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