btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / libc++ / forward_list
blob8a87fc5e1f26adb3f2ec318b93ea6ca78d722d7e
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 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_FORWARD_LIST
12 #define _LIBCPP_FORWARD_LIST
15     forward_list synopsis
17 namespace std
20 template <class T, class Allocator = allocator<T>>
21 class forward_list
23 public:
24     typedef T         value_type;
25     typedef Allocator allocator_type;
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;
34     typedef <details> iterator;
35     typedef <details> const_iterator;
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);
56     ~forward_list();
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);
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);
70     allocator_type get_allocator() const noexcept;
72     iterator       begin() noexcept;
73     const_iterator begin() const noexcept;
74     iterator       end() noexcept;
75     const_iterator end() const noexcept;
77     const_iterator cbegin() const noexcept;
78     const_iterator cend() const noexcept;
80     iterator       before_begin() noexcept;
81     const_iterator before_begin() const noexcept;
82     const_iterator cbefore_begin() const noexcept;
84     bool empty() const noexcept;
85     size_type max_size() const noexcept;
87     reference       front();
88     const_reference front() const;
90     template <class... Args> void emplace_front(Args&&... args);
91     void push_front(const value_type& v);
92     void push_front(value_type&& v);
94     void pop_front();
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);
106     iterator erase_after(const_iterator p);
107     iterator erase_after(const_iterator first, const_iterator last);
109     void swap(forward_list& x)
110         noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
112     void resize(size_type n);
113     void resize(size_type n, const value_type& v);
114     void clear() noexcept;
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;
137 template <class T, class Allocator>
138     bool operator==(const forward_list<T, Allocator>& x,
139                     const forward_list<T, Allocator>& y);
141 template <class T, class Allocator>
142     bool operator< (const forward_list<T, Allocator>& x,
143                     const forward_list<T, Allocator>& y);
145 template <class T, class Allocator>
146     bool operator!=(const forward_list<T, Allocator>& x,
147                     const forward_list<T, Allocator>& y);
149 template <class T, class Allocator>
150     bool operator> (const forward_list<T, Allocator>& x,
151                     const forward_list<T, Allocator>& y);
153 template <class T, class Allocator>
154     bool operator>=(const forward_list<T, Allocator>& x,
155                     const forward_list<T, Allocator>& y);
157 template <class T, class Allocator>
158     bool operator<=(const forward_list<T, Allocator>& x,
159                     const forward_list<T, Allocator>& y);
161 template <class T, class Allocator>
162     void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
163          noexcept(noexcept(x.swap(y)));
165 }  // std
169 #include <__config>
171 #include <initializer_list>
172 #include <memory>
173 #include <limits>
174 #include <iterator>
175 #include <algorithm>
177 #include <__undef_min_max>
179 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
180 #pragma GCC system_header
181 #endif
183 _LIBCPP_BEGIN_NAMESPACE_STD
185 template <class _Tp, class _VoidPtr> struct __forward_list_node;
187 template <class _NodePtr>
188 struct __forward_begin_node
190     typedef _NodePtr pointer;
192     pointer __next_;
194      _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
197 template <class _Tp, class _VoidPtr>
198 struct _LIBCPP_HIDDEN __begin_node_of
200     typedef __forward_begin_node
201         <
202              typename pointer_traits<_VoidPtr>::template
203 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
204                  rebind<__forward_list_node<_Tp, _VoidPtr> >
205 #else
206                  rebind<__forward_list_node<_Tp, _VoidPtr> >::other
207 #endif
208          > type;
211 template <class _Tp, class _VoidPtr>
212 struct __forward_list_node
213     : public __begin_node_of<_Tp, _VoidPtr>::type
215     typedef _Tp value_type;
217     value_type __value_;
220 template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY forward_list;
221 template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
223 template <class _NodePtr>
224 class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator
226     typedef _NodePtr __node_pointer;
228     __node_pointer __ptr_;
230     _LIBCPP_INLINE_VISIBILITY
231     explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
233     template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list;
234     template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
236 public:
237     typedef forward_iterator_tag                              iterator_category;
238     typedef typename pointer_traits<__node_pointer>::element_type::value_type
239                                                               value_type;
240     typedef value_type&                                       reference;
241     typedef typename pointer_traits<__node_pointer>::difference_type
242                                                               difference_type;
243     typedef typename pointer_traits<__node_pointer>::template
244 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
245             rebind<value_type>
246 #else
247             rebind<value_type>::other
248 #endif
249                                                               pointer;
251     _LIBCPP_INLINE_VISIBILITY
252     __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
254     _LIBCPP_INLINE_VISIBILITY
255     reference operator*() const {return __ptr_->__value_;}
256     _LIBCPP_INLINE_VISIBILITY
257     pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
259     _LIBCPP_INLINE_VISIBILITY
260     __forward_list_iterator& operator++()
261     {
262         __ptr_ = __ptr_->__next_;
263         return *this;
264     }
265     _LIBCPP_INLINE_VISIBILITY
266     __forward_list_iterator operator++(int)
267     {
268         __forward_list_iterator __t(*this);
269         ++(*this);
270         return __t;
271     }
273     friend _LIBCPP_INLINE_VISIBILITY
274     bool operator==(const __forward_list_iterator& __x,
275                     const __forward_list_iterator& __y)
276         {return __x.__ptr_ == __y.__ptr_;}
277     friend _LIBCPP_INLINE_VISIBILITY
278     bool operator!=(const __forward_list_iterator& __x,
279                     const __forward_list_iterator& __y)
280         {return !(__x == __y);}
283 template <class _NodeConstPtr>
284 class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator
286     typedef _NodeConstPtr __node_const_pointer;
288     __node_const_pointer __ptr_;
290     _LIBCPP_INLINE_VISIBILITY
291     explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
292         : __ptr_(__p) {}
294     typedef typename remove_const
295         <
296             typename pointer_traits<__node_const_pointer>::element_type
297         >::type                                               __node;
298     typedef typename pointer_traits<__node_const_pointer>::template
299 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
300             rebind<__node>
301 #else
302             rebind<__node>::other
303 #endif
304                                                               __node_pointer;
306     template<class, class> friend class forward_list;
308 public:
309     typedef forward_iterator_tag                              iterator_category;
310     typedef typename __node::value_type                       value_type;
311     typedef const value_type&                                 reference;
312     typedef typename pointer_traits<__node_const_pointer>::difference_type
313                                                               difference_type;
314     typedef typename pointer_traits<__node_const_pointer>::template
315 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
316             rebind<const value_type>
317 #else
318             rebind<const value_type>::other
319 #endif
320                                                               pointer;
322     _LIBCPP_INLINE_VISIBILITY
323     __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
324     _LIBCPP_INLINE_VISIBILITY
325     __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
326         : __ptr_(__p.__ptr_) {}
328     _LIBCPP_INLINE_VISIBILITY
329     reference operator*() const {return __ptr_->__value_;}
330     _LIBCPP_INLINE_VISIBILITY
331     pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
333     _LIBCPP_INLINE_VISIBILITY
334     __forward_list_const_iterator& operator++()
335     {
336         __ptr_ = __ptr_->__next_;
337         return *this;
338     }
339     _LIBCPP_INLINE_VISIBILITY
340     __forward_list_const_iterator operator++(int)
341     {
342         __forward_list_const_iterator __t(*this);
343         ++(*this);
344         return __t;
345     }
347     friend _LIBCPP_INLINE_VISIBILITY
348     bool operator==(const __forward_list_const_iterator& __x,
349                     const __forward_list_const_iterator& __y)
350         {return __x.__ptr_ == __y.__ptr_;}
351     friend _LIBCPP_INLINE_VISIBILITY
352     bool operator!=(const __forward_list_const_iterator& __x,
353                            const __forward_list_const_iterator& __y)
354         {return !(__x == __y);}
357 template <class _Tp, class _Alloc>
358 class __forward_list_base
360 protected:
361     typedef _Tp    value_type;
362     typedef _Alloc allocator_type;
364     typedef typename allocator_traits<allocator_type>::void_pointer  void_pointer;
365     typedef __forward_list_node<value_type, void_pointer>            __node;
366     typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
367     typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
368     typedef allocator_traits<__node_allocator>        __node_traits;
369     typedef typename __node_traits::pointer           __node_pointer;
370     typedef typename __node_traits::pointer           __node_const_pointer;
372     typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __begin_node>::type __begin_node_allocator;
373     typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
375     __compressed_pair<__begin_node, __node_allocator> __before_begin_;
377     _LIBCPP_INLINE_VISIBILITY
378     __node_pointer        __before_begin() _NOEXCEPT
379         {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>::
380                                         pointer_to(__before_begin_.first()));}
381     _LIBCPP_INLINE_VISIBILITY
382     __node_const_pointer  __before_begin() const _NOEXCEPT
383         {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>::
384                                         pointer_to(const_cast<__begin_node&>(__before_begin_.first())));}
386     _LIBCPP_INLINE_VISIBILITY
387           __node_allocator& __alloc() _NOEXCEPT
388             {return __before_begin_.second();}
389     _LIBCPP_INLINE_VISIBILITY
390     const __node_allocator& __alloc() const _NOEXCEPT
391         {return __before_begin_.second();}
393     typedef __forward_list_iterator<__node_pointer>             iterator;
394     typedef __forward_list_const_iterator<__node_pointer>       const_iterator;
396     _LIBCPP_INLINE_VISIBILITY
397     __forward_list_base()
398         _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
399         : __before_begin_(__begin_node()) {}
400     _LIBCPP_INLINE_VISIBILITY
401     __forward_list_base(const allocator_type& __a)
402         : __before_begin_(__begin_node(), __node_allocator(__a)) {}
404 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
405 public:
406     __forward_list_base(__forward_list_base&& __x)
407         _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
408     __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
409 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
411 private:
412     __forward_list_base(const __forward_list_base&);
413     __forward_list_base& operator=(const __forward_list_base&);
415 public:
416     ~__forward_list_base();
418 protected:
419     _LIBCPP_INLINE_VISIBILITY
420     void __copy_assign_alloc(const __forward_list_base& __x)
421         {__copy_assign_alloc(__x, integral_constant<bool,
422               __node_traits::propagate_on_container_copy_assignment::value>());}
424     _LIBCPP_INLINE_VISIBILITY
425     void __move_assign_alloc(__forward_list_base& __x)
426         _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
427                    is_nothrow_move_assignable<__node_allocator>::value)
428         {__move_assign_alloc(__x, integral_constant<bool,
429               __node_traits::propagate_on_container_move_assignment::value>());}
431 public:
432     void swap(__forward_list_base& __x)
433 #if _LIBCPP_STD_VER >= 14
434         _NOEXCEPT;
435 #else
436         _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || 
437                     __is_nothrow_swappable<__node_allocator>::value);
438 #endif
439 protected:
440     void clear() _NOEXCEPT;
442 private:
443     _LIBCPP_INLINE_VISIBILITY
444     void __copy_assign_alloc(const __forward_list_base&, false_type) {}
445     _LIBCPP_INLINE_VISIBILITY
446     void __copy_assign_alloc(const __forward_list_base& __x, true_type)
447     {
448         if (__alloc() != __x.__alloc())
449             clear();
450         __alloc() = __x.__alloc();
451     }
453     _LIBCPP_INLINE_VISIBILITY
454     void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
455         {}
456     _LIBCPP_INLINE_VISIBILITY
457     void __move_assign_alloc(__forward_list_base& __x, true_type)
458         _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
459         {__alloc() = _VSTD::move(__x.__alloc());}
462 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
464 template <class _Tp, class _Alloc>
465 inline _LIBCPP_INLINE_VISIBILITY
466 __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
467         _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
468     : __before_begin_(_VSTD::move(__x.__before_begin_))
470     __x.__before_begin()->__next_ = nullptr;
473 template <class _Tp, class _Alloc>
474 inline _LIBCPP_INLINE_VISIBILITY
475 __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
476                                                       const allocator_type& __a)
477     : __before_begin_(__begin_node(), __node_allocator(__a))
479     if (__alloc() == __x.__alloc())
480     {
481         __before_begin()->__next_ = __x.__before_begin()->__next_;
482         __x.__before_begin()->__next_ = nullptr;
483     }
486 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
488 template <class _Tp, class _Alloc>
489 __forward_list_base<_Tp, _Alloc>::~__forward_list_base()
491     clear();
494 template <class _Tp, class _Alloc>
495 inline _LIBCPP_INLINE_VISIBILITY
496 void
497 __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
498 #if _LIBCPP_STD_VER >= 14
499         _NOEXCEPT
500 #else
501         _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value || 
502                     __is_nothrow_swappable<__node_allocator>::value)
503 #endif
505     __swap_allocator(__alloc(), __x.__alloc(), 
506             integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
507     using _VSTD::swap;
508     swap(__before_begin()->__next_, __x.__before_begin()->__next_);
511 template <class _Tp, class _Alloc>
512 void
513 __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
515     __node_allocator& __a = __alloc();
516     for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
517     {
518         __node_pointer __next = __p->__next_;
519         __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
520         __node_traits::deallocate(__a, __p, 1);
521         __p = __next;
522     }
523     __before_begin()->__next_ = nullptr;
526 template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
527 class _LIBCPP_TYPE_VIS_ONLY forward_list
528     : private __forward_list_base<_Tp, _Alloc>
530     typedef __forward_list_base<_Tp, _Alloc> base;
531     typedef typename base::__node_allocator  __node_allocator;
532     typedef typename base::__node            __node;
533     typedef typename base::__node_traits     __node_traits;
534     typedef typename base::__node_pointer    __node_pointer;
536 public:
537     typedef _Tp    value_type;
538     typedef _Alloc allocator_type;
540     typedef value_type&                                                reference;
541     typedef const value_type&                                          const_reference;
542     typedef typename allocator_traits<allocator_type>::pointer         pointer;
543     typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
544     typedef typename allocator_traits<allocator_type>::size_type       size_type;
545     typedef typename allocator_traits<allocator_type>::difference_type difference_type;
547     typedef typename base::iterator       iterator;
548     typedef typename base::const_iterator const_iterator;
550     _LIBCPP_INLINE_VISIBILITY
551     forward_list()
552         _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
553         {} // = default;
554     explicit forward_list(const allocator_type& __a);
555     explicit forward_list(size_type __n);
556 #if _LIBCPP_STD_VER > 11
557     explicit forward_list(size_type __n, const allocator_type& __a);
558 #endif
559     forward_list(size_type __n, const value_type& __v);
560     forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
561     template <class _InputIterator>
562         forward_list(_InputIterator __f, _InputIterator __l,
563                      typename enable_if<
564                        __is_input_iterator<_InputIterator>::value
565                      >::type* = nullptr);
566     template <class _InputIterator>
567         forward_list(_InputIterator __f, _InputIterator __l,
568                      const allocator_type& __a,
569                      typename enable_if<
570                        __is_input_iterator<_InputIterator>::value
571                      >::type* = nullptr);
572     forward_list(const forward_list& __x);
573     forward_list(const forward_list& __x, const allocator_type& __a);
574 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
575     _LIBCPP_INLINE_VISIBILITY
576     forward_list(forward_list&& __x)
577         _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
578         : base(_VSTD::move(__x)) {}
579     forward_list(forward_list&& __x, const allocator_type& __a);
580 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
581 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
582     forward_list(initializer_list<value_type> __il);
583     forward_list(initializer_list<value_type> __il, const allocator_type& __a);
584 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
586     // ~forward_list() = default;
588     forward_list& operator=(const forward_list& __x);
589 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
590     forward_list& operator=(forward_list&& __x)
591         _NOEXCEPT_(
592              __node_traits::propagate_on_container_move_assignment::value &&
593              is_nothrow_move_assignable<allocator_type>::value);
594 #endif
595 #ifndef  _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
596     forward_list& operator=(initializer_list<value_type> __il);
597 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
599     template <class _InputIterator>
600         typename enable_if
601         <
602             __is_input_iterator<_InputIterator>::value,
603             void
604         >::type
605         assign(_InputIterator __f, _InputIterator __l);
606     void assign(size_type __n, const value_type& __v);
607 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
608     void assign(initializer_list<value_type> __il);
609 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
611     _LIBCPP_INLINE_VISIBILITY
612     allocator_type get_allocator() const _NOEXCEPT
613         {return allocator_type(base::__alloc());}
615     _LIBCPP_INLINE_VISIBILITY
616     iterator       begin() _NOEXCEPT
617         {return       iterator(base::__before_begin()->__next_);}
618     _LIBCPP_INLINE_VISIBILITY
619     const_iterator begin() const _NOEXCEPT
620         {return const_iterator(base::__before_begin()->__next_);}
621     _LIBCPP_INLINE_VISIBILITY
622     iterator       end() _NOEXCEPT
623         {return       iterator(nullptr);}
624     _LIBCPP_INLINE_VISIBILITY
625     const_iterator end() const _NOEXCEPT
626         {return const_iterator(nullptr);}
628     _LIBCPP_INLINE_VISIBILITY
629     const_iterator cbegin() const _NOEXCEPT
630         {return const_iterator(base::__before_begin()->__next_);}
631     _LIBCPP_INLINE_VISIBILITY
632     const_iterator cend() const _NOEXCEPT
633         {return const_iterator(nullptr);}
635     _LIBCPP_INLINE_VISIBILITY
636     iterator       before_begin() _NOEXCEPT
637         {return       iterator(base::__before_begin());}
638     _LIBCPP_INLINE_VISIBILITY
639     const_iterator before_begin() const _NOEXCEPT
640         {return const_iterator(base::__before_begin());}
641     _LIBCPP_INLINE_VISIBILITY
642     const_iterator cbefore_begin() const _NOEXCEPT
643         {return const_iterator(base::__before_begin());}
645     _LIBCPP_INLINE_VISIBILITY
646     bool empty() const _NOEXCEPT
647         {return base::__before_begin()->__next_ == nullptr;}
648     _LIBCPP_INLINE_VISIBILITY
649     size_type max_size() const _NOEXCEPT
650         {return numeric_limits<size_type>::max();}
652     _LIBCPP_INLINE_VISIBILITY
653     reference       front()       {return base::__before_begin()->__next_->__value_;}
654     _LIBCPP_INLINE_VISIBILITY
655     const_reference front() const {return base::__before_begin()->__next_->__value_;}
657 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
658 #ifndef _LIBCPP_HAS_NO_VARIADICS
659     template <class... _Args> void emplace_front(_Args&&... __args);
660 #endif
661     void push_front(value_type&& __v);
662 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
663     void push_front(const value_type& __v);
665     void pop_front();
667 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
668 #ifndef _LIBCPP_HAS_NO_VARIADICS
669     template <class... _Args>
670         iterator emplace_after(const_iterator __p, _Args&&... __args);
671 #endif  // _LIBCPP_HAS_NO_VARIADICS
672     iterator insert_after(const_iterator __p, value_type&& __v);
673 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
674     iterator insert_after(const_iterator __p, const value_type& __v);
675     iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
676     template <class _InputIterator>
677         _LIBCPP_INLINE_VISIBILITY
678         typename enable_if
679         <
680             __is_input_iterator<_InputIterator>::value,
681             iterator
682         >::type
683         insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
684 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
685     iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
686         {return insert_after(__p, __il.begin(), __il.end());}
687 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
689     iterator erase_after(const_iterator __p);
690     iterator erase_after(const_iterator __f, const_iterator __l);
692     _LIBCPP_INLINE_VISIBILITY
693     void swap(forward_list& __x)
694 #if _LIBCPP_STD_VER >= 14
695         _NOEXCEPT
696 #else
697         _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
698                    __is_nothrow_swappable<__node_allocator>::value)
699 #endif
700         {base::swap(__x);}
702     void resize(size_type __n);
703     void resize(size_type __n, const value_type& __v);
704     _LIBCPP_INLINE_VISIBILITY
705     void clear() _NOEXCEPT {base::clear();}
707 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
708     _LIBCPP_INLINE_VISIBILITY
709     void splice_after(const_iterator __p, forward_list&& __x);
710     _LIBCPP_INLINE_VISIBILITY
711     void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
712     _LIBCPP_INLINE_VISIBILITY
713     void splice_after(const_iterator __p, forward_list&& __x,
714                       const_iterator __f, const_iterator __l);
715 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
716     void splice_after(const_iterator __p, forward_list& __x);
717     void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
718     void splice_after(const_iterator __p, forward_list& __x,
719                       const_iterator __f, const_iterator __l);
720     void remove(const value_type& __v);
721     template <class _Predicate> void remove_if(_Predicate __pred);
722     _LIBCPP_INLINE_VISIBILITY
723     void unique() {unique(__equal_to<value_type>());}
724     template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
725 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
726     _LIBCPP_INLINE_VISIBILITY
727     void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
728     template <class _Compare>
729         _LIBCPP_INLINE_VISIBILITY
730         void merge(forward_list&& __x, _Compare __comp)
731         {merge(__x, _VSTD::move(__comp));}
732 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
733     _LIBCPP_INLINE_VISIBILITY
734     void merge(forward_list& __x) {merge(__x, __less<value_type>());}
735     template <class _Compare> void merge(forward_list& __x, _Compare __comp);
736     _LIBCPP_INLINE_VISIBILITY
737     void sort() {sort(__less<value_type>());}
738     template <class _Compare> void sort(_Compare __comp);
739     void reverse() _NOEXCEPT;
741 private:
743 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
744     void __move_assign(forward_list& __x, true_type)
745         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
746     void __move_assign(forward_list& __x, false_type);
747 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
749     template <class _Compare>
750         static
751         __node_pointer
752         __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
754     template <class _Compare>
755         static
756         __node_pointer
757         __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
760 template <class _Tp, class _Alloc>
761 inline _LIBCPP_INLINE_VISIBILITY
762 forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
763     : base(__a)
767 template <class _Tp, class _Alloc>
768 forward_list<_Tp, _Alloc>::forward_list(size_type __n)
770     if (__n > 0)
771     {
772         __node_allocator& __a = base::__alloc();
773         typedef __allocator_destructor<__node_allocator> _Dp;
774         unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
775         for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
776                                                              __p = __p->__next_)
777         {
778             __h.reset(__node_traits::allocate(__a, 1));
779             __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
780             __h->__next_ = nullptr;
781             __p->__next_ = __h.release();
782         }
783     }
786 #if _LIBCPP_STD_VER > 11
787 template <class _Tp, class _Alloc>
788 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a)
789     : base ( __a )
791     if (__n > 0)
792     {
793         __node_allocator& __a = base::__alloc();
794         typedef __allocator_destructor<__node_allocator> _Dp;
795         unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
796         for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
797                                                              __p = __p->__next_)
798         {
799             __h.reset(__node_traits::allocate(__a, 1));
800             __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
801             __h->__next_ = nullptr;
802             __p->__next_ = __h.release();
803         }
804     }
806 #endif
808 template <class _Tp, class _Alloc>
809 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
811     insert_after(cbefore_begin(), __n, __v);
814 template <class _Tp, class _Alloc>
815 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
816                                         const allocator_type& __a)
817     : base(__a)
819     insert_after(cbefore_begin(), __n, __v);
822 template <class _Tp, class _Alloc>
823 template <class _InputIterator>
824 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
825                                         typename enable_if<
826                                           __is_input_iterator<_InputIterator>::value
827                                         >::type*)
829     insert_after(cbefore_begin(), __f, __l);
832 template <class _Tp, class _Alloc>
833 template <class _InputIterator>
834 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
835                                         const allocator_type& __a,
836                                         typename enable_if<
837                                           __is_input_iterator<_InputIterator>::value
838                                         >::type*)
839     : base(__a)
841     insert_after(cbefore_begin(), __f, __l);
844 template <class _Tp, class _Alloc>
845 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
846     : base(allocator_type(
847              __node_traits::select_on_container_copy_construction(__x.__alloc())
848                          )
849           )
851     insert_after(cbefore_begin(), __x.begin(), __x.end());
854 template <class _Tp, class _Alloc>
855 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
856                                         const allocator_type& __a)
857     : base(__a)
859     insert_after(cbefore_begin(), __x.begin(), __x.end());
862 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
864 template <class _Tp, class _Alloc>
865 forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
866                                         const allocator_type& __a)
867     : base(_VSTD::move(__x), __a)
869     if (base::__alloc() != __x.__alloc())
870     {
871         typedef move_iterator<iterator> _Ip;
872         insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
873     }
876 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
878 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
880 template <class _Tp, class _Alloc>
881 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
883     insert_after(cbefore_begin(), __il.begin(), __il.end());
886 template <class _Tp, class _Alloc>
887 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
888                                         const allocator_type& __a)
889     : base(__a)
891     insert_after(cbefore_begin(), __il.begin(), __il.end());
894 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
896 template <class _Tp, class _Alloc>
897 forward_list<_Tp, _Alloc>&
898 forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
900     if (this != &__x)
901     {
902         base::__copy_assign_alloc(__x);
903         assign(__x.begin(), __x.end());
904     }
905     return *this;
908 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
910 template <class _Tp, class _Alloc>
911 void
912 forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
913     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
915     clear();
916     base::__move_assign_alloc(__x);
917     base::__before_begin()->__next_ = __x.__before_begin()->__next_;
918     __x.__before_begin()->__next_ = nullptr;
921 template <class _Tp, class _Alloc>
922 void
923 forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
925     if (base::__alloc() == __x.__alloc())
926         __move_assign(__x, true_type());
927     else
928     {
929         typedef move_iterator<iterator> _Ip;
930         assign(_Ip(__x.begin()), _Ip(__x.end()));
931     }
934 template <class _Tp, class _Alloc>
935 inline _LIBCPP_INLINE_VISIBILITY
936 forward_list<_Tp, _Alloc>&
937 forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
938     _NOEXCEPT_(
939              __node_traits::propagate_on_container_move_assignment::value &&
940              is_nothrow_move_assignable<allocator_type>::value)
942     __move_assign(__x, integral_constant<bool,
943           __node_traits::propagate_on_container_move_assignment::value>());
944     return *this;
947 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
949 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
951 template <class _Tp, class _Alloc>
952 inline _LIBCPP_INLINE_VISIBILITY
953 forward_list<_Tp, _Alloc>&
954 forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
956     assign(__il.begin(), __il.end());
957     return *this;
960 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
962 template <class _Tp, class _Alloc>
963 template <class _InputIterator>
964 typename enable_if
966     __is_input_iterator<_InputIterator>::value,
967     void
968 >::type
969 forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
971     iterator __i = before_begin();
972     iterator __j = _VSTD::next(__i);
973     iterator __e = end();
974     for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
975         *__j = *__f;
976     if (__j == __e)
977         insert_after(__i, __f, __l);
978     else
979         erase_after(__i, __e);
982 template <class _Tp, class _Alloc>
983 void
984 forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
986     iterator __i = before_begin();
987     iterator __j = _VSTD::next(__i);
988     iterator __e = end();
989     for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
990         *__j = __v;
991     if (__j == __e)
992         insert_after(__i, __n, __v);
993     else
994         erase_after(__i, __e);
997 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
999 template <class _Tp, class _Alloc>
1000 inline _LIBCPP_INLINE_VISIBILITY
1001 void
1002 forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1004     assign(__il.begin(), __il.end());
1007 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1009 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1010 #ifndef _LIBCPP_HAS_NO_VARIADICS
1012 template <class _Tp, class _Alloc>
1013 template <class... _Args>
1014 void
1015 forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1017     __node_allocator& __a = base::__alloc();
1018     typedef __allocator_destructor<__node_allocator> _Dp;
1019     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1020     __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1021                                   _VSTD::forward<_Args>(__args)...);
1022     __h->__next_ = base::__before_begin()->__next_;
1023     base::__before_begin()->__next_ = __h.release();
1026 #endif  // _LIBCPP_HAS_NO_VARIADICS
1028 template <class _Tp, class _Alloc>
1029 void
1030 forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1032     __node_allocator& __a = base::__alloc();
1033     typedef __allocator_destructor<__node_allocator> _Dp;
1034     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1035     __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1036     __h->__next_ = base::__before_begin()->__next_;
1037     base::__before_begin()->__next_ = __h.release();
1040 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1042 template <class _Tp, class _Alloc>
1043 void
1044 forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1046     __node_allocator& __a = base::__alloc();
1047     typedef __allocator_destructor<__node_allocator> _Dp;
1048     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1049     __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1050     __h->__next_ = base::__before_begin()->__next_;
1051     base::__before_begin()->__next_ = __h.release();
1054 template <class _Tp, class _Alloc>
1055 void
1056 forward_list<_Tp, _Alloc>::pop_front()
1058     __node_allocator& __a = base::__alloc();
1059     __node_pointer __p = base::__before_begin()->__next_;
1060     base::__before_begin()->__next_ = __p->__next_;
1061     __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
1062     __node_traits::deallocate(__a, __p, 1);
1065 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1066 #ifndef _LIBCPP_HAS_NO_VARIADICS
1068 template <class _Tp, class _Alloc>
1069 template <class... _Args>
1070 typename forward_list<_Tp, _Alloc>::iterator
1071 forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1073     __node_pointer const __r = __p.__ptr_;
1074     __node_allocator& __a = base::__alloc();
1075     typedef __allocator_destructor<__node_allocator> _Dp;
1076     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1077     __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1078                                   _VSTD::forward<_Args>(__args)...);
1079     __h->__next_ = __r->__next_;
1080     __r->__next_ = __h.release();
1081     return iterator(__r->__next_);
1084 #endif  // _LIBCPP_HAS_NO_VARIADICS
1086 template <class _Tp, class _Alloc>
1087 typename forward_list<_Tp, _Alloc>::iterator
1088 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1090     __node_pointer const __r = __p.__ptr_;
1091     __node_allocator& __a = base::__alloc();
1092     typedef __allocator_destructor<__node_allocator> _Dp;
1093     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1094     __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1095     __h->__next_ = __r->__next_;
1096     __r->__next_ = __h.release();
1097     return iterator(__r->__next_);
1100 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1102 template <class _Tp, class _Alloc>
1103 typename forward_list<_Tp, _Alloc>::iterator
1104 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1106     __node_pointer const __r = __p.__ptr_;
1107     __node_allocator& __a = base::__alloc();
1108     typedef __allocator_destructor<__node_allocator> _Dp;
1109     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1110     __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1111     __h->__next_ = __r->__next_;
1112     __r->__next_ = __h.release();
1113     return iterator(__r->__next_);
1116 template <class _Tp, class _Alloc>
1117 typename forward_list<_Tp, _Alloc>::iterator
1118 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1119                                         const value_type& __v)
1121     __node_pointer __r = __p.__ptr_;
1122     if (__n > 0)
1123     {
1124         __node_allocator& __a = base::__alloc();
1125         typedef __allocator_destructor<__node_allocator> _Dp;
1126         unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1127         __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1128         __node_pointer __first = __h.release();
1129         __node_pointer __last = __first;
1130 #ifndef _LIBCPP_NO_EXCEPTIONS
1131         try
1132         {
1133 #endif  // _LIBCPP_NO_EXCEPTIONS
1134             for (--__n; __n != 0; --__n, __last = __last->__next_)
1135             {
1136                 __h.reset(__node_traits::allocate(__a, 1));
1137                 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1138                 __last->__next_ = __h.release();
1139             }
1140 #ifndef _LIBCPP_NO_EXCEPTIONS
1141         }
1142         catch (...)
1143         {
1144             while (__first != nullptr)
1145             {
1146                 __node_pointer __next = __first->__next_;
1147                 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1148                 __node_traits::deallocate(__a, __first, 1);
1149                 __first = __next;
1150             }
1151             throw;
1152         }
1153 #endif  // _LIBCPP_NO_EXCEPTIONS
1154         __last->__next_ = __r->__next_;
1155         __r->__next_ = __first;
1156         __r = __last;
1157     }
1158     return iterator(__r);
1161 template <class _Tp, class _Alloc>
1162 template <class _InputIterator>
1163 typename enable_if
1165     __is_input_iterator<_InputIterator>::value,
1166     typename forward_list<_Tp, _Alloc>::iterator
1167 >::type
1168 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1169                                         _InputIterator __f, _InputIterator __l)
1171     __node_pointer __r = __p.__ptr_;
1172     if (__f != __l)
1173     {
1174         __node_allocator& __a = base::__alloc();
1175         typedef __allocator_destructor<__node_allocator> _Dp;
1176         unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1177         __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1178         __node_pointer __first = __h.release();
1179         __node_pointer __last = __first;
1180 #ifndef _LIBCPP_NO_EXCEPTIONS
1181         try
1182         {
1183 #endif  // _LIBCPP_NO_EXCEPTIONS
1184             for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
1185             {
1186                 __h.reset(__node_traits::allocate(__a, 1));
1187                 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1188                 __last->__next_ = __h.release();
1189             }
1190 #ifndef _LIBCPP_NO_EXCEPTIONS
1191         }
1192         catch (...)
1193         {
1194             while (__first != nullptr)
1195             {
1196                 __node_pointer __next = __first->__next_;
1197                 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1198                 __node_traits::deallocate(__a, __first, 1);
1199                 __first = __next;
1200             }
1201             throw;
1202         }
1203 #endif  // _LIBCPP_NO_EXCEPTIONS
1204         __last->__next_ = __r->__next_;
1205         __r->__next_ = __first;
1206         __r = __last;
1207     }
1208     return iterator(__r);
1211 template <class _Tp, class _Alloc>
1212 typename forward_list<_Tp, _Alloc>::iterator
1213 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1215     __node_pointer __p = __f.__ptr_;
1216     __node_pointer __n = __p->__next_;
1217     __p->__next_ = __n->__next_;
1218     __node_allocator& __a = base::__alloc();
1219     __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1220     __node_traits::deallocate(__a, __n, 1);
1221     return iterator(__p->__next_);
1224 template <class _Tp, class _Alloc>
1225 typename forward_list<_Tp, _Alloc>::iterator
1226 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1228     __node_pointer __e = __l.__ptr_;
1229     if (__f != __l)
1230     {
1231         __node_pointer __p = __f.__ptr_;
1232         __node_pointer __n = __p->__next_;
1233         if (__n != __e)
1234         {
1235             __p->__next_ = __e;
1236             __node_allocator& __a = base::__alloc();
1237             do
1238             {
1239                 __p = __n->__next_;
1240                 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1241                 __node_traits::deallocate(__a, __n, 1);
1242                 __n = __p;
1243             } while (__n != __e);
1244         }
1245     }
1246     return iterator(__e);
1249 template <class _Tp, class _Alloc>
1250 void
1251 forward_list<_Tp, _Alloc>::resize(size_type __n)
1253     size_type __sz = 0;
1254     iterator __p = before_begin();
1255     iterator __i = begin();
1256     iterator __e = end();
1257     for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1258         ;
1259     if (__i != __e)
1260         erase_after(__p, __e);
1261     else
1262     {
1263         __n -= __sz;
1264         if (__n > 0)
1265         {
1266             __node_allocator& __a = base::__alloc();
1267             typedef __allocator_destructor<__node_allocator> _Dp;
1268             unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
1269             for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1270                                                          __ptr = __ptr->__next_)
1271             {
1272                 __h.reset(__node_traits::allocate(__a, 1));
1273                 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
1274                 __h->__next_ = nullptr;
1275                 __ptr->__next_ = __h.release();
1276             }
1277         }
1278     }
1281 template <class _Tp, class _Alloc>
1282 void
1283 forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1285     size_type __sz = 0;
1286     iterator __p = before_begin();
1287     iterator __i = begin();
1288     iterator __e = end();
1289     for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1290         ;
1291     if (__i != __e)
1292         erase_after(__p, __e);
1293     else
1294     {
1295         __n -= __sz;
1296         if (__n > 0)
1297         {
1298             __node_allocator& __a = base::__alloc();
1299             typedef __allocator_destructor<__node_allocator> _Dp;
1300             unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
1301             for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1302                                                          __ptr = __ptr->__next_)
1303             {
1304                 __h.reset(__node_traits::allocate(__a, 1));
1305                 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1306                 __h->__next_ = nullptr;
1307                 __ptr->__next_ = __h.release();
1308             }
1309         }
1310     }
1313 template <class _Tp, class _Alloc>
1314 void
1315 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1316                                         forward_list& __x)
1318     if (!__x.empty())
1319     {
1320         if (__p.__ptr_->__next_ != nullptr)
1321         {
1322             const_iterator __lm1 = __x.before_begin();
1323             while (__lm1.__ptr_->__next_ != nullptr)
1324                 ++__lm1;
1325             __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
1326         }
1327         __p.__ptr_->__next_ = __x.__before_begin()->__next_;
1328         __x.__before_begin()->__next_ = nullptr;
1329     }
1332 template <class _Tp, class _Alloc>
1333 void
1334 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1335                                         forward_list& __x,
1336                                         const_iterator __i)
1338     const_iterator __lm1 = _VSTD::next(__i);
1339     if (__p != __i && __p != __lm1)
1340     {
1341         __i.__ptr_->__next_ = __lm1.__ptr_->__next_;
1342         __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
1343         __p.__ptr_->__next_ = __lm1.__ptr_;
1344     }
1347 template <class _Tp, class _Alloc>
1348 void
1349 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1350                                         forward_list& __x,
1351                                         const_iterator __f, const_iterator __l)
1353     if (__f != __l && __p != __f)
1354     {
1355         const_iterator __lm1 = __f;
1356         while (__lm1.__ptr_->__next_ != __l.__ptr_)
1357             ++__lm1;
1358         if (__f != __lm1)
1359         {
1360             __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
1361             __p.__ptr_->__next_ = __f.__ptr_->__next_;
1362             __f.__ptr_->__next_ = __l.__ptr_;
1363         }
1364     }
1367 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1369 template <class _Tp, class _Alloc>
1370 inline _LIBCPP_INLINE_VISIBILITY
1371 void
1372 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1373                                         forward_list&& __x)
1375     splice_after(__p, __x);
1378 template <class _Tp, class _Alloc>
1379 inline _LIBCPP_INLINE_VISIBILITY
1380 void
1381 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1382                                         forward_list&& __x,
1383                                         const_iterator __i)
1385     splice_after(__p, __x, __i);
1388 template <class _Tp, class _Alloc>
1389 inline _LIBCPP_INLINE_VISIBILITY
1390 void
1391 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1392                                         forward_list&& __x,
1393                                         const_iterator __f, const_iterator __l)
1395     splice_after(__p, __x, __f, __l);
1398 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1400 template <class _Tp, class _Alloc>
1401 void
1402 forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1404     forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
1405     iterator __e = end();
1406     for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1407     {
1408         if (__i.__ptr_->__next_->__value_ == __v)
1409         {
1410             iterator __j = _VSTD::next(__i, 2);
1411             for (; __j != __e && *__j == __v; ++__j)
1412                 ;
1413             __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1414             if (__j == __e)
1415                 break;
1416             __i = __j;
1417         }
1418         else
1419             ++__i;
1420     }
1423 template <class _Tp, class _Alloc>
1424 template <class _Predicate>
1425 void
1426 forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1428     iterator __e = end();
1429     for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1430     {
1431         if (__pred(__i.__ptr_->__next_->__value_))
1432         {
1433             iterator __j = _VSTD::next(__i, 2);
1434             for (; __j != __e && __pred(*__j); ++__j)
1435                 ;
1436             erase_after(__i, __j);
1437             if (__j == __e)
1438                 break;
1439             __i = __j;
1440         }
1441         else
1442             ++__i;
1443     }
1446 template <class _Tp, class _Alloc>
1447 template <class _BinaryPredicate>
1448 void
1449 forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1451     for (iterator __i = begin(), __e = end(); __i != __e;)
1452     {
1453         iterator __j = _VSTD::next(__i);
1454         for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1455             ;
1456         if (__i.__ptr_->__next_ != __j.__ptr_)
1457             erase_after(__i, __j);
1458         __i = __j;
1459     }
1462 template <class _Tp, class _Alloc>
1463 template <class _Compare>
1464 void
1465 forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1467     if (this != &__x)
1468     {
1469         base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1470                                                     __x.__before_begin()->__next_,
1471                                                     __comp);
1472         __x.__before_begin()->__next_ = nullptr;
1473     }
1476 template <class _Tp, class _Alloc>
1477 template <class _Compare>
1478 typename forward_list<_Tp, _Alloc>::__node_pointer
1479 forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1480                                    _Compare& __comp)
1482     if (__f1 == nullptr)
1483         return __f2;
1484     if (__f2 == nullptr)
1485         return __f1;
1486     __node_pointer __r;
1487     if (__comp(__f2->__value_, __f1->__value_))
1488     {
1489         __node_pointer __t = __f2;
1490         while (__t->__next_ != nullptr &&
1491                              __comp(__t->__next_->__value_, __f1->__value_))
1492             __t = __t->__next_;
1493         __r = __f2;
1494         __f2 = __t->__next_;
1495         __t->__next_ = __f1;
1496     }
1497     else
1498         __r = __f1;
1499     __node_pointer __p = __f1;
1500     __f1 = __f1->__next_;
1501     while (__f1 != nullptr && __f2 != nullptr)
1502     {
1503         if (__comp(__f2->__value_, __f1->__value_))
1504         {
1505             __node_pointer __t = __f2;
1506             while (__t->__next_ != nullptr &&
1507                                  __comp(__t->__next_->__value_, __f1->__value_))
1508                 __t = __t->__next_;
1509             __p->__next_ = __f2;
1510             __f2 = __t->__next_;
1511             __t->__next_ = __f1;
1512         }
1513         __p = __f1;
1514         __f1 = __f1->__next_;
1515     }
1516     if (__f2 != nullptr)
1517         __p->__next_ = __f2;
1518     return __r;
1521 template <class _Tp, class _Alloc>
1522 template <class _Compare>
1523 inline _LIBCPP_INLINE_VISIBILITY
1524 void
1525 forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1527     base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1528                                        _VSTD::distance(begin(), end()), __comp);
1531 template <class _Tp, class _Alloc>
1532 template <class _Compare>
1533 typename forward_list<_Tp, _Alloc>::__node_pointer
1534 forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1535                                   _Compare& __comp)
1537     switch (__sz)
1538     {
1539     case 0:
1540     case 1:
1541         return __f1;
1542     case 2:
1543         if (__comp(__f1->__next_->__value_, __f1->__value_))
1544         {
1545             __node_pointer __t = __f1->__next_;
1546             __t->__next_ = __f1;
1547             __f1->__next_ = nullptr;
1548             __f1 = __t;
1549         }
1550         return __f1;
1551     }
1552     difference_type __sz1 = __sz / 2;
1553     difference_type __sz2 = __sz - __sz1;
1554     __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;
1555     __node_pointer __f2 = __t->__next_;
1556     __t->__next_ = nullptr;
1557     return __merge(__sort(__f1, __sz1, __comp),
1558                    __sort(__f2, __sz2, __comp), __comp);
1561 template <class _Tp, class _Alloc>
1562 void
1563 forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
1565     __node_pointer __p = base::__before_begin()->__next_;
1566     if (__p != nullptr)
1567     {
1568         __node_pointer __f = __p->__next_;
1569         __p->__next_ = nullptr;
1570         while (__f != nullptr)
1571         {
1572             __node_pointer __t = __f->__next_;
1573             __f->__next_ = __p;
1574             __p = __f;
1575             __f = __t;
1576         }
1577         base::__before_begin()->__next_ = __p;
1578     }
1581 template <class _Tp, class _Alloc>
1582 bool operator==(const forward_list<_Tp, _Alloc>& __x,
1583                 const forward_list<_Tp, _Alloc>& __y)
1585     typedef forward_list<_Tp, _Alloc> _Cp;
1586     typedef typename _Cp::const_iterator _Ip;
1587     _Ip __ix = __x.begin();
1588     _Ip __ex = __x.end();
1589     _Ip __iy = __y.begin();
1590     _Ip __ey = __y.end();
1591     for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1592         if (!(*__ix == *__iy))
1593             return false;
1594     return (__ix == __ex) == (__iy == __ey);
1597 template <class _Tp, class _Alloc>
1598 inline _LIBCPP_INLINE_VISIBILITY
1599 bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1600                 const forward_list<_Tp, _Alloc>& __y)
1602     return !(__x == __y);
1605 template <class _Tp, class _Alloc>
1606 inline _LIBCPP_INLINE_VISIBILITY
1607 bool operator< (const forward_list<_Tp, _Alloc>& __x,
1608                 const forward_list<_Tp, _Alloc>& __y)
1610     return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
1611                                          __y.begin(), __y.end());
1614 template <class _Tp, class _Alloc>
1615 inline _LIBCPP_INLINE_VISIBILITY
1616 bool operator> (const forward_list<_Tp, _Alloc>& __x,
1617                 const forward_list<_Tp, _Alloc>& __y)
1619     return __y < __x;
1622 template <class _Tp, class _Alloc>
1623 inline _LIBCPP_INLINE_VISIBILITY
1624 bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1625                 const forward_list<_Tp, _Alloc>& __y)
1627     return !(__x < __y);
1630 template <class _Tp, class _Alloc>
1631 inline _LIBCPP_INLINE_VISIBILITY
1632 bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1633                 const forward_list<_Tp, _Alloc>& __y)
1635     return !(__y < __x);
1638 template <class _Tp, class _Alloc>
1639 inline _LIBCPP_INLINE_VISIBILITY
1640 void
1641 swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1642     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1644     __x.swap(__y);
1647 _LIBCPP_END_NAMESPACE_STD
1649 #endif  // _LIBCPP_FORWARD_LIST