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