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