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