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