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