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