forward_list revision 227825
1// -*- C++ -*-
2//===----------------------- forward_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_FORWARD_LIST
12#define _LIBCPP_FORWARD_LIST
13
14/*
15    forward_list synopsis
16
17namespace std
18{
19
20template <class T, class Allocator = allocator<T>>
21class forward_list
22{
23public:
24    typedef T         value_type;
25    typedef Allocator allocator_type;
26
27    typedef value_type&                                                reference;
28    typedef const value_type&                                          const_reference;
29    typedef typename allocator_traits<allocator_type>::pointer         pointer;
30    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
31    typedef typename allocator_traits<allocator_type>::size_type       size_type;
32    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
33
34    typedef <details> iterator;
35    typedef <details> const_iterator;
36
37    forward_list()
38        noexcept(is_nothrow_default_constructible<allocator_type>::value);
39    explicit forward_list(const allocator_type& a);
40    explicit forward_list(size_type n);
41    forward_list(size_type n, const value_type& v);
42    forward_list(size_type n, const value_type& v, const allocator_type& a);
43    template <class InputIterator>
44        forward_list(InputIterator first, InputIterator last);
45    template <class InputIterator>
46        forward_list(InputIterator first, InputIterator last, const allocator_type& a);
47    forward_list(const forward_list& x);
48    forward_list(const forward_list& x, const allocator_type& a);
49    forward_list(forward_list&& x)
50        noexcept(is_nothrow_move_constructible<allocator_type>::value);
51    forward_list(forward_list&& x, const allocator_type& a);
52    forward_list(initializer_list<value_type> il);
53    forward_list(initializer_list<value_type> il, const allocator_type& a);
54
55    ~forward_list();
56
57    forward_list& operator=(const forward_list& x);
58    forward_list& operator=(forward_list&& x)
59        noexcept(
60             allocator_type::propagate_on_container_move_assignment::value &&
61             is_nothrow_move_assignable<allocator_type>::value);
62    forward_list& operator=(initializer_list<value_type> il);
63
64    template <class InputIterator>
65        void assign(InputIterator first, InputIterator last);
66    void assign(size_type n, const value_type& v);
67    void assign(initializer_list<value_type> il);
68
69    allocator_type get_allocator() const noexcept;
70
71    iterator       begin() noexcept;
72    const_iterator begin() const noexcept;
73    iterator       end() noexcept;
74    const_iterator end() const noexcept;
75
76    const_iterator cbegin() const noexcept;
77    const_iterator cend() const noexcept;
78
79    iterator       before_begin() noexcept;
80    const_iterator before_begin() const noexcept;
81    const_iterator cbefore_begin() const noexcept;
82
83    bool empty() const noexcept;
84    size_type max_size() const noexcept;
85
86    reference       front();
87    const_reference front() const;
88
89    template <class... Args> void emplace_front(Args&&... args);
90    void push_front(const value_type& v);
91    void push_front(value_type&& v);
92
93    void pop_front();
94
95    template <class... Args>
96        iterator emplace_after(const_iterator p, Args&&... args);
97    iterator insert_after(const_iterator p, const value_type& v);
98    iterator insert_after(const_iterator p, value_type&& v);
99    iterator insert_after(const_iterator p, size_type n, const value_type& v);
100    template <class InputIterator>
101        iterator insert_after(const_iterator p,
102                              InputIterator first, InputIterator last);
103    iterator insert_after(const_iterator p, initializer_list<value_type> il);
104
105    iterator erase_after(const_iterator p);
106    iterator erase_after(const_iterator first, const_iterator last);
107
108    void swap(forward_list& x)
109        noexcept(!allocator_type::propagate_on_container_swap::value ||
110                 __is_nothrow_swappable<allocator_type>::value);
111
112    void resize(size_type n);
113    void resize(size_type n, const value_type& v);
114    void clear() noexcept;
115
116    void splice_after(const_iterator p, forward_list& x);
117    void splice_after(const_iterator p, forward_list&& x);
118    void splice_after(const_iterator p, forward_list& x, const_iterator i);
119    void splice_after(const_iterator p, forward_list&& x, const_iterator i);
120    void splice_after(const_iterator p, forward_list& x,
121                      const_iterator first, const_iterator last);
122    void splice_after(const_iterator p, forward_list&& x,
123                      const_iterator first, const_iterator last);
124    void remove(const value_type& v);
125    template <class Predicate> void remove_if(Predicate pred);
126    void unique();
127    template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
128    void merge(forward_list& x);
129    void merge(forward_list&& x);
130    template <class Compare> void merge(forward_list& x, Compare comp);
131    template <class Compare> void merge(forward_list&& x, Compare comp);
132    void sort();
133    template <class Compare> void sort(Compare comp);
134    void reverse() noexcept;
135};
136
137template <class T, class Allocator>
138    bool operator==(const forward_list<T, Allocator>& x,
139                    const forward_list<T, Allocator>& y);
140
141template <class T, class Allocator>
142    bool operator< (const forward_list<T, Allocator>& x,
143                    const forward_list<T, Allocator>& y);
144
145template <class T, class Allocator>
146    bool operator!=(const forward_list<T, Allocator>& x,
147                    const forward_list<T, Allocator>& y);
148
149template <class T, class Allocator>
150    bool operator> (const forward_list<T, Allocator>& x,
151                    const forward_list<T, Allocator>& y);
152
153template <class T, class Allocator>
154    bool operator>=(const forward_list<T, Allocator>& x,
155                    const forward_list<T, Allocator>& y);
156
157template <class T, class Allocator>
158    bool operator<=(const forward_list<T, Allocator>& x,
159                    const forward_list<T, Allocator>& y);
160
161template <class T, class Allocator>
162    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
163         noexcept(noexcept(x.swap(y)));
164
165}  // std
166
167*/
168
169#include <__config>
170
171#include <initializer_list>
172#include <memory>
173#include <limits>
174#include <iterator>
175#include <algorithm>
176
177#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
178#pragma GCC system_header
179#endif
180
181_LIBCPP_BEGIN_NAMESPACE_STD
182
183template <class _Tp, class _VoidPtr> struct __forward_list_node;
184
185template <class _NodePtr>
186struct __forward_begin_node
187{
188    typedef __forward_begin_node __self;
189    typedef _NodePtr pointer;
190
191    pointer __next_;
192
193     _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
194};
195
196template <class _Tp, class _VoidPtr>
197struct __forward_list_node
198    : public __forward_begin_node
199             <
200                 typename pointer_traits<_VoidPtr>::template
201#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
202                     rebind<__forward_list_node<_Tp, _VoidPtr> >
203#else
204                     rebind<__forward_list_node<_Tp, _VoidPtr> >::other
205#endif
206             >
207{
208    typedef _Tp value_type;
209
210    value_type __value_;
211};
212
213template<class _Tp, class _Alloc> class forward_list;
214template<class _NodeConstPtr> class __forward_list_const_iterator;
215
216template <class _NodePtr>
217class _LIBCPP_VISIBLE __forward_list_iterator
218{
219    typedef _NodePtr __node_pointer;
220
221    __node_pointer __ptr_;
222
223    _LIBCPP_INLINE_VISIBILITY
224    explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
225
226    template<class, class> friend class forward_list;
227    template<class> friend class __forward_list_const_iterator;
228
229public:
230    typedef forward_iterator_tag                              iterator_category;
231    typedef typename pointer_traits<__node_pointer>::element_type::value_type
232                                                              value_type;
233    typedef value_type& reference;
234    typedef typename pointer_traits<__node_pointer>::difference_type
235                                                              difference_type;
236    typedef typename pointer_traits<__node_pointer>::template
237#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
238            rebind<value_type>
239#else
240            rebind<value_type>::other
241#endif
242                                                              pointer;
243
244    _LIBCPP_INLINE_VISIBILITY
245    __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
246
247    _LIBCPP_INLINE_VISIBILITY
248    reference operator*() const {return __ptr_->__value_;}
249    _LIBCPP_INLINE_VISIBILITY
250    pointer operator->() const {return &__ptr_->__value_;}
251
252    _LIBCPP_INLINE_VISIBILITY
253    __forward_list_iterator& operator++()
254    {
255        __ptr_ = __ptr_->__next_;
256        return *this;
257    }
258    _LIBCPP_INLINE_VISIBILITY
259    __forward_list_iterator operator++(int)
260    {
261        __forward_list_iterator __t(*this);
262        ++(*this);
263        return __t;
264    }
265
266    friend _LIBCPP_INLINE_VISIBILITY
267    bool operator==(const __forward_list_iterator& __x,
268                    const __forward_list_iterator& __y)
269        {return __x.__ptr_ == __y.__ptr_;}
270    friend _LIBCPP_INLINE_VISIBILITY
271    bool operator!=(const __forward_list_iterator& __x,
272                    const __forward_list_iterator& __y)
273        {return !(__x == __y);}
274};
275
276template <class _NodeConstPtr>
277class _LIBCPP_VISIBLE __forward_list_const_iterator
278{
279    typedef _NodeConstPtr __node_const_pointer;
280
281    __node_const_pointer __ptr_;
282
283    _LIBCPP_INLINE_VISIBILITY
284    explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
285        : __ptr_(__p) {}
286
287    typedef typename remove_const
288        <
289            typename pointer_traits<__node_const_pointer>::element_type
290        >::type                                               __node;
291    typedef typename pointer_traits<__node_const_pointer>::template
292#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
293            rebind<__node>
294#else
295            rebind<__node>::other
296#endif
297                                                              __node_pointer;
298
299    template<class, class> friend class forward_list;
300
301public:
302    typedef forward_iterator_tag                              iterator_category;
303    typedef typename __node::value_type                       value_type;
304    typedef const value_type& reference;
305    typedef typename pointer_traits<__node_const_pointer>::difference_type
306                                                              difference_type;
307    typedef typename pointer_traits<__node_const_pointer>::template
308#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
309            rebind<const value_type>
310#else
311            rebind<const value_type>::other
312#endif
313                                                              pointer;
314
315    _LIBCPP_INLINE_VISIBILITY
316    __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
317    _LIBCPP_INLINE_VISIBILITY
318    __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
319        : __ptr_(__p.__ptr_) {}
320
321    _LIBCPP_INLINE_VISIBILITY
322    reference operator*() const {return __ptr_->__value_;}
323    _LIBCPP_INLINE_VISIBILITY
324    pointer operator->() const {return &__ptr_->__value_;}
325
326    _LIBCPP_INLINE_VISIBILITY
327    __forward_list_const_iterator& operator++()
328    {
329        __ptr_ = __ptr_->__next_;
330        return *this;
331    }
332    _LIBCPP_INLINE_VISIBILITY
333    __forward_list_const_iterator operator++(int)
334    {
335        __forward_list_const_iterator __t(*this);
336        ++(*this);
337        return __t;
338    }
339
340    friend _LIBCPP_INLINE_VISIBILITY
341    bool operator==(const __forward_list_const_iterator& __x,
342                    const __forward_list_const_iterator& __y)
343        {return __x.__ptr_ == __y.__ptr_;}
344    friend _LIBCPP_INLINE_VISIBILITY
345    bool operator!=(const __forward_list_const_iterator& __x,
346                           const __forward_list_const_iterator& __y)
347        {return !(__x == __y);}
348};
349
350template <class _Tp, class _Alloc>
351class __forward_list_base
352{
353protected:
354    typedef _Tp    value_type;
355    typedef _Alloc allocator_type;
356
357    typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
358    typedef __forward_list_node<value_type, void_pointer>           __node;
359    typedef typename __node::__self                                 __begin_node;
360    typedef typename allocator_traits<allocator_type>::template
361#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
362                rebind_alloc<__node>
363#else
364                rebind_alloc<__node>::other
365#endif
366                                                      __node_allocator;
367    typedef allocator_traits<__node_allocator>        __node_traits;
368    typedef typename __node_traits::pointer           __node_pointer;
369    typedef typename __node_traits::const_pointer     __node_const_pointer;
370
371    __compressed_pair<__begin_node, __node_allocator> __before_begin_;
372
373    _LIBCPP_INLINE_VISIBILITY
374    __node_pointer        __before_begin() _NOEXCEPT
375        {return pointer_traits<__node_pointer>::pointer_to(
376                                static_cast<__node&>(__before_begin_.first()));}
377    _LIBCPP_INLINE_VISIBILITY
378    __node_const_pointer  __before_begin() const _NOEXCEPT
379        {return pointer_traits<__node_const_pointer>::pointer_to(
380                          static_cast<const __node&>(__before_begin_.first()));}
381
382    _LIBCPP_INLINE_VISIBILITY
383          __node_allocator& __alloc() _NOEXCEPT
384            {return __before_begin_.second();}
385    _LIBCPP_INLINE_VISIBILITY
386    const __node_allocator& __alloc() const _NOEXCEPT
387        {return __before_begin_.second();}
388
389    typedef __forward_list_iterator<__node_pointer>             iterator;
390    typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
391
392    _LIBCPP_INLINE_VISIBILITY
393    __forward_list_base()
394        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
395        : __before_begin_(__begin_node()) {}
396    _LIBCPP_INLINE_VISIBILITY
397    __forward_list_base(const allocator_type& __a)
398        : __before_begin_(__begin_node(), __node_allocator(__a)) {}
399
400#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
401public:
402    __forward_list_base(__forward_list_base&& __x)
403        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
404    __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
405#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
406
407private:
408    __forward_list_base(const __forward_list_base&);
409    __forward_list_base& operator=(const __forward_list_base&);
410
411public:
412    ~__forward_list_base();
413
414protected:
415    _LIBCPP_INLINE_VISIBILITY
416    void __copy_assign_alloc(const __forward_list_base& __x)
417        {__copy_assign_alloc(__x, integral_constant<bool,
418              __node_traits::propagate_on_container_copy_assignment::value>());}
419
420    _LIBCPP_INLINE_VISIBILITY
421    void __move_assign_alloc(__forward_list_base& __x)
422        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
423                   is_nothrow_move_assignable<__node_allocator>::value)
424        {__move_assign_alloc(__x, integral_constant<bool,
425              __node_traits::propagate_on_container_move_assignment::value>());}
426
427public:
428    void swap(__forward_list_base& __x)
429        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
430                   __is_nothrow_swappable<__node_allocator>::value);
431protected:
432    void clear() _NOEXCEPT;
433
434private:
435    _LIBCPP_INLINE_VISIBILITY
436    void __copy_assign_alloc(const __forward_list_base&, false_type) {}
437    _LIBCPP_INLINE_VISIBILITY
438    void __copy_assign_alloc(const __forward_list_base& __x, true_type)
439    {
440        if (__alloc() != __x.__alloc())
441            clear();
442        __alloc() = __x.__alloc();
443    }
444
445    _LIBCPP_INLINE_VISIBILITY
446    void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
447        {}
448    _LIBCPP_INLINE_VISIBILITY
449    void __move_assign_alloc(__forward_list_base& __x, true_type)
450        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
451        {__alloc() = _VSTD::move(__x.__alloc());}
452
453    _LIBCPP_INLINE_VISIBILITY
454    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
455        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
456                   __is_nothrow_swappable<__node_allocator>::value)
457        {__swap_alloc(__x, __y, integral_constant<bool,
458                         __node_traits::propagate_on_container_swap::value>());}
459    _LIBCPP_INLINE_VISIBILITY
460    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
461                                                                     false_type)
462        _NOEXCEPT
463        {}
464    _LIBCPP_INLINE_VISIBILITY
465    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
466                                                                      true_type)
467        _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
468        {
469            using _VSTD::swap;
470            swap(__x, __y);
471        }
472};
473
474#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
475
476template <class _Tp, class _Alloc>
477inline _LIBCPP_INLINE_VISIBILITY
478__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
479        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
480    : __before_begin_(_VSTD::move(__x.__before_begin_))
481{
482    __x.__before_begin()->__next_ = nullptr;
483}
484
485template <class _Tp, class _Alloc>
486inline _LIBCPP_INLINE_VISIBILITY
487__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
488                                                      const allocator_type& __a)
489    : __before_begin_(__begin_node(), __node_allocator(__a))
490{
491    if (__alloc() == __x.__alloc())
492    {
493        __before_begin()->__next_ = __x.__before_begin()->__next_;
494        __x.__before_begin()->__next_ = nullptr;
495    }
496}
497
498#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
499
500template <class _Tp, class _Alloc>
501__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
502{
503    clear();
504}
505
506template <class _Tp, class _Alloc>
507inline _LIBCPP_INLINE_VISIBILITY
508void
509__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
510        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
511                   __is_nothrow_swappable<__node_allocator>::value)
512{
513    __swap_alloc(__alloc(), __x.__alloc());
514    using _VSTD::swap;
515    swap(__before_begin()->__next_, __x.__before_begin()->__next_);
516}
517
518template <class _Tp, class _Alloc>
519void
520__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
521{
522    __node_allocator& __a = __alloc();
523    for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
524    {
525        __node_pointer __next = __p->__next_;
526        __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
527        __node_traits::deallocate(__a, __p, 1);
528        __p = __next;
529    }
530    __before_begin()->__next_ = nullptr;
531}
532
533template <class _Tp, class _Alloc = allocator<_Tp> >
534class _LIBCPP_VISIBLE forward_list
535    : private __forward_list_base<_Tp, _Alloc>
536{
537    typedef __forward_list_base<_Tp, _Alloc> base;
538    typedef typename base::__node_allocator  __node_allocator;
539    typedef typename base::__node            __node;
540    typedef typename base::__node_traits     __node_traits;
541    typedef typename base::__node_pointer    __node_pointer;
542
543public:
544    typedef _Tp    value_type;
545    typedef _Alloc allocator_type;
546
547    typedef value_type&                                                reference;
548    typedef const value_type&                                          const_reference;
549    typedef typename allocator_traits<allocator_type>::pointer         pointer;
550    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
551    typedef typename allocator_traits<allocator_type>::size_type       size_type;
552    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
553
554    typedef typename base::iterator       iterator;
555    typedef typename base::const_iterator const_iterator;
556
557    _LIBCPP_INLINE_VISIBILITY
558    forward_list()
559        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
560        {} // = default;
561    explicit forward_list(const allocator_type& __a);
562    explicit forward_list(size_type __n);
563    forward_list(size_type __n, const value_type& __v);
564    forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
565    template <class _InputIterator>
566        forward_list(_InputIterator __f, _InputIterator __l,
567                     typename enable_if<
568                       __is_input_iterator<_InputIterator>::value
569                     >::type* = nullptr);
570    template <class _InputIterator>
571        forward_list(_InputIterator __f, _InputIterator __l,
572                     const allocator_type& __a,
573                     typename enable_if<
574                       __is_input_iterator<_InputIterator>::value
575                     >::type* = nullptr);
576    forward_list(const forward_list& __x);
577    forward_list(const forward_list& __x, const allocator_type& __a);
578#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
579    _LIBCPP_INLINE_VISIBILITY
580    forward_list(forward_list&& __x)
581        _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
582        : base(_VSTD::move(__x)) {}
583    forward_list(forward_list&& __x, const allocator_type& __a);
584#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
585#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
586    forward_list(initializer_list<value_type> __il);
587    forward_list(initializer_list<value_type> __il, const allocator_type& __a);
588#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
589
590    // ~forward_list() = default;
591
592    forward_list& operator=(const forward_list& __x);
593#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
594    forward_list& operator=(forward_list&& __x)
595        _NOEXCEPT_(
596             __node_traits::propagate_on_container_move_assignment::value &&
597             is_nothrow_move_assignable<allocator_type>::value);
598#endif
599#ifndef  _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
600    forward_list& operator=(initializer_list<value_type> __il);
601#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
602
603    template <class _InputIterator>
604        typename enable_if
605        <
606            __is_input_iterator<_InputIterator>::value,
607            void
608        >::type
609        assign(_InputIterator __f, _InputIterator __l);
610    void assign(size_type __n, const value_type& __v);
611#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
612    void assign(initializer_list<value_type> __il);
613#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
614
615    _LIBCPP_INLINE_VISIBILITY
616    allocator_type get_allocator() const _NOEXCEPT
617        {return allocator_type(base::__alloc());}
618
619    _LIBCPP_INLINE_VISIBILITY
620    iterator       begin() _NOEXCEPT
621        {return       iterator(base::__before_begin()->__next_);}
622    _LIBCPP_INLINE_VISIBILITY
623    const_iterator begin() const _NOEXCEPT
624        {return const_iterator(base::__before_begin()->__next_);}
625    _LIBCPP_INLINE_VISIBILITY
626    iterator       end() _NOEXCEPT
627        {return       iterator(nullptr);}
628    _LIBCPP_INLINE_VISIBILITY
629    const_iterator end() const _NOEXCEPT
630        {return const_iterator(nullptr);}
631
632    _LIBCPP_INLINE_VISIBILITY
633    const_iterator cbegin() const _NOEXCEPT
634        {return const_iterator(base::__before_begin()->__next_);}
635    _LIBCPP_INLINE_VISIBILITY
636    const_iterator cend() const _NOEXCEPT
637        {return const_iterator(nullptr);}
638
639    _LIBCPP_INLINE_VISIBILITY
640    iterator       before_begin() _NOEXCEPT
641        {return       iterator(base::__before_begin());}
642    _LIBCPP_INLINE_VISIBILITY
643    const_iterator before_begin() const _NOEXCEPT
644        {return const_iterator(base::__before_begin());}
645    _LIBCPP_INLINE_VISIBILITY
646    const_iterator cbefore_begin() const _NOEXCEPT
647        {return const_iterator(base::__before_begin());}
648
649    _LIBCPP_INLINE_VISIBILITY
650    bool empty() const _NOEXCEPT
651        {return base::__before_begin()->__next_ == nullptr;}
652    _LIBCPP_INLINE_VISIBILITY
653    size_type max_size() const _NOEXCEPT
654        {return numeric_limits<size_type>::max();}
655
656    _LIBCPP_INLINE_VISIBILITY
657    reference       front()       {return base::__before_begin()->__next_->__value_;}
658    _LIBCPP_INLINE_VISIBILITY
659    const_reference front() const {return base::__before_begin()->__next_->__value_;}
660
661#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
662#ifndef _LIBCPP_HAS_NO_VARIADICS
663    template <class... _Args> void emplace_front(_Args&&... __args);
664#endif
665    void push_front(value_type&& __v);
666#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
667    void push_front(const value_type& __v);
668
669    void pop_front();
670
671#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
672#ifndef _LIBCPP_HAS_NO_VARIADICS
673    template <class... _Args>
674        iterator emplace_after(const_iterator __p, _Args&&... __args);
675#endif  // _LIBCPP_HAS_NO_VARIADICS
676    iterator insert_after(const_iterator __p, value_type&& __v);
677#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
678    iterator insert_after(const_iterator __p, const value_type& __v);
679    iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
680    template <class _InputIterator>
681        _LIBCPP_INLINE_VISIBILITY
682        typename enable_if
683        <
684            __is_input_iterator<_InputIterator>::value,
685            iterator
686        >::type
687        insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
688#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
689    iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
690        {return insert_after(__p, __il.begin(), __il.end());}
691#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
692
693    iterator erase_after(const_iterator __p);
694    iterator erase_after(const_iterator __f, const_iterator __l);
695
696    _LIBCPP_INLINE_VISIBILITY
697    void swap(forward_list& __x)
698        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
699                   __is_nothrow_swappable<__node_allocator>::value)
700        {base::swap(__x);}
701
702    void resize(size_type __n);
703    void resize(size_type __n, const value_type& __v);
704    _LIBCPP_INLINE_VISIBILITY
705    void clear() _NOEXCEPT {base::clear();}
706
707#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
708    _LIBCPP_INLINE_VISIBILITY
709    void splice_after(const_iterator __p, forward_list&& __x);
710    _LIBCPP_INLINE_VISIBILITY
711    void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
712    _LIBCPP_INLINE_VISIBILITY
713    void splice_after(const_iterator __p, forward_list&& __x,
714                      const_iterator __f, const_iterator __l);
715#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
716    void splice_after(const_iterator __p, forward_list& __x);
717    void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
718    void splice_after(const_iterator __p, forward_list& __x,
719                      const_iterator __f, const_iterator __l);
720    void remove(const value_type& __v);
721    template <class _Predicate> void remove_if(_Predicate __pred);
722    _LIBCPP_INLINE_VISIBILITY
723    void unique() {unique(__equal_to<value_type>());}
724    template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
725#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
726    _LIBCPP_INLINE_VISIBILITY
727    void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
728    template <class _Compare>
729        _LIBCPP_INLINE_VISIBILITY
730        void merge(forward_list&& __x, _Compare __comp)
731        {merge(__x, _VSTD::move(__comp));}
732#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
733    _LIBCPP_INLINE_VISIBILITY
734    void merge(forward_list& __x) {merge(__x, __less<value_type>());}
735    template <class _Compare> void merge(forward_list& __x, _Compare __comp);
736    _LIBCPP_INLINE_VISIBILITY
737    void sort() {sort(__less<value_type>());}
738    template <class _Compare> void sort(_Compare __comp);
739    void reverse() _NOEXCEPT;
740
741private:
742
743#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
744    void __move_assign(forward_list& __x, true_type)
745        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
746    void __move_assign(forward_list& __x, false_type);
747#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
748
749    template <class _Compare>
750        static
751        __node_pointer
752        __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
753
754    template <class _Compare>
755        static
756        __node_pointer
757        __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
758};
759
760template <class _Tp, class _Alloc>
761inline _LIBCPP_INLINE_VISIBILITY
762forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
763    : base(__a)
764{
765}
766
767template <class _Tp, class _Alloc>
768forward_list<_Tp, _Alloc>::forward_list(size_type __n)
769{
770    if (__n > 0)
771    {
772        __node_allocator& __a = base::__alloc();
773        typedef __allocator_destructor<__node_allocator> _D;
774        unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
775        for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
776                                                             __p = __p->__next_)
777        {
778            __h.reset(__node_traits::allocate(__a, 1));
779            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
780            __h->__next_ = nullptr;
781            __p->__next_ = __h.release();
782        }
783    }
784}
785
786template <class _Tp, class _Alloc>
787forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
788{
789    insert_after(cbefore_begin(), __n, __v);
790}
791
792template <class _Tp, class _Alloc>
793forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
794                                        const allocator_type& __a)
795    : base(__a)
796{
797    insert_after(cbefore_begin(), __n, __v);
798}
799
800template <class _Tp, class _Alloc>
801template <class _InputIterator>
802forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
803                                        typename enable_if<
804                                          __is_input_iterator<_InputIterator>::value
805                                        >::type*)
806{
807    insert_after(cbefore_begin(), __f, __l);
808}
809
810template <class _Tp, class _Alloc>
811template <class _InputIterator>
812forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
813                                        const allocator_type& __a,
814                                        typename enable_if<
815                                          __is_input_iterator<_InputIterator>::value
816                                        >::type*)
817    : base(__a)
818{
819    insert_after(cbefore_begin(), __f, __l);
820}
821
822template <class _Tp, class _Alloc>
823forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
824    : base(allocator_type(
825             __node_traits::select_on_container_copy_construction(__x.__alloc())
826                         )
827          )
828{
829    insert_after(cbefore_begin(), __x.begin(), __x.end());
830}
831
832template <class _Tp, class _Alloc>
833forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
834                                        const allocator_type& __a)
835    : base(__a)
836{
837    insert_after(cbefore_begin(), __x.begin(), __x.end());
838}
839
840#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
841
842template <class _Tp, class _Alloc>
843forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
844                                        const allocator_type& __a)
845    : base(_VSTD::move(__x), __a)
846{
847    if (base::__alloc() != __x.__alloc())
848    {
849        typedef move_iterator<iterator> _I;
850        insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
851    }
852}
853
854#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
855
856#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
857
858template <class _Tp, class _Alloc>
859forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
860{
861    insert_after(cbefore_begin(), __il.begin(), __il.end());
862}
863
864template <class _Tp, class _Alloc>
865forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
866                                        const allocator_type& __a)
867    : base(__a)
868{
869    insert_after(cbefore_begin(), __il.begin(), __il.end());
870}
871
872#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
873
874template <class _Tp, class _Alloc>
875forward_list<_Tp, _Alloc>&
876forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
877{
878    if (this != &__x)
879    {
880        base::__copy_assign_alloc(__x);
881        assign(__x.begin(), __x.end());
882    }
883    return *this;
884}
885
886#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
887
888template <class _Tp, class _Alloc>
889void
890forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
891    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
892{
893    clear();
894    base::__move_assign_alloc(__x);
895    base::__before_begin()->__next_ = __x.__before_begin()->__next_;
896    __x.__before_begin()->__next_ = nullptr;
897}
898
899template <class _Tp, class _Alloc>
900void
901forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
902{
903    if (base::__alloc() == __x.__alloc())
904        __move_assign(__x, true_type());
905    else
906    {
907        typedef move_iterator<iterator> _I;
908        assign(_I(__x.begin()), _I(__x.end()));
909    }
910}
911
912template <class _Tp, class _Alloc>
913inline _LIBCPP_INLINE_VISIBILITY
914forward_list<_Tp, _Alloc>&
915forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
916    _NOEXCEPT_(
917             __node_traits::propagate_on_container_move_assignment::value &&
918             is_nothrow_move_assignable<allocator_type>::value)
919{
920    __move_assign(__x, integral_constant<bool,
921          __node_traits::propagate_on_container_move_assignment::value>());
922    return *this;
923}
924
925#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
926
927#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
928
929template <class _Tp, class _Alloc>
930inline _LIBCPP_INLINE_VISIBILITY
931forward_list<_Tp, _Alloc>&
932forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
933{
934    assign(__il.begin(), __il.end());
935    return *this;
936}
937
938#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
939
940template <class _Tp, class _Alloc>
941template <class _InputIterator>
942typename enable_if
943<
944    __is_input_iterator<_InputIterator>::value,
945    void
946>::type
947forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
948{
949    iterator __i = before_begin();
950    iterator __j = _VSTD::next(__i);
951    iterator __e = end();
952    for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
953        *__j = *__f;
954    if (__j == __e)
955        insert_after(__i, __f, __l);
956    else
957        erase_after(__i, __e);
958}
959
960template <class _Tp, class _Alloc>
961void
962forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
963{
964    iterator __i = before_begin();
965    iterator __j = _VSTD::next(__i);
966    iterator __e = end();
967    for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
968        *__j = __v;
969    if (__j == __e)
970        insert_after(__i, __n, __v);
971    else
972        erase_after(__i, __e);
973}
974
975#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
976
977template <class _Tp, class _Alloc>
978inline _LIBCPP_INLINE_VISIBILITY
979void
980forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
981{
982    assign(__il.begin(), __il.end());
983}
984
985#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
986
987#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
988#ifndef _LIBCPP_HAS_NO_VARIADICS
989
990template <class _Tp, class _Alloc>
991template <class... _Args>
992void
993forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
994{
995    __node_allocator& __a = base::__alloc();
996    typedef __allocator_destructor<__node_allocator> _D;
997    unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
998    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
999                                  _VSTD::forward<_Args>(__args)...);
1000    __h->__next_ = base::__before_begin()->__next_;
1001    base::__before_begin()->__next_ = __h.release();
1002}
1003
1004#endif  // _LIBCPP_HAS_NO_VARIADICS
1005
1006template <class _Tp, class _Alloc>
1007void
1008forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1009{
1010    __node_allocator& __a = base::__alloc();
1011    typedef __allocator_destructor<__node_allocator> _D;
1012    unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1013    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1014    __h->__next_ = base::__before_begin()->__next_;
1015    base::__before_begin()->__next_ = __h.release();
1016}
1017
1018#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1019
1020template <class _Tp, class _Alloc>
1021void
1022forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1023{
1024    __node_allocator& __a = base::__alloc();
1025    typedef __allocator_destructor<__node_allocator> _D;
1026    unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1027    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1028    __h->__next_ = base::__before_begin()->__next_;
1029    base::__before_begin()->__next_ = __h.release();
1030}
1031
1032template <class _Tp, class _Alloc>
1033void
1034forward_list<_Tp, _Alloc>::pop_front()
1035{
1036    __node_allocator& __a = base::__alloc();
1037    __node_pointer __p = base::__before_begin()->__next_;
1038    base::__before_begin()->__next_ = __p->__next_;
1039    __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
1040    __node_traits::deallocate(__a, __p, 1);
1041}
1042
1043#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1044#ifndef _LIBCPP_HAS_NO_VARIADICS
1045
1046template <class _Tp, class _Alloc>
1047template <class... _Args>
1048typename forward_list<_Tp, _Alloc>::iterator
1049forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1050{
1051    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1052    __node_allocator& __a = base::__alloc();
1053    typedef __allocator_destructor<__node_allocator> _D;
1054    unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1055    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1056                                  _VSTD::forward<_Args>(__args)...);
1057    __h->__next_ = __r->__next_;
1058    __r->__next_ = __h.release();
1059    return iterator(__r->__next_);
1060}
1061
1062#endif  // _LIBCPP_HAS_NO_VARIADICS
1063
1064template <class _Tp, class _Alloc>
1065typename forward_list<_Tp, _Alloc>::iterator
1066forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1067{
1068    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1069    __node_allocator& __a = base::__alloc();
1070    typedef __allocator_destructor<__node_allocator> _D;
1071    unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1072    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1073    __h->__next_ = __r->__next_;
1074    __r->__next_ = __h.release();
1075    return iterator(__r->__next_);
1076}
1077
1078#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1079
1080template <class _Tp, class _Alloc>
1081typename forward_list<_Tp, _Alloc>::iterator
1082forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1083{
1084    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1085    __node_allocator& __a = base::__alloc();
1086    typedef __allocator_destructor<__node_allocator> _D;
1087    unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1088    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1089    __h->__next_ = __r->__next_;
1090    __r->__next_ = __h.release();
1091    return iterator(__r->__next_);
1092}
1093
1094template <class _Tp, class _Alloc>
1095typename forward_list<_Tp, _Alloc>::iterator
1096forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1097                                        const value_type& __v)
1098{
1099    __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
1100    if (__n > 0)
1101    {
1102        __node_allocator& __a = base::__alloc();
1103        typedef __allocator_destructor<__node_allocator> _D;
1104        unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1105        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1106        __node_pointer __first = __h.release();
1107        __node_pointer __last = __first;
1108#ifndef _LIBCPP_NO_EXCEPTIONS
1109        try
1110        {
1111#endif  // _LIBCPP_NO_EXCEPTIONS
1112            for (--__n; __n != 0; --__n, __last = __last->__next_)
1113            {
1114                __h.reset(__node_traits::allocate(__a, 1));
1115                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1116                __last->__next_ = __h.release();
1117            }
1118#ifndef _LIBCPP_NO_EXCEPTIONS
1119        }
1120        catch (...)
1121        {
1122            while (__first != nullptr)
1123            {
1124                __node_pointer __next = __first->__next_;
1125                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1126                __node_traits::deallocate(__a, __first, 1);
1127                __first = __next;
1128            }
1129            throw;
1130        }
1131#endif  // _LIBCPP_NO_EXCEPTIONS
1132        __last->__next_ = __r->__next_;
1133        __r->__next_ = __first;
1134        __r = __last;
1135    }
1136    return iterator(__r);
1137}
1138
1139template <class _Tp, class _Alloc>
1140template <class _InputIterator>
1141typename enable_if
1142<
1143    __is_input_iterator<_InputIterator>::value,
1144    typename forward_list<_Tp, _Alloc>::iterator
1145>::type
1146forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1147                                        _InputIterator __f, _InputIterator __l)
1148{
1149    __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
1150    if (__f != __l)
1151    {
1152        __node_allocator& __a = base::__alloc();
1153        typedef __allocator_destructor<__node_allocator> _D;
1154        unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1155        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1156        __node_pointer __first = __h.release();
1157        __node_pointer __last = __first;
1158#ifndef _LIBCPP_NO_EXCEPTIONS
1159        try
1160        {
1161#endif  // _LIBCPP_NO_EXCEPTIONS
1162            for (++__f; __f != __l; ++__f, __last = __last->__next_)
1163            {
1164                __h.reset(__node_traits::allocate(__a, 1));
1165                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1166                __last->__next_ = __h.release();
1167            }
1168#ifndef _LIBCPP_NO_EXCEPTIONS
1169        }
1170        catch (...)
1171        {
1172            while (__first != nullptr)
1173            {
1174                __node_pointer __next = __first->__next_;
1175                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1176                __node_traits::deallocate(__a, __first, 1);
1177                __first = __next;
1178            }
1179            throw;
1180        }
1181#endif  // _LIBCPP_NO_EXCEPTIONS
1182        __last->__next_ = __r->__next_;
1183        __r->__next_ = __first;
1184        __r = __last;
1185    }
1186    return iterator(__r);
1187}
1188
1189template <class _Tp, class _Alloc>
1190typename forward_list<_Tp, _Alloc>::iterator
1191forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1192{
1193    __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1194    __node_pointer __n = __p->__next_;
1195    __p->__next_ = __n->__next_;
1196    __node_allocator& __a = base::__alloc();
1197    __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1198    __node_traits::deallocate(__a, __n, 1);
1199    return iterator(__p->__next_);
1200}
1201
1202template <class _Tp, class _Alloc>
1203typename forward_list<_Tp, _Alloc>::iterator
1204forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1205{
1206    __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
1207    if (__f != __l)
1208    {
1209        __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1210        __node_pointer __n = __p->__next_;
1211        if (__n != __e)
1212        {
1213            __p->__next_ = __e;
1214            __node_allocator& __a = base::__alloc();
1215            do
1216            {
1217                __p = __n->__next_;
1218                __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1219                __node_traits::deallocate(__a, __n, 1);
1220                __n = __p;
1221            } while (__n != __e);
1222        }
1223    }
1224    return iterator(__e);
1225}
1226
1227template <class _Tp, class _Alloc>
1228void
1229forward_list<_Tp, _Alloc>::resize(size_type __n)
1230{
1231    size_type __sz = 0;
1232    iterator __p = before_begin();
1233    iterator __i = begin();
1234    iterator __e = end();
1235    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1236        ;
1237    if (__i != __e)
1238        erase_after(__p, __e);
1239    else
1240    {
1241        __n -= __sz;
1242        if (__n > 0)
1243        {
1244            __node_allocator& __a = base::__alloc();
1245            typedef __allocator_destructor<__node_allocator> _D;
1246            unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1247            for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1248                                                         __ptr = __ptr->__next_)
1249            {
1250                __h.reset(__node_traits::allocate(__a, 1));
1251                __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
1252                __h->__next_ = nullptr;
1253                __ptr->__next_ = __h.release();
1254            }
1255        }
1256    }
1257}
1258
1259template <class _Tp, class _Alloc>
1260void
1261forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1262{
1263    size_type __sz = 0;
1264    iterator __p = before_begin();
1265    iterator __i = begin();
1266    iterator __e = end();
1267    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1268        ;
1269    if (__i != __e)
1270        erase_after(__p, __e);
1271    else
1272    {
1273        __n -= __sz;
1274        if (__n > 0)
1275        {
1276            __node_allocator& __a = base::__alloc();
1277            typedef __allocator_destructor<__node_allocator> _D;
1278            unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1279            for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1280                                                         __ptr = __ptr->__next_)
1281            {
1282                __h.reset(__node_traits::allocate(__a, 1));
1283                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1284                __h->__next_ = nullptr;
1285                __ptr->__next_ = __h.release();
1286            }
1287        }
1288    }
1289}
1290
1291template <class _Tp, class _Alloc>
1292void
1293forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1294                                        forward_list& __x)
1295{
1296    if (!__x.empty())
1297    {
1298        if (__p.__ptr_->__next_ != nullptr)
1299        {
1300            const_iterator __lm1 = __x.before_begin();
1301            while (__lm1.__ptr_->__next_ != nullptr)
1302                ++__lm1;
1303            const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1304                const_cast<__node_pointer>(__p.__ptr_)->__next_;
1305        }
1306        const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1307            const_cast<__node_pointer>(__x.__before_begin())->__next_;
1308        const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1309    }
1310}
1311
1312template <class _Tp, class _Alloc>
1313void
1314forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1315                                        forward_list& __x,
1316                                        const_iterator __i)
1317{
1318    const_iterator __lm1 = _VSTD::next(__i);
1319    if (__p != __i && __p != __lm1)
1320    {
1321        const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1322            const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1323        const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1324            const_cast<__node_pointer>(__p.__ptr_)->__next_;
1325        const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1326            const_cast<__node_pointer>(__lm1.__ptr_);
1327    }
1328}
1329
1330template <class _Tp, class _Alloc>
1331void
1332forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1333                                        forward_list& __x,
1334                                        const_iterator __f, const_iterator __l)
1335{
1336    if (__f != __l && __p != __f)
1337    {
1338        const_iterator __lm1 = __f;
1339        while (__lm1.__ptr_->__next_ != __l.__ptr_)
1340            ++__lm1;
1341        if (__f != __lm1)
1342        {
1343            const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1344                const_cast<__node_pointer>(__p.__ptr_)->__next_;
1345            const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1346                const_cast<__node_pointer>(__f.__ptr_)->__next_;
1347            const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1348                const_cast<__node_pointer>(__l.__ptr_);
1349        }
1350    }
1351}
1352
1353#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1354
1355template <class _Tp, class _Alloc>
1356inline _LIBCPP_INLINE_VISIBILITY
1357void
1358forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1359                                        forward_list&& __x)
1360{
1361    splice_after(__p, __x);
1362}
1363
1364template <class _Tp, class _Alloc>
1365inline _LIBCPP_INLINE_VISIBILITY
1366void
1367forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1368                                        forward_list&& __x,
1369                                        const_iterator __i)
1370{
1371    splice_after(__p, __x, __i);
1372}
1373
1374template <class _Tp, class _Alloc>
1375inline _LIBCPP_INLINE_VISIBILITY
1376void
1377forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1378                                        forward_list&& __x,
1379                                        const_iterator __f, const_iterator __l)
1380{
1381    splice_after(__p, __x, __f, __l);
1382}
1383
1384#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1385
1386template <class _Tp, class _Alloc>
1387void
1388forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1389{
1390    iterator __e = end();
1391    for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1392    {
1393        if (__i.__ptr_->__next_->__value_ == __v)
1394        {
1395            iterator __j = _VSTD::next(__i, 2);
1396            for (; __j != __e && *__j == __v; ++__j)
1397                ;
1398            erase_after(__i, __j);
1399            if (__j == __e)
1400                break;
1401            __i = __j;
1402        }
1403        else
1404            ++__i;
1405    }
1406}
1407
1408template <class _Tp, class _Alloc>
1409template <class _Predicate>
1410void
1411forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1412{
1413    iterator __e = end();
1414    for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1415    {
1416        if (__pred(__i.__ptr_->__next_->__value_))
1417        {
1418            iterator __j = _VSTD::next(__i, 2);
1419            for (; __j != __e && __pred(*__j); ++__j)
1420                ;
1421            erase_after(__i, __j);
1422            if (__j == __e)
1423                break;
1424            __i = __j;
1425        }
1426        else
1427            ++__i;
1428    }
1429}
1430
1431template <class _Tp, class _Alloc>
1432template <class _BinaryPredicate>
1433void
1434forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1435{
1436    for (iterator __i = begin(), __e = end(); __i != __e;)
1437    {
1438        iterator __j = _VSTD::next(__i);
1439        for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1440            ;
1441        if (__i.__ptr_->__next_ != __j.__ptr_)
1442            erase_after(__i, __j);
1443        __i = __j;
1444    }
1445}
1446
1447template <class _Tp, class _Alloc>
1448template <class _Compare>
1449void
1450forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1451{
1452    if (this != &__x)
1453    {
1454        base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1455                                                    __x.__before_begin()->__next_,
1456                                                    __comp);
1457        __x.__before_begin()->__next_ = nullptr;
1458    }
1459}
1460
1461template <class _Tp, class _Alloc>
1462template <class _Compare>
1463typename forward_list<_Tp, _Alloc>::__node_pointer
1464forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1465                                   _Compare& __comp)
1466{
1467    if (__f1 == nullptr)
1468        return __f2;
1469    if (__f2 == nullptr)
1470        return __f1;
1471    __node_pointer __r;
1472    if (__comp(__f2->__value_, __f1->__value_))
1473    {
1474        __node_pointer __t = __f2;
1475        while (__t->__next_ != nullptr &&
1476                             __comp(__t->__next_->__value_, __f1->__value_))
1477            __t = __t->__next_;
1478        __r = __f2;
1479        __f2 = __t->__next_;
1480        __t->__next_ = __f1;
1481    }
1482    else
1483        __r = __f1;
1484    __node_pointer __p = __f1;
1485    __f1 = __f1->__next_;
1486    while (__f1 != nullptr && __f2 != nullptr)
1487    {
1488        if (__comp(__f2->__value_, __f1->__value_))
1489        {
1490            __node_pointer __t = __f2;
1491            while (__t->__next_ != nullptr &&
1492                                 __comp(__t->__next_->__value_, __f1->__value_))
1493                __t = __t->__next_;
1494            __p->__next_ = __f2;
1495            __f2 = __t->__next_;
1496            __t->__next_ = __f1;
1497        }
1498        __p = __f1;
1499        __f1 = __f1->__next_;
1500    }
1501    if (__f2 != nullptr)
1502        __p->__next_ = __f2;
1503    return __r;
1504}
1505
1506template <class _Tp, class _Alloc>
1507template <class _Compare>
1508inline _LIBCPP_INLINE_VISIBILITY
1509void
1510forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1511{
1512    base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1513                                       _VSTD::distance(begin(), end()), __comp);
1514}
1515
1516template <class _Tp, class _Alloc>
1517template <class _Compare>
1518typename forward_list<_Tp, _Alloc>::__node_pointer
1519forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1520                                  _Compare& __comp)
1521{
1522    switch (__sz)
1523    {
1524    case 0:
1525    case 1:
1526        return __f1;
1527    case 2:
1528        if (__comp(__f1->__next_->__value_, __f1->__value_))
1529        {
1530            __node_pointer __t = __f1->__next_;
1531            __t->__next_ = __f1;
1532            __f1->__next_ = nullptr;
1533            __f1 = __t;
1534        }
1535        return __f1;
1536    }
1537    difference_type __sz1 = __sz / 2;
1538    difference_type __sz2 = __sz - __sz1;
1539    __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;
1540    __node_pointer __f2 = __t->__next_;
1541    __t->__next_ = nullptr;
1542    return __merge(__sort(__f1, __sz1, __comp),
1543                   __sort(__f2, __sz2, __comp), __comp);
1544}
1545
1546template <class _Tp, class _Alloc>
1547void
1548forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
1549{
1550    __node_pointer __p = base::__before_begin()->__next_;
1551    if (__p != nullptr)
1552    {
1553        __node_pointer __f = __p->__next_;
1554        __p->__next_ = nullptr;
1555        while (__f != nullptr)
1556        {
1557            __node_pointer __t = __f->__next_;
1558            __f->__next_ = __p;
1559            __p = __f;
1560            __f = __t;
1561        }
1562        base::__before_begin()->__next_ = __p;
1563    }
1564}
1565
1566template <class _Tp, class _Alloc>
1567bool operator==(const forward_list<_Tp, _Alloc>& __x,
1568                const forward_list<_Tp, _Alloc>& __y)
1569{
1570    typedef forward_list<_Tp, _Alloc> _C;
1571    typedef typename _C::const_iterator _I;
1572    _I __ix = __x.begin();
1573    _I __ex = __x.end();
1574    _I __iy = __y.begin();
1575    _I __ey = __y.end();
1576    for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1577        if (!(*__ix == *__iy))
1578            return false;
1579    return (__ix == __ex) == (__iy == __ey);
1580}
1581
1582template <class _Tp, class _Alloc>
1583inline _LIBCPP_INLINE_VISIBILITY
1584bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1585                const forward_list<_Tp, _Alloc>& __y)
1586{
1587    return !(__x == __y);
1588}
1589
1590template <class _Tp, class _Alloc>
1591inline _LIBCPP_INLINE_VISIBILITY
1592bool operator< (const forward_list<_Tp, _Alloc>& __x,
1593                const forward_list<_Tp, _Alloc>& __y)
1594{
1595    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
1596                                         __y.begin(), __y.end());
1597}
1598
1599template <class _Tp, class _Alloc>
1600inline _LIBCPP_INLINE_VISIBILITY
1601bool operator> (const forward_list<_Tp, _Alloc>& __x,
1602                const forward_list<_Tp, _Alloc>& __y)
1603{
1604    return __y < __x;
1605}
1606
1607template <class _Tp, class _Alloc>
1608inline _LIBCPP_INLINE_VISIBILITY
1609bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1610                const forward_list<_Tp, _Alloc>& __y)
1611{
1612    return !(__x < __y);
1613}
1614
1615template <class _Tp, class _Alloc>
1616inline _LIBCPP_INLINE_VISIBILITY
1617bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1618                const forward_list<_Tp, _Alloc>& __y)
1619{
1620    return !(__y < __x);
1621}
1622
1623template <class _Tp, class _Alloc>
1624inline _LIBCPP_INLINE_VISIBILITY
1625void
1626swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1627    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1628{
1629    __x.swap(__y);
1630}
1631
1632_LIBCPP_END_NAMESPACE_STD
1633
1634#endif  // _LIBCPP_FORWARD_LIST
1635