13e519524SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_FORWARD_LIST
113e519524SHoward Hinnant#define _LIBCPP_FORWARD_LIST
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    forward_list synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnanttemplate <class T, class Allocator = allocator<T>>
203e519524SHoward Hinnantclass forward_list
213e519524SHoward Hinnant{
223e519524SHoward Hinnantpublic:
233e519524SHoward Hinnant    typedef T         value_type;
243e519524SHoward Hinnant    typedef Allocator allocator_type;
253e519524SHoward Hinnant
263e519524SHoward Hinnant    typedef value_type&                                                reference;
273e519524SHoward Hinnant    typedef const value_type&                                          const_reference;
283e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::pointer         pointer;
293e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
303e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::size_type       size_type;
313e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
323e519524SHoward Hinnant
333e519524SHoward Hinnant    typedef <details> iterator;
343e519524SHoward Hinnant    typedef <details> const_iterator;
353e519524SHoward Hinnant
3691a47507SHoward Hinnant    forward_list()
3791a47507SHoward Hinnant        noexcept(is_nothrow_default_constructible<allocator_type>::value);
383e519524SHoward Hinnant    explicit forward_list(const allocator_type& a);
393e519524SHoward Hinnant    explicit forward_list(size_type n);
40f1b6d1b5SMarshall Clow    explicit forward_list(size_type n, const allocator_type& a); // C++14
413e519524SHoward Hinnant    forward_list(size_type n, const value_type& v);
423e519524SHoward Hinnant    forward_list(size_type n, const value_type& v, const allocator_type& a);
433e519524SHoward Hinnant    template <class InputIterator>
443e519524SHoward Hinnant        forward_list(InputIterator first, InputIterator last);
453e519524SHoward Hinnant    template <class InputIterator>
463e519524SHoward Hinnant        forward_list(InputIterator first, InputIterator last, const allocator_type& a);
473e519524SHoward Hinnant    forward_list(const forward_list& x);
483e519524SHoward Hinnant    forward_list(const forward_list& x, const allocator_type& a);
4991a47507SHoward Hinnant    forward_list(forward_list&& x)
5091a47507SHoward Hinnant        noexcept(is_nothrow_move_constructible<allocator_type>::value);
513e519524SHoward Hinnant    forward_list(forward_list&& x, const allocator_type& a);
523e519524SHoward Hinnant    forward_list(initializer_list<value_type> il);
533e519524SHoward Hinnant    forward_list(initializer_list<value_type> il, const allocator_type& a);
543e519524SHoward Hinnant
553e519524SHoward Hinnant    ~forward_list();
563e519524SHoward Hinnant
573e519524SHoward Hinnant    forward_list& operator=(const forward_list& x);
5891a47507SHoward Hinnant    forward_list& operator=(forward_list&& x)
5991a47507SHoward Hinnant        noexcept(
6091a47507SHoward Hinnant             allocator_type::propagate_on_container_move_assignment::value &&
6191a47507SHoward Hinnant             is_nothrow_move_assignable<allocator_type>::value);
623e519524SHoward Hinnant    forward_list& operator=(initializer_list<value_type> il);
633e519524SHoward Hinnant
643e519524SHoward Hinnant    template <class InputIterator>
653e519524SHoward Hinnant        void assign(InputIterator first, InputIterator last);
663e519524SHoward Hinnant    void assign(size_type n, const value_type& v);
673e519524SHoward Hinnant    void assign(initializer_list<value_type> il);
683e519524SHoward Hinnant
69f9dc2831SHoward Hinnant    allocator_type get_allocator() const noexcept;
703e519524SHoward Hinnant
71f9dc2831SHoward Hinnant    iterator       begin() noexcept;
72f9dc2831SHoward Hinnant    const_iterator begin() const noexcept;
73f9dc2831SHoward Hinnant    iterator       end() noexcept;
74f9dc2831SHoward Hinnant    const_iterator end() const noexcept;
753e519524SHoward Hinnant
76f9dc2831SHoward Hinnant    const_iterator cbegin() const noexcept;
77f9dc2831SHoward Hinnant    const_iterator cend() const noexcept;
783e519524SHoward Hinnant
79f9dc2831SHoward Hinnant    iterator       before_begin() noexcept;
80f9dc2831SHoward Hinnant    const_iterator before_begin() const noexcept;
81f9dc2831SHoward Hinnant    const_iterator cbefore_begin() const noexcept;
823e519524SHoward Hinnant
83f9dc2831SHoward Hinnant    bool empty() const noexcept;
84f9dc2831SHoward Hinnant    size_type max_size() const noexcept;
853e519524SHoward Hinnant
863e519524SHoward Hinnant    reference       front();
873e519524SHoward Hinnant    const_reference front() const;
883e519524SHoward Hinnant
8963b560beSMarshall Clow    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
903e519524SHoward Hinnant    void push_front(const value_type& v);
913e519524SHoward Hinnant    void push_front(value_type&& v);
923e519524SHoward Hinnant
933e519524SHoward Hinnant    void pop_front();
943e519524SHoward Hinnant
953e519524SHoward Hinnant    template <class... Args>
963e519524SHoward Hinnant        iterator emplace_after(const_iterator p, Args&&... args);
973e519524SHoward Hinnant    iterator insert_after(const_iterator p, const value_type& v);
983e519524SHoward Hinnant    iterator insert_after(const_iterator p, value_type&& v);
993e519524SHoward Hinnant    iterator insert_after(const_iterator p, size_type n, const value_type& v);
1003e519524SHoward Hinnant    template <class InputIterator>
1013e519524SHoward Hinnant        iterator insert_after(const_iterator p,
1023e519524SHoward Hinnant                              InputIterator first, InputIterator last);
1033e519524SHoward Hinnant    iterator insert_after(const_iterator p, initializer_list<value_type> il);
1043e519524SHoward Hinnant
1053db88036SHoward Hinnant    iterator erase_after(const_iterator p);
1063db88036SHoward Hinnant    iterator erase_after(const_iterator first, const_iterator last);
1073e519524SHoward Hinnant
10891a47507SHoward Hinnant    void swap(forward_list& x)
109e3fbe143SMarshall Clow        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
1103e519524SHoward Hinnant
1113e519524SHoward Hinnant    void resize(size_type n);
1123e519524SHoward Hinnant    void resize(size_type n, const value_type& v);
113f9dc2831SHoward Hinnant    void clear() noexcept;
1143e519524SHoward Hinnant
115eb92df7eSHoward Hinnant    void splice_after(const_iterator p, forward_list& x);
1163e519524SHoward Hinnant    void splice_after(const_iterator p, forward_list&& x);
117eb92df7eSHoward Hinnant    void splice_after(const_iterator p, forward_list& x, const_iterator i);
1183e519524SHoward Hinnant    void splice_after(const_iterator p, forward_list&& x, const_iterator i);
119eb92df7eSHoward Hinnant    void splice_after(const_iterator p, forward_list& x,
120eb92df7eSHoward Hinnant                      const_iterator first, const_iterator last);
1213e519524SHoward Hinnant    void splice_after(const_iterator p, forward_list&& x,
1223e519524SHoward Hinnant                      const_iterator first, const_iterator last);
123f814dcbaSMarshall Clow    size_type remove(const value_type& v);           // void before C++20
124f814dcbaSMarshall Clow    template <class Predicate>
125f814dcbaSMarshall Clow      size_type remove_if(Predicate pred);           // void before C++20
126f814dcbaSMarshall Clow    size_type unique();                              // void before C++20
127f814dcbaSMarshall Clow    template <class BinaryPredicate>
128f814dcbaSMarshall Clow      size_type unique(BinaryPredicate binary_pred); // void before C++20
129eb92df7eSHoward Hinnant    void merge(forward_list& x);
1303e519524SHoward Hinnant    void merge(forward_list&& x);
131eb92df7eSHoward Hinnant    template <class Compare> void merge(forward_list& x, Compare comp);
1323e519524SHoward Hinnant    template <class Compare> void merge(forward_list&& x, Compare comp);
1333e519524SHoward Hinnant    void sort();
1343e519524SHoward Hinnant    template <class Compare> void sort(Compare comp);
135f9dc2831SHoward Hinnant    void reverse() noexcept;
1363e519524SHoward Hinnant};
1373e519524SHoward Hinnant
138e076700bSMarshall Clow
139e076700bSMarshall Clowtemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
140e076700bSMarshall Clow    forward_list(InputIterator, InputIterator, Allocator = Allocator())
141e076700bSMarshall Clow    -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;  // C++17
142e076700bSMarshall Clow
1433e519524SHoward Hinnanttemplate <class T, class Allocator>
1443e519524SHoward Hinnant    bool operator==(const forward_list<T, Allocator>& x,
1453e519524SHoward Hinnant                    const forward_list<T, Allocator>& y);
1463e519524SHoward Hinnant
1473e519524SHoward Hinnanttemplate <class T, class Allocator>
1483e519524SHoward Hinnant    bool operator< (const forward_list<T, Allocator>& x,
1493e519524SHoward Hinnant                    const forward_list<T, Allocator>& y);
1503e519524SHoward Hinnant
1513e519524SHoward Hinnanttemplate <class T, class Allocator>
1523e519524SHoward Hinnant    bool operator!=(const forward_list<T, Allocator>& x,
1533e519524SHoward Hinnant                    const forward_list<T, Allocator>& y);
1543e519524SHoward Hinnant
1553e519524SHoward Hinnanttemplate <class T, class Allocator>
1563e519524SHoward Hinnant    bool operator> (const forward_list<T, Allocator>& x,
1573e519524SHoward Hinnant                    const forward_list<T, Allocator>& y);
1583e519524SHoward Hinnant
1593e519524SHoward Hinnanttemplate <class T, class Allocator>
1603e519524SHoward Hinnant    bool operator>=(const forward_list<T, Allocator>& x,
1613e519524SHoward Hinnant                    const forward_list<T, Allocator>& y);
1623e519524SHoward Hinnant
1633e519524SHoward Hinnanttemplate <class T, class Allocator>
1643e519524SHoward Hinnant    bool operator<=(const forward_list<T, Allocator>& x,
1653e519524SHoward Hinnant                    const forward_list<T, Allocator>& y);
1663e519524SHoward Hinnant
1673e519524SHoward Hinnanttemplate <class T, class Allocator>
16891a47507SHoward Hinnant    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
16945900104SHoward Hinnant         noexcept(noexcept(x.swap(y)));
1703e519524SHoward Hinnant
171f60c63c0SMarshall Clowtemplate <class T, class Allocator, class U>
1723e895085SMarek Kurdej    typename forward_list<T, Allocator>::size_type
1733e895085SMarek Kurdej    erase(forward_list<T, Allocator>& c, const U& value);       // C++20
174f60c63c0SMarshall Clowtemplate <class T, class Allocator, class Predicate>
1753e895085SMarek Kurdej    typename forward_list<T, Allocator>::size_type
1763e895085SMarek Kurdej    erase_if(forward_list<T, Allocator>& c, Predicate pred);    // C++20
177f60c63c0SMarshall Clow
1783e519524SHoward Hinnant}  // std
1793e519524SHoward Hinnant
1803e519524SHoward Hinnant*/
1813e519524SHoward Hinnant
1822e2f3158SNikolas Klauser#include <__algorithm/comp.h>
1832e2f3158SNikolas Klauser#include <__algorithm/lexicographical_compare.h>
1842e2f3158SNikolas Klauser#include <__algorithm/min.h>
185385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
1863e519524SHoward Hinnant#include <__config>
1873cd4531bSNikolas Klauser#include <__iterator/distance.h>
1883cd4531bSNikolas Klauser#include <__iterator/iterator_traits.h>
1893cd4531bSNikolas Klauser#include <__iterator/move_iterator.h>
1903cd4531bSNikolas Klauser#include <__iterator/next.h>
191*f4fb72e6SNikolas Klauser#include <__memory/swap_allocator.h>
1926adbc83eSChristopher Di Bella#include <__utility/forward.h>
193bfbd73f8SArthur O'Dwyer#include <limits>
194bfbd73f8SArthur O'Dwyer#include <memory>
1957da4ee6fSKonstantin Varlamov#include <type_traits>
196f56972e2SMarshall Clow#include <version>
1973e519524SHoward Hinnant
198de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
199de4a57cbSLouis Dionne#  include <algorithm>
200de4a57cbSLouis Dionne#  include <functional>
201de4a57cbSLouis Dionne#  include <iterator>
202de4a57cbSLouis Dionne#endif
203de4a57cbSLouis Dionne
204db1978b6SNikolas Klauser// standard-mandated includes
205db1978b6SNikolas Klauser
206db1978b6SNikolas Klauser// [iterator.range]
207db1978b6SNikolas Klauser#include <__iterator/access.h>
208db1978b6SNikolas Klauser#include <__iterator/data.h>
209db1978b6SNikolas Klauser#include <__iterator/empty.h>
210db1978b6SNikolas Klauser#include <__iterator/reverse_access.h>
211db1978b6SNikolas Klauser#include <__iterator/size.h>
212db1978b6SNikolas Klauser
213db1978b6SNikolas Klauser// [forward.list.syn]
214db1978b6SNikolas Klauser#include <compare>
215db1978b6SNikolas Klauser#include <initializer_list>
216db1978b6SNikolas Klauser
217073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2183e519524SHoward Hinnant#  pragma GCC system_header
219073458b1SHoward Hinnant#endif
2203e519524SHoward Hinnant
221a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
222a016efb1SEric Fiselier#include <__undef_macros>
223a016efb1SEric Fiselier
224a016efb1SEric Fiselier
2253e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
2263e519524SHoward Hinnant
227ce53420eSHoward Hinnanttemplate <class _Tp, class _VoidPtr> struct __forward_list_node;
22807b9cd36SEric Fiseliertemplate <class _NodePtr> struct __forward_begin_node;
22907b9cd36SEric Fiselier
23007b9cd36SEric Fiselier
23107b9cd36SEric Fiseliertemplate <class>
23207b9cd36SEric Fiselierstruct __forward_list_node_value_type;
23307b9cd36SEric Fiselier
23407b9cd36SEric Fiseliertemplate <class _Tp, class _VoidPtr>
23507b9cd36SEric Fiselierstruct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
23607b9cd36SEric Fiselier  typedef _Tp type;
23707b9cd36SEric Fiselier};
23807b9cd36SEric Fiselier
23907b9cd36SEric Fiseliertemplate <class _NodePtr>
24007b9cd36SEric Fiselierstruct __forward_node_traits {
24107b9cd36SEric Fiselier
24207b9cd36SEric Fiselier  typedef typename remove_cv<
24307b9cd36SEric Fiselier        typename pointer_traits<_NodePtr>::element_type>::type  __node;
24407b9cd36SEric Fiselier  typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
24507b9cd36SEric Fiselier  typedef _NodePtr                                              __node_pointer;
24607b9cd36SEric Fiselier  typedef __forward_begin_node<_NodePtr>                        __begin_node;
24707b9cd36SEric Fiselier  typedef typename __rebind_pointer<_NodePtr, __begin_node>::type
24807b9cd36SEric Fiselier                                                                __begin_node_pointer;
24907b9cd36SEric Fiselier  typedef typename __rebind_pointer<_NodePtr, void>::type       __void_pointer;
25007b9cd36SEric Fiselier
25107b9cd36SEric Fiselier#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
25207b9cd36SEric Fiselier  typedef __begin_node_pointer __iter_node_pointer;
25307b9cd36SEric Fiselier#else
25407b9cd36SEric Fiselier  typedef typename conditional<
25507b9cd36SEric Fiselier          is_pointer<__void_pointer>::value,
25607b9cd36SEric Fiselier          __begin_node_pointer,
25707b9cd36SEric Fiselier          __node_pointer
25807b9cd36SEric Fiselier    >::type __iter_node_pointer;
25907b9cd36SEric Fiselier#endif
26007b9cd36SEric Fiselier
26107b9cd36SEric Fiselier  typedef typename conditional<
26207b9cd36SEric Fiselier          is_same<__iter_node_pointer, __node_pointer>::value,
26307b9cd36SEric Fiselier          __begin_node_pointer,
26407b9cd36SEric Fiselier          __node_pointer
26507b9cd36SEric Fiselier    >::type __non_iter_node_pointer;
26607b9cd36SEric Fiselier
26707b9cd36SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
26807b9cd36SEric Fiselier  static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) {
26907b9cd36SEric Fiselier      return __p;
27007b9cd36SEric Fiselier  }
27107b9cd36SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
27207b9cd36SEric Fiselier  static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
27307b9cd36SEric Fiselier      return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
27407b9cd36SEric Fiselier  }
27507b9cd36SEric Fiselier};
2763e519524SHoward Hinnant
2773e519524SHoward Hinnanttemplate <class _NodePtr>
2783e519524SHoward Hinnantstruct __forward_begin_node
2793e519524SHoward Hinnant{
2803e519524SHoward Hinnant    typedef _NodePtr pointer;
28107b9cd36SEric Fiselier    typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
2823e519524SHoward Hinnant
2833e519524SHoward Hinnant    pointer __next_;
2843e519524SHoward Hinnant
2850af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
28607b9cd36SEric Fiselier
28707b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
28807b9cd36SEric Fiselier    __begin_node_pointer __next_as_begin() const {
28907b9cd36SEric Fiselier        return static_cast<__begin_node_pointer>(__next_);
29007b9cd36SEric Fiselier    }
2913e519524SHoward Hinnant};
2923e519524SHoward Hinnant
2933e519524SHoward Hinnanttemplate <class _Tp, class _VoidPtr>
29409df4a66SPeter Collingbournestruct _LIBCPP_HIDDEN __begin_node_of
29509df4a66SPeter Collingbourne{
296934b0921SEric Fiselier    typedef __forward_begin_node<
297934b0921SEric Fiselier        typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
29809df4a66SPeter Collingbourne    > type;
29909df4a66SPeter Collingbourne};
30009df4a66SPeter Collingbourne
30109df4a66SPeter Collingbournetemplate <class _Tp, class _VoidPtr>
3027c2f5827SAmy Huangstruct _LIBCPP_STANDALONE_DEBUG __forward_list_node
30309df4a66SPeter Collingbourne    : public __begin_node_of<_Tp, _VoidPtr>::type
3043e519524SHoward Hinnant{
3053e519524SHoward Hinnant    typedef _Tp value_type;
3063e519524SHoward Hinnant
3073e519524SHoward Hinnant    value_type __value_;
3083e519524SHoward Hinnant};
3093e519524SHoward Hinnant
31007b9cd36SEric Fiselier
311e2f2d1edSEric Fiseliertemplate <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list;
312e2f2d1edSEric Fiseliertemplate<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
3133e519524SHoward Hinnant
3143e519524SHoward Hinnanttemplate <class _NodePtr>
315e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __forward_list_iterator
3163e519524SHoward Hinnant{
31707b9cd36SEric Fiselier    typedef __forward_node_traits<_NodePtr>         __traits;
31807b9cd36SEric Fiselier    typedef typename __traits::__node_pointer       __node_pointer;
31907b9cd36SEric Fiselier    typedef typename __traits::__begin_node_pointer __begin_node_pointer;
32007b9cd36SEric Fiselier    typedef typename __traits::__iter_node_pointer  __iter_node_pointer;
32107b9cd36SEric Fiselier    typedef typename __traits::__void_pointer       __void_pointer;
3223e519524SHoward Hinnant
32307b9cd36SEric Fiselier    __iter_node_pointer __ptr_;
3243e519524SHoward Hinnant
3250af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
32607b9cd36SEric Fiselier    __begin_node_pointer __get_begin() const {
32707b9cd36SEric Fiselier        return static_cast<__begin_node_pointer>(
32807b9cd36SEric Fiselier                static_cast<__void_pointer>(__ptr_));
32907b9cd36SEric Fiselier    }
33007b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
33107b9cd36SEric Fiselier    __node_pointer __get_unsafe_node_pointer() const {
33207b9cd36SEric Fiselier        return static_cast<__node_pointer>(
33307b9cd36SEric Fiselier                static_cast<__void_pointer>(__ptr_));
33407b9cd36SEric Fiselier    }
33507b9cd36SEric Fiselier
33607b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
33707b9cd36SEric Fiselier    explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
33807b9cd36SEric Fiselier
33907b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
34007b9cd36SEric Fiselier    explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
34107b9cd36SEric Fiselier        : __ptr_(__traits::__as_iter_node(__p)) {}
34207b9cd36SEric Fiselier
34307b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
34407b9cd36SEric Fiselier    explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
34507b9cd36SEric Fiselier        : __ptr_(__traits::__as_iter_node(__p)) {}
3463e519524SHoward Hinnant
347e2f2d1edSEric Fiselier    template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list;
348e2f2d1edSEric Fiselier    template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
3493e519524SHoward Hinnant
3503e519524SHoward Hinnantpublic:
3513e519524SHoward Hinnant    typedef forward_iterator_tag                              iterator_category;
35207b9cd36SEric Fiselier    typedef typename __traits::__node_value_type              value_type;
3533e519524SHoward Hinnant    typedef value_type&                                       reference;
3543e519524SHoward Hinnant    typedef typename pointer_traits<__node_pointer>::difference_type
3553e519524SHoward Hinnant                                                              difference_type;
356934b0921SEric Fiselier    typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
3573e519524SHoward Hinnant
3580af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
359f9dc2831SHoward Hinnant    __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
3603e519524SHoward Hinnant
3610af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
36207b9cd36SEric Fiselier    reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
3630af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
36407b9cd36SEric Fiselier    pointer operator->() const {
36507b9cd36SEric Fiselier        return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
36607b9cd36SEric Fiselier    }
3673e519524SHoward Hinnant
3680af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
3693e519524SHoward Hinnant    __forward_list_iterator& operator++()
3703e519524SHoward Hinnant    {
3714de5f986SEric Fiselier        __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
3723e519524SHoward Hinnant        return *this;
3733e519524SHoward Hinnant    }
3740af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
3753e519524SHoward Hinnant    __forward_list_iterator operator++(int)
3763e519524SHoward Hinnant    {
3773e519524SHoward Hinnant        __forward_list_iterator __t(*this);
3783e519524SHoward Hinnant        ++(*this);
3793e519524SHoward Hinnant        return __t;
3803e519524SHoward Hinnant    }
3813e519524SHoward Hinnant
3820af133f9SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
3830af133f9SHoward Hinnant    bool operator==(const __forward_list_iterator& __x,
3843e519524SHoward Hinnant                    const __forward_list_iterator& __y)
3853e519524SHoward Hinnant        {return __x.__ptr_ == __y.__ptr_;}
3860af133f9SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
3870af133f9SHoward Hinnant    bool operator!=(const __forward_list_iterator& __x,
3883e519524SHoward Hinnant                    const __forward_list_iterator& __y)
3893e519524SHoward Hinnant        {return !(__x == __y);}
3903e519524SHoward Hinnant};
3913e519524SHoward Hinnant
3923e519524SHoward Hinnanttemplate <class _NodeConstPtr>
393e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
3943e519524SHoward Hinnant{
39507b9cd36SEric Fiselier    static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
39607b9cd36SEric Fiselier    typedef _NodeConstPtr _NodePtr;
3973e519524SHoward Hinnant
39807b9cd36SEric Fiselier    typedef __forward_node_traits<_NodePtr>         __traits;
39907b9cd36SEric Fiselier    typedef typename __traits::__node               __node;
40007b9cd36SEric Fiselier    typedef typename __traits::__node_pointer       __node_pointer;
40107b9cd36SEric Fiselier    typedef typename __traits::__begin_node_pointer __begin_node_pointer;
40207b9cd36SEric Fiselier    typedef typename __traits::__iter_node_pointer  __iter_node_pointer;
40307b9cd36SEric Fiselier    typedef typename __traits::__void_pointer       __void_pointer;
40407b9cd36SEric Fiselier
40507b9cd36SEric Fiselier    __iter_node_pointer __ptr_;
40607b9cd36SEric Fiselier
40707b9cd36SEric Fiselier    __begin_node_pointer __get_begin() const {
40807b9cd36SEric Fiselier        return static_cast<__begin_node_pointer>(
40907b9cd36SEric Fiselier                static_cast<__void_pointer>(__ptr_));
41007b9cd36SEric Fiselier    }
41107b9cd36SEric Fiselier    __node_pointer __get_unsafe_node_pointer() const {
41207b9cd36SEric Fiselier        return static_cast<__node_pointer>(
41307b9cd36SEric Fiselier                static_cast<__void_pointer>(__ptr_));
41407b9cd36SEric Fiselier    }
4153e519524SHoward Hinnant
4160af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
41707b9cd36SEric Fiselier    explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
41807b9cd36SEric Fiselier        : __ptr_(nullptr) {}
4193e519524SHoward Hinnant
42007b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
42107b9cd36SEric Fiselier    explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
42207b9cd36SEric Fiselier        : __ptr_(__traits::__as_iter_node(__p)) {}
42307b9cd36SEric Fiselier
42407b9cd36SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
42507b9cd36SEric Fiselier    explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
42607b9cd36SEric Fiselier        : __ptr_(__traits::__as_iter_node(__p)) {}
42707b9cd36SEric Fiselier
4283e519524SHoward Hinnant
4293e519524SHoward Hinnant    template<class, class> friend class forward_list;
4303e519524SHoward Hinnant
4313e519524SHoward Hinnantpublic:
4323e519524SHoward Hinnant    typedef forward_iterator_tag                              iterator_category;
43307b9cd36SEric Fiselier    typedef typename __traits::__node_value_type              value_type;
4343e519524SHoward Hinnant    typedef const value_type&                                 reference;
43507b9cd36SEric Fiselier    typedef typename pointer_traits<__node_pointer>::difference_type
4363e519524SHoward Hinnant                                                              difference_type;
43707b9cd36SEric Fiselier    typedef typename __rebind_pointer<__node_pointer, const value_type>::type
43807b9cd36SEric Fiselier                                                              pointer;
4393e519524SHoward Hinnant
4400af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
441f9dc2831SHoward Hinnant    __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
4420af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
443f9dc2831SHoward Hinnant    __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
4443e519524SHoward Hinnant        : __ptr_(__p.__ptr_) {}
4453e519524SHoward Hinnant
4460af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
44707b9cd36SEric Fiselier    reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
4480af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
44907b9cd36SEric Fiselier    pointer operator->() const {return pointer_traits<pointer>::pointer_to(
45007b9cd36SEric Fiselier                __get_unsafe_node_pointer()->__value_);}
4513e519524SHoward Hinnant
4520af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
4533e519524SHoward Hinnant    __forward_list_const_iterator& operator++()
4543e519524SHoward Hinnant    {
4554de5f986SEric Fiselier        __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
4563e519524SHoward Hinnant        return *this;
4573e519524SHoward Hinnant    }
4580af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
4593e519524SHoward Hinnant    __forward_list_const_iterator operator++(int)
4603e519524SHoward Hinnant    {
4613e519524SHoward Hinnant        __forward_list_const_iterator __t(*this);
4623e519524SHoward Hinnant        ++(*this);
4633e519524SHoward Hinnant        return __t;
4643e519524SHoward Hinnant    }
4653e519524SHoward Hinnant
4660af133f9SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
4670af133f9SHoward Hinnant    bool operator==(const __forward_list_const_iterator& __x,
4683e519524SHoward Hinnant                    const __forward_list_const_iterator& __y)
4693e519524SHoward Hinnant        {return __x.__ptr_ == __y.__ptr_;}
4700af133f9SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
4710af133f9SHoward Hinnant    bool operator!=(const __forward_list_const_iterator& __x,
4723e519524SHoward Hinnant                           const __forward_list_const_iterator& __y)
4733e519524SHoward Hinnant        {return !(__x == __y);}
4743e519524SHoward Hinnant};
4753e519524SHoward Hinnant
4763e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
4773e519524SHoward Hinnantclass __forward_list_base
4783e519524SHoward Hinnant{
4793e519524SHoward Hinnantprotected:
4803e519524SHoward Hinnant    typedef _Tp    value_type;
4813e519524SHoward Hinnant    typedef _Alloc allocator_type;
4823e519524SHoward Hinnant
4833e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::void_pointer  void_pointer;
4843e519524SHoward Hinnant    typedef __forward_list_node<value_type, void_pointer>            __node;
48509df4a66SPeter Collingbourne    typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
4861f508014SMarshall Clow    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
4873e519524SHoward Hinnant    typedef allocator_traits<__node_allocator>        __node_traits;
4883e519524SHoward Hinnant    typedef typename __node_traits::pointer           __node_pointer;
4898a27ba80SHoward Hinnant
49007b9cd36SEric Fiselier    typedef typename __rebind_alloc_helper<
49107b9cd36SEric Fiselier        allocator_traits<allocator_type>, __begin_node
49207b9cd36SEric Fiselier    >::type                                           __begin_node_allocator;
49307b9cd36SEric Fiselier    typedef typename allocator_traits<__begin_node_allocator>::pointer
49407b9cd36SEric Fiselier                                                      __begin_node_pointer;
4953e519524SHoward Hinnant
4968cef7fd7SEric Fiselier    static_assert((!is_same<allocator_type, __node_allocator>::value),
4978cef7fd7SEric Fiselier                  "internal allocator type must differ from user-specified "
4988cef7fd7SEric Fiselier                  "type; otherwise overload resolution breaks");
4998cef7fd7SEric Fiselier
5003e519524SHoward Hinnant    __compressed_pair<__begin_node, __node_allocator> __before_begin_;
5013e519524SHoward Hinnant
5020af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
50307b9cd36SEric Fiselier    __begin_node_pointer        __before_begin() _NOEXCEPT
50407b9cd36SEric Fiselier        {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());}
5050af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
50607b9cd36SEric Fiselier    __begin_node_pointer __before_begin() const _NOEXCEPT
50707b9cd36SEric Fiselier        {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));}
5083e519524SHoward Hinnant
5090af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
51091a47507SHoward Hinnant          __node_allocator& __alloc() _NOEXCEPT
51191a47507SHoward Hinnant            {return __before_begin_.second();}
5120af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
513f9dc2831SHoward Hinnant    const __node_allocator& __alloc() const _NOEXCEPT
514f9dc2831SHoward Hinnant        {return __before_begin_.second();}
5153e519524SHoward Hinnant
5163e519524SHoward Hinnant    typedef __forward_list_iterator<__node_pointer>             iterator;
5178a27ba80SHoward Hinnant    typedef __forward_list_const_iterator<__node_pointer>       const_iterator;
5183e519524SHoward Hinnant
5190af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5203e519524SHoward Hinnant    __forward_list_base()
52191a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
522549545b6SEric Fiselier        : __before_begin_(__begin_node(), __default_init_tag()) {}
5230af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5248cef7fd7SEric Fiselier    explicit __forward_list_base(const allocator_type& __a)
5253e519524SHoward Hinnant        : __before_begin_(__begin_node(), __node_allocator(__a)) {}
5268cef7fd7SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
5278cef7fd7SEric Fiselier    explicit __forward_list_base(const __node_allocator& __a)
5288cef7fd7SEric Fiselier        : __before_begin_(__begin_node(), __a) {}
52999f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
53091a47507SHoward Hinnantpublic:
531cd31b434SEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
53291a47507SHoward Hinnant    __forward_list_base(__forward_list_base&& __x)
53391a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
534cd31b434SEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
5353e519524SHoward Hinnant    __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
53699f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
5373e519524SHoward Hinnant
5383e519524SHoward Hinnantprivate:
5393e519524SHoward Hinnant    __forward_list_base(const __forward_list_base&);
5403e519524SHoward Hinnant    __forward_list_base& operator=(const __forward_list_base&);
5413e519524SHoward Hinnant
54291a47507SHoward Hinnantpublic:
5433e519524SHoward Hinnant    ~__forward_list_base();
5443e519524SHoward Hinnant
54591a47507SHoward Hinnantprotected:
5460af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5473e519524SHoward Hinnant    void __copy_assign_alloc(const __forward_list_base& __x)
5483e519524SHoward Hinnant        {__copy_assign_alloc(__x, integral_constant<bool,
5493e519524SHoward Hinnant              __node_traits::propagate_on_container_copy_assignment::value>());}
5503e519524SHoward Hinnant
5510af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5523e519524SHoward Hinnant    void __move_assign_alloc(__forward_list_base& __x)
55391a47507SHoward Hinnant        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
55491a47507SHoward Hinnant                   is_nothrow_move_assignable<__node_allocator>::value)
5553e519524SHoward Hinnant        {__move_assign_alloc(__x, integral_constant<bool,
5563e519524SHoward Hinnant              __node_traits::propagate_on_container_move_assignment::value>());}
5573e519524SHoward Hinnant
55891a47507SHoward Hinnantpublic:
559cd31b434SEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
56091a47507SHoward Hinnant    void swap(__forward_list_base& __x)
561e3fbe143SMarshall Clow#if _LIBCPP_STD_VER >= 14
562e3fbe143SMarshall Clow        _NOEXCEPT;
563e3fbe143SMarshall Clow#else
5647adf713aSHyundeok Park        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
56591a47507SHoward Hinnant                    __is_nothrow_swappable<__node_allocator>::value);
566e3fbe143SMarshall Clow#endif
56791a47507SHoward Hinnantprotected:
568f9dc2831SHoward Hinnant    void clear() _NOEXCEPT;
5693e519524SHoward Hinnant
5703e519524SHoward Hinnantprivate:
5710af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5723e519524SHoward Hinnant    void __copy_assign_alloc(const __forward_list_base&, false_type) {}
5730af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5743e519524SHoward Hinnant    void __copy_assign_alloc(const __forward_list_base& __x, true_type)
5753e519524SHoward Hinnant    {
5763e519524SHoward Hinnant        if (__alloc() != __x.__alloc())
5773e519524SHoward Hinnant            clear();
5783e519524SHoward Hinnant        __alloc() = __x.__alloc();
5793e519524SHoward Hinnant    }
5803e519524SHoward Hinnant
5810af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
582fd838227SEric Fiselier    void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT
58391a47507SHoward Hinnant        {}
5840af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
5853e519524SHoward Hinnant    void __move_assign_alloc(__forward_list_base& __x, true_type)
58691a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
587ce48a113SHoward Hinnant        {__alloc() = _VSTD::move(__x.__alloc());}
5883e519524SHoward Hinnant};
5893e519524SHoward Hinnant
59099f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
5913e519524SHoward Hinnant
5923e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
593cd31b434SEvgeniy Stepanovinline
5943e519524SHoward Hinnant__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
59591a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
596ce48a113SHoward Hinnant    : __before_begin_(_VSTD::move(__x.__before_begin_))
5973e519524SHoward Hinnant{
5983e519524SHoward Hinnant    __x.__before_begin()->__next_ = nullptr;
5993e519524SHoward Hinnant}
6003e519524SHoward Hinnant
6013e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
602cd31b434SEvgeniy Stepanovinline
6033e519524SHoward Hinnant__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
6043e519524SHoward Hinnant                                                      const allocator_type& __a)
6053e519524SHoward Hinnant    : __before_begin_(__begin_node(), __node_allocator(__a))
6063e519524SHoward Hinnant{
6073e519524SHoward Hinnant    if (__alloc() == __x.__alloc())
6083e519524SHoward Hinnant    {
6093e519524SHoward Hinnant        __before_begin()->__next_ = __x.__before_begin()->__next_;
6103e519524SHoward Hinnant        __x.__before_begin()->__next_ = nullptr;
6113e519524SHoward Hinnant    }
6123e519524SHoward Hinnant}
6133e519524SHoward Hinnant
61499f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
6153e519524SHoward Hinnant
6163e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
6173e519524SHoward Hinnant__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
6183e519524SHoward Hinnant{
6193e519524SHoward Hinnant    clear();
6203e519524SHoward Hinnant}
6213e519524SHoward Hinnant
6223e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
623cd31b434SEvgeniy Stepanovinline
6243e519524SHoward Hinnantvoid
6253e519524SHoward Hinnant__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
626e3fbe143SMarshall Clow#if _LIBCPP_STD_VER >= 14
627e3fbe143SMarshall Clow        _NOEXCEPT
628e3fbe143SMarshall Clow#else
6297adf713aSHyundeok Park        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
63091a47507SHoward Hinnant                    __is_nothrow_swappable<__node_allocator>::value)
631e3fbe143SMarshall Clow#endif
6323e519524SHoward Hinnant{
6336e965df6SArthur O'Dwyer    _VSTD::__swap_allocator(__alloc(), __x.__alloc(),
634e3fbe143SMarshall Clow            integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
635ce48a113SHoward Hinnant    using _VSTD::swap;
6363e519524SHoward Hinnant    swap(__before_begin()->__next_, __x.__before_begin()->__next_);
6373e519524SHoward Hinnant}
6383e519524SHoward Hinnant
6393e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
6403e519524SHoward Hinnantvoid
641f9dc2831SHoward Hinnant__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
6423e519524SHoward Hinnant{
6433e519524SHoward Hinnant    __node_allocator& __a = __alloc();
6443e519524SHoward Hinnant    for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
6453e519524SHoward Hinnant    {
6463e519524SHoward Hinnant        __node_pointer __next = __p->__next_;
647ce48a113SHoward Hinnant        __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
6483e519524SHoward Hinnant        __node_traits::deallocate(__a, __p, 1);
6493e519524SHoward Hinnant        __p = __next;
6503e519524SHoward Hinnant    }
6513e519524SHoward Hinnant    __before_begin()->__next_ = nullptr;
6523e519524SHoward Hinnant}
6533e519524SHoward Hinnant
654b5d34aa4SMarshall Clowtemplate <class _Tp, class _Alloc /*= allocator<_Tp>*/>
655e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS forward_list
6563e519524SHoward Hinnant    : private __forward_list_base<_Tp, _Alloc>
6573e519524SHoward Hinnant{
6583e519524SHoward Hinnant    typedef __forward_list_base<_Tp, _Alloc> base;
65991a47507SHoward Hinnant    typedef typename base::__node_allocator  __node_allocator;
66091a47507SHoward Hinnant    typedef typename base::__node               __node;
66191a47507SHoward Hinnant    typedef typename base::__node_traits        __node_traits;
66291a47507SHoward Hinnant    typedef typename base::__node_pointer       __node_pointer;
66307b9cd36SEric Fiselier    typedef typename base::__begin_node_pointer __begin_node_pointer;
66491a47507SHoward Hinnant
6653e519524SHoward Hinnantpublic:
6663e519524SHoward Hinnant    typedef _Tp    value_type;
6673e519524SHoward Hinnant    typedef _Alloc allocator_type;
6683e519524SHoward Hinnant
66994f89aeeSMarshall Clow    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
67094f89aeeSMarshall Clow                  "Allocator::value_type must be same type as value_type");
67194f89aeeSMarshall Clow
6723e519524SHoward Hinnant    typedef value_type&                                                 reference;
6733e519524SHoward Hinnant    typedef const value_type&                                           const_reference;
6743e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::pointer          pointer;
6753e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::const_pointer    const_pointer;
6767da4ee6fSKonstantin Varlamov    typedef typename allocator_traits<allocator_type>::size_type        size_type;
6773e519524SHoward Hinnant    typedef typename allocator_traits<allocator_type>::difference_type  difference_type;
6783e519524SHoward Hinnant
6793e519524SHoward Hinnant    typedef typename base::iterator       iterator;
6803e519524SHoward Hinnant    typedef typename base::const_iterator const_iterator;
681f814dcbaSMarshall Clow#if _LIBCPP_STD_VER > 17
682f814dcbaSMarshall Clow    typedef size_type                                __remove_return_type;
683f814dcbaSMarshall Clow#else
684f814dcbaSMarshall Clow    typedef void                                     __remove_return_type;
685f814dcbaSMarshall Clow#endif
6863e519524SHoward Hinnant
68791a47507SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
68891a47507SHoward Hinnant    forward_list()
68991a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
69091a47507SHoward Hinnant        {} // = default;
691cd31b434SEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
6923e519524SHoward Hinnant    explicit forward_list(const allocator_type& __a);
6933e519524SHoward Hinnant    explicit forward_list(size_type __n);
694fb829766SMarshall Clow#if _LIBCPP_STD_VER > 11
695fb829766SMarshall Clow    explicit forward_list(size_type __n, const allocator_type& __a);
696fb829766SMarshall Clow#endif
6973e519524SHoward Hinnant    forward_list(size_type __n, const value_type& __v);
6987da4ee6fSKonstantin Varlamov
6997da4ee6fSKonstantin Varlamov    template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
7007da4ee6fSKonstantin Varlamov    forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a)
7017da4ee6fSKonstantin Varlamov    {
7027da4ee6fSKonstantin Varlamov        insert_after(cbefore_begin(), __n, __v);
7037da4ee6fSKonstantin Varlamov    }
7047da4ee6fSKonstantin Varlamov
7053e519524SHoward Hinnant    template <class _InputIterator>
7063e519524SHoward Hinnant        forward_list(_InputIterator __f, _InputIterator __l,
7074887d047SNikolas Klauser                     __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
7083e519524SHoward Hinnant    template <class _InputIterator>
7093e519524SHoward Hinnant        forward_list(_InputIterator __f, _InputIterator __l,
7103e519524SHoward Hinnant                     const allocator_type& __a,
7114887d047SNikolas Klauser                     __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr);
7123e519524SHoward Hinnant    forward_list(const forward_list& __x);
7133c6bd176SNikolas Klauser    forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
71499f2c001SEric Fiselier
71599f2c001SEric Fiselier    forward_list& operator=(const forward_list& __x);
71699f2c001SEric Fiselier
71799f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
7180af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
71991a47507SHoward Hinnant    forward_list(forward_list&& __x)
72091a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
721ce48a113SHoward Hinnant        : base(_VSTD::move(__x)) {}
7223c6bd176SNikolas Klauser    forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
72399f2c001SEric Fiselier
7243e519524SHoward Hinnant    forward_list(initializer_list<value_type> __il);
7253e519524SHoward Hinnant    forward_list(initializer_list<value_type> __il, const allocator_type& __a);
7263e519524SHoward Hinnant
727cd31b434SEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
72891a47507SHoward Hinnant    forward_list& operator=(forward_list&& __x)
72991a47507SHoward Hinnant        _NOEXCEPT_(
73091a47507SHoward Hinnant             __node_traits::propagate_on_container_move_assignment::value &&
73191a47507SHoward Hinnant             is_nothrow_move_assignable<allocator_type>::value);
73299f2c001SEric Fiselier
733cd31b434SEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
7343e519524SHoward Hinnant    forward_list& operator=(initializer_list<value_type> __il);
73599f2c001SEric Fiselier
73699f2c001SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
73799f2c001SEric Fiselier    void assign(initializer_list<value_type> __il);
73899f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
73999f2c001SEric Fiselier
74099f2c001SEric Fiselier    // ~forward_list() = default;
7413e519524SHoward Hinnant
7423e519524SHoward Hinnant    template <class _InputIterator>
7434887d047SNikolas Klauser    __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
7443e519524SHoward Hinnant        assign(_InputIterator __f, _InputIterator __l);
7453e519524SHoward Hinnant    void assign(size_type __n, const value_type& __v);
7463e519524SHoward Hinnant
7470af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
748f9dc2831SHoward Hinnant    allocator_type get_allocator() const _NOEXCEPT
749f9dc2831SHoward Hinnant        {return allocator_type(base::__alloc());}
7503e519524SHoward Hinnant
7510af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
752f9dc2831SHoward Hinnant    iterator       begin() _NOEXCEPT
753f9dc2831SHoward Hinnant        {return       iterator(base::__before_begin()->__next_);}
7540af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
755f9dc2831SHoward Hinnant    const_iterator begin() const _NOEXCEPT
756f9dc2831SHoward Hinnant        {return const_iterator(base::__before_begin()->__next_);}
7570af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
758f9dc2831SHoward Hinnant    iterator       end() _NOEXCEPT
759f9dc2831SHoward Hinnant        {return       iterator(nullptr);}
7600af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
761f9dc2831SHoward Hinnant    const_iterator end() const _NOEXCEPT
762f9dc2831SHoward Hinnant        {return const_iterator(nullptr);}
7633e519524SHoward Hinnant
7640af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
765f9dc2831SHoward Hinnant    const_iterator cbegin() const _NOEXCEPT
766f9dc2831SHoward Hinnant        {return const_iterator(base::__before_begin()->__next_);}
7670af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
768f9dc2831SHoward Hinnant    const_iterator cend() const _NOEXCEPT
769f9dc2831SHoward Hinnant        {return const_iterator(nullptr);}
7703e519524SHoward Hinnant
7710af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
772f9dc2831SHoward Hinnant    iterator       before_begin() _NOEXCEPT
773f9dc2831SHoward Hinnant        {return       iterator(base::__before_begin());}
7740af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
775f9dc2831SHoward Hinnant    const_iterator before_begin() const _NOEXCEPT
776f9dc2831SHoward Hinnant        {return const_iterator(base::__before_begin());}
7770af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
778f9dc2831SHoward Hinnant    const_iterator cbefore_begin() const _NOEXCEPT
779f9dc2831SHoward Hinnant        {return const_iterator(base::__before_begin());}
7803e519524SHoward Hinnant
78172c8fad4SMarshall Clow    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
782f9dc2831SHoward Hinnant    bool empty() const _NOEXCEPT
783f9dc2831SHoward Hinnant        {return base::__before_begin()->__next_ == nullptr;}
7840af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
78555b31b4eSEric Fiselier    size_type max_size() const _NOEXCEPT {
786d586f92cSArthur O'Dwyer        return _VSTD::min<size_type>(
78755b31b4eSEric Fiselier            __node_traits::max_size(base::__alloc()),
78855b31b4eSEric Fiselier            numeric_limits<difference_type>::max());
78955b31b4eSEric Fiselier    }
7903e519524SHoward Hinnant
7910af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7923e519524SHoward Hinnant    reference       front()       {return base::__before_begin()->__next_->__value_;}
7930af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
7943e519524SHoward Hinnant    const_reference front() const {return base::__before_begin()->__next_->__value_;}
7953e519524SHoward Hinnant
79699f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
79763b560beSMarshall Clow#if _LIBCPP_STD_VER > 14
7980e411641SEric Fiselier    template <class... _Args> reference emplace_front(_Args&&... __args);
79963b560beSMarshall Clow#else
80063b560beSMarshall Clow    template <class... _Args> void      emplace_front(_Args&&... __args);
80163b560beSMarshall Clow#endif
8023e519524SHoward Hinnant    void push_front(value_type&& __v);
80399f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
8043e519524SHoward Hinnant    void push_front(const value_type& __v);
8053e519524SHoward Hinnant
8063e519524SHoward Hinnant    void pop_front();
8073e519524SHoward Hinnant
80899f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
8093e519524SHoward Hinnant    template <class... _Args>
8103e519524SHoward Hinnant        iterator emplace_after(const_iterator __p, _Args&&... __args);
81199f2c001SEric Fiselier
8123e519524SHoward Hinnant    iterator insert_after(const_iterator __p, value_type&& __v);
81399f2c001SEric Fiselier    iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
81499f2c001SEric Fiselier        {return insert_after(__p, __il.begin(), __il.end());}
81599f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
8163e519524SHoward Hinnant    iterator insert_after(const_iterator __p, const value_type& __v);
8173e519524SHoward Hinnant    iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
8183e519524SHoward Hinnant    template <class _InputIterator>
8190af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8204887d047SNikolas Klauser    __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, iterator>
8213e519524SHoward Hinnant        insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
8223e519524SHoward Hinnant
8233db88036SHoward Hinnant    iterator erase_after(const_iterator __p);
8243db88036SHoward Hinnant    iterator erase_after(const_iterator __f, const_iterator __l);
8253e519524SHoward Hinnant
8260af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
82791a47507SHoward Hinnant    void swap(forward_list& __x)
828e3fbe143SMarshall Clow#if _LIBCPP_STD_VER >= 14
829e3fbe143SMarshall Clow        _NOEXCEPT
830e3fbe143SMarshall Clow#else
83191a47507SHoward Hinnant        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
83291a47507SHoward Hinnant                   __is_nothrow_swappable<__node_allocator>::value)
833e3fbe143SMarshall Clow#endif
83491a47507SHoward Hinnant        {base::swap(__x);}
8353e519524SHoward Hinnant
8363e519524SHoward Hinnant    void resize(size_type __n);
8373e519524SHoward Hinnant    void resize(size_type __n, const value_type& __v);
8380af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
839f9dc2831SHoward Hinnant    void clear() _NOEXCEPT {base::clear();}
8403e519524SHoward Hinnant
841eb92df7eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8423e519524SHoward Hinnant    void splice_after(const_iterator __p, forward_list&& __x);
843eb92df7eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8443e519524SHoward Hinnant    void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
845eb92df7eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8463e519524SHoward Hinnant    void splice_after(const_iterator __p, forward_list&& __x,
8473e519524SHoward Hinnant                      const_iterator __f, const_iterator __l);
8483e519524SHoward Hinnant    void splice_after(const_iterator __p, forward_list& __x);
8493e519524SHoward Hinnant    void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
8503e519524SHoward Hinnant    void splice_after(const_iterator __p, forward_list& __x,
8513e519524SHoward Hinnant                      const_iterator __f, const_iterator __l);
852f814dcbaSMarshall Clow    __remove_return_type remove(const value_type& __v);
853f814dcbaSMarshall Clow    template <class _Predicate> __remove_return_type remove_if(_Predicate __pred);
8540af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
855f814dcbaSMarshall Clow    __remove_return_type unique() {return unique(__equal_to<value_type>());}
856f814dcbaSMarshall Clow    template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred);
85799f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
8580af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
859eb92df7eSHoward Hinnant    void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
860eb92df7eSHoward Hinnant    template <class _Compare>
861eb92df7eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
862eb92df7eSHoward Hinnant        void merge(forward_list&& __x, _Compare __comp)
863ce48a113SHoward Hinnant        {merge(__x, _VSTD::move(__comp));}
86499f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
8650af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8663e519524SHoward Hinnant    void merge(forward_list& __x) {merge(__x, __less<value_type>());}
8673e519524SHoward Hinnant    template <class _Compare> void merge(forward_list& __x, _Compare __comp);
8680af133f9SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8693e519524SHoward Hinnant    void sort() {sort(__less<value_type>());}
870cd31b434SEvgeniy Stepanov    template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
871f9dc2831SHoward Hinnant    void reverse() _NOEXCEPT;
8723e519524SHoward Hinnant
8733e519524SHoward Hinnantprivate:
8743e519524SHoward Hinnant
87599f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
87691a47507SHoward Hinnant    void __move_assign(forward_list& __x, true_type)
87791a47507SHoward Hinnant        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
8783e519524SHoward Hinnant    void __move_assign(forward_list& __x, false_type);
87999f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
8803e519524SHoward Hinnant
8813e519524SHoward Hinnant    template <class _Compare>
8823e519524SHoward Hinnant        static
8833e519524SHoward Hinnant        __node_pointer
8843e519524SHoward Hinnant        __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
8853e519524SHoward Hinnant
8863e519524SHoward Hinnant    template <class _Compare>
8873e519524SHoward Hinnant        static
8883e519524SHoward Hinnant        __node_pointer
8893e519524SHoward Hinnant        __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
8903e519524SHoward Hinnant};
8913e519524SHoward Hinnant
892e076700bSMarshall Clow
89301666904SLouis Dionne#if _LIBCPP_STD_VER >= 17
894e076700bSMarshall Clowtemplate<class _InputIterator,
895199d2ebeSArthur O'Dwyer         class _Alloc = allocator<__iter_value_type<_InputIterator>>,
89668072a71SKonstantin Varlamov         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
8974e0ea2cfSLouis Dionne         class = enable_if_t<__is_allocator<_Alloc>::value>
898e076700bSMarshall Clow         >
899e076700bSMarshall Clowforward_list(_InputIterator, _InputIterator)
900199d2ebeSArthur O'Dwyer  -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
901e076700bSMarshall Clow
902e076700bSMarshall Clowtemplate<class _InputIterator,
903e076700bSMarshall Clow         class _Alloc,
90468072a71SKonstantin Varlamov         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
9054e0ea2cfSLouis Dionne         class = enable_if_t<__is_allocator<_Alloc>::value>
906e076700bSMarshall Clow         >
907e076700bSMarshall Clowforward_list(_InputIterator, _InputIterator, _Alloc)
908199d2ebeSArthur O'Dwyer  -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
909e076700bSMarshall Clow#endif
910e076700bSMarshall Clow
9113e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
912cd31b434SEvgeniy Stepanovinline
9133e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
9143e519524SHoward Hinnant    : base(__a)
9153e519524SHoward Hinnant{
9163e519524SHoward Hinnant}
9173e519524SHoward Hinnant
9183e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
9193e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(size_type __n)
9203e519524SHoward Hinnant{
9213e519524SHoward Hinnant    if (__n > 0)
9223e519524SHoward Hinnant    {
9233e519524SHoward Hinnant        __node_allocator& __a = base::__alloc();
924c003db1fSHoward Hinnant        typedef __allocator_destructor<__node_allocator> _Dp;
925c003db1fSHoward Hinnant        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
92607b9cd36SEric Fiselier        for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
92707b9cd36SEric Fiselier                                                             __p = __p->__next_as_begin())
9283e519524SHoward Hinnant        {
9293e519524SHoward Hinnant            __h.reset(__node_traits::allocate(__a, 1));
930ce48a113SHoward Hinnant            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
9313e519524SHoward Hinnant            __h->__next_ = nullptr;
9323e519524SHoward Hinnant            __p->__next_ = __h.release();
9333e519524SHoward Hinnant        }
9343e519524SHoward Hinnant    }
9353e519524SHoward Hinnant}
9363e519524SHoward Hinnant
937fb829766SMarshall Clow#if _LIBCPP_STD_VER > 11
938fb829766SMarshall Clowtemplate <class _Tp, class _Alloc>
939572e6deeSEric Fiselierforward_list<_Tp, _Alloc>::forward_list(size_type __n,
940572e6deeSEric Fiselier                                        const allocator_type& __base_alloc)
941572e6deeSEric Fiselier    : base ( __base_alloc )
942fb829766SMarshall Clow{
943fb829766SMarshall Clow    if (__n > 0)
944fb829766SMarshall Clow    {
945fb829766SMarshall Clow        __node_allocator& __a = base::__alloc();
946fb829766SMarshall Clow        typedef __allocator_destructor<__node_allocator> _Dp;
947fb829766SMarshall Clow        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
94807b9cd36SEric Fiselier        for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
94907b9cd36SEric Fiselier                                                             __p = __p->__next_as_begin())
950fb829766SMarshall Clow        {
951fb829766SMarshall Clow            __h.reset(__node_traits::allocate(__a, 1));
952fb829766SMarshall Clow            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
953fb829766SMarshall Clow            __h->__next_ = nullptr;
954fb829766SMarshall Clow            __p->__next_ = __h.release();
955fb829766SMarshall Clow        }
956fb829766SMarshall Clow    }
957fb829766SMarshall Clow}
958fb829766SMarshall Clow#endif
959fb829766SMarshall Clow
9603e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
9613e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
9623e519524SHoward Hinnant{
9633e519524SHoward Hinnant    insert_after(cbefore_begin(), __n, __v);
9643e519524SHoward Hinnant}
9653e519524SHoward Hinnant
9663e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
9673e519524SHoward Hinnanttemplate <class _InputIterator>
9683e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
9694887d047SNikolas Klauser                                        __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
9703e519524SHoward Hinnant{
9713e519524SHoward Hinnant    insert_after(cbefore_begin(), __f, __l);
9723e519524SHoward Hinnant}
9733e519524SHoward Hinnant
9743e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
9753e519524SHoward Hinnanttemplate <class _InputIterator>
9763e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
9773e519524SHoward Hinnant                                        const allocator_type& __a,
9784887d047SNikolas Klauser                                        __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*)
9793e519524SHoward Hinnant    : base(__a)
9803e519524SHoward Hinnant{
9813e519524SHoward Hinnant    insert_after(cbefore_begin(), __f, __l);
9823e519524SHoward Hinnant}
9833e519524SHoward Hinnant
9843e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
9853e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
9868cef7fd7SEric Fiselier    : base(
9878cef7fd7SEric Fiselier          __node_traits::select_on_container_copy_construction(__x.__alloc())) {
9883e519524SHoward Hinnant  insert_after(cbefore_begin(), __x.begin(), __x.end());
9893e519524SHoward Hinnant}
9903e519524SHoward Hinnant
9913e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
9923e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
9933c6bd176SNikolas Klauser                                        const __type_identity_t<allocator_type>& __a)
9943e519524SHoward Hinnant    : base(__a)
9953e519524SHoward Hinnant{
9963e519524SHoward Hinnant    insert_after(cbefore_begin(), __x.begin(), __x.end());
9973e519524SHoward Hinnant}
9983e519524SHoward Hinnant
99999f2c001SEric Fiseliertemplate <class _Tp, class _Alloc>
100099f2c001SEric Fiselierforward_list<_Tp, _Alloc>&
100199f2c001SEric Fiselierforward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
100299f2c001SEric Fiselier{
1003b8608b87SMark de Wever    if (this != _VSTD::addressof(__x))
100499f2c001SEric Fiselier    {
100599f2c001SEric Fiselier        base::__copy_assign_alloc(__x);
100699f2c001SEric Fiselier        assign(__x.begin(), __x.end());
100799f2c001SEric Fiselier    }
100899f2c001SEric Fiselier    return *this;
100999f2c001SEric Fiselier}
10103e519524SHoward Hinnant
101199f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
10123e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
10133e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
10143c6bd176SNikolas Klauser                                        const __type_identity_t<allocator_type>& __a)
1015ce48a113SHoward Hinnant    : base(_VSTD::move(__x), __a)
10163e519524SHoward Hinnant{
10173e519524SHoward Hinnant    if (base::__alloc() != __x.__alloc())
10183e519524SHoward Hinnant    {
1019c003db1fSHoward Hinnant        typedef move_iterator<iterator> _Ip;
1020c003db1fSHoward Hinnant        insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
10213e519524SHoward Hinnant    }
10223e519524SHoward Hinnant}
10233e519524SHoward Hinnant
10243e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
10253e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
10263e519524SHoward Hinnant{
10273e519524SHoward Hinnant    insert_after(cbefore_begin(), __il.begin(), __il.end());
10283e519524SHoward Hinnant}
10293e519524SHoward Hinnant
10303e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
10313e519524SHoward Hinnantforward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
10323e519524SHoward Hinnant                                        const allocator_type& __a)
10333e519524SHoward Hinnant    : base(__a)
10343e519524SHoward Hinnant{
10353e519524SHoward Hinnant    insert_after(cbefore_begin(), __il.begin(), __il.end());
10363e519524SHoward Hinnant}
10373e519524SHoward Hinnant
10383e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
10393e519524SHoward Hinnantvoid
10403e519524SHoward Hinnantforward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
104191a47507SHoward Hinnant    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
10423e519524SHoward Hinnant{
10433e519524SHoward Hinnant    clear();
10443e519524SHoward Hinnant    base::__move_assign_alloc(__x);
10453e519524SHoward Hinnant    base::__before_begin()->__next_ = __x.__before_begin()->__next_;
10463e519524SHoward Hinnant    __x.__before_begin()->__next_ = nullptr;
10473e519524SHoward Hinnant}
10483e519524SHoward Hinnant
10493e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
10503e519524SHoward Hinnantvoid
10513e519524SHoward Hinnantforward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
10523e519524SHoward Hinnant{
10533e519524SHoward Hinnant    if (base::__alloc() == __x.__alloc())
10543e519524SHoward Hinnant        __move_assign(__x, true_type());
10553e519524SHoward Hinnant    else
10563e519524SHoward Hinnant    {
1057c003db1fSHoward Hinnant        typedef move_iterator<iterator> _Ip;
1058c003db1fSHoward Hinnant        assign(_Ip(__x.begin()), _Ip(__x.end()));
10593e519524SHoward Hinnant    }
10603e519524SHoward Hinnant}
10613e519524SHoward Hinnant
10623e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
1063cd31b434SEvgeniy Stepanovinline
10643e519524SHoward Hinnantforward_list<_Tp, _Alloc>&
10653e519524SHoward Hinnantforward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
106691a47507SHoward Hinnant    _NOEXCEPT_(
106791a47507SHoward Hinnant             __node_traits::propagate_on_container_move_assignment::value &&
106891a47507SHoward Hinnant             is_nothrow_move_assignable<allocator_type>::value)
10693e519524SHoward Hinnant{
10703e519524SHoward Hinnant    __move_assign(__x, integral_constant<bool,
10713e519524SHoward Hinnant          __node_traits::propagate_on_container_move_assignment::value>());
10723e519524SHoward Hinnant    return *this;
10733e519524SHoward Hinnant}
10743e519524SHoward Hinnant
10753e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
1076cd31b434SEvgeniy Stepanovinline
10773e519524SHoward Hinnantforward_list<_Tp, _Alloc>&
10783e519524SHoward Hinnantforward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
10793e519524SHoward Hinnant{
10803e519524SHoward Hinnant    assign(__il.begin(), __il.end());
10813e519524SHoward Hinnant    return *this;
10823e519524SHoward Hinnant}
10833e519524SHoward Hinnant
108499f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
108554976f26SHoward Hinnant
10863e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
10873e519524SHoward Hinnanttemplate <class _InputIterator>
10884887d047SNikolas Klauser__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>
10893e519524SHoward Hinnantforward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
10903e519524SHoward Hinnant{
10913e519524SHoward Hinnant    iterator __i = before_begin();
1092ce48a113SHoward Hinnant    iterator __j = _VSTD::next(__i);
10933e519524SHoward Hinnant    iterator __e = end();
1094910285b2SEric Fiselier    for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
10953e519524SHoward Hinnant        *__j = *__f;
10963e519524SHoward Hinnant    if (__j == __e)
10973e519524SHoward Hinnant        insert_after(__i, __f, __l);
10983e519524SHoward Hinnant    else
10993e519524SHoward Hinnant        erase_after(__i, __e);
11003e519524SHoward Hinnant}
11013e519524SHoward Hinnant
11023e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
11033e519524SHoward Hinnantvoid
11043e519524SHoward Hinnantforward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
11053e519524SHoward Hinnant{
11063e519524SHoward Hinnant    iterator __i = before_begin();
1107ce48a113SHoward Hinnant    iterator __j = _VSTD::next(__i);
11083e519524SHoward Hinnant    iterator __e = end();
11093e519524SHoward Hinnant    for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
11103e519524SHoward Hinnant        *__j = __v;
11113e519524SHoward Hinnant    if (__j == __e)
11123e519524SHoward Hinnant        insert_after(__i, __n, __v);
11133e519524SHoward Hinnant    else
11143e519524SHoward Hinnant        erase_after(__i, __e);
11153e519524SHoward Hinnant}
11163e519524SHoward Hinnant
111799f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
111854976f26SHoward Hinnant
11193e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
1120cd31b434SEvgeniy Stepanovinline
11213e519524SHoward Hinnantvoid
11223e519524SHoward Hinnantforward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
11233e519524SHoward Hinnant{
11243e519524SHoward Hinnant    assign(__il.begin(), __il.end());
11253e519524SHoward Hinnant}
11263e519524SHoward Hinnant
11273e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
11283e519524SHoward Hinnanttemplate <class... _Args>
112963b560beSMarshall Clow#if _LIBCPP_STD_VER > 14
11300e411641SEric Fiseliertypename forward_list<_Tp, _Alloc>::reference
113163b560beSMarshall Clow#else
113263b560beSMarshall Clowvoid
113363b560beSMarshall Clow#endif
11343e519524SHoward Hinnantforward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
11353e519524SHoward Hinnant{
11363e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1137c003db1fSHoward Hinnant    typedef __allocator_destructor<__node_allocator> _Dp;
1138c003db1fSHoward Hinnant    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1139ce48a113SHoward Hinnant    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1140ce48a113SHoward Hinnant                                  _VSTD::forward<_Args>(__args)...);
11413e519524SHoward Hinnant    __h->__next_ = base::__before_begin()->__next_;
11423e519524SHoward Hinnant    base::__before_begin()->__next_ = __h.release();
114363b560beSMarshall Clow#if _LIBCPP_STD_VER > 14
11440e411641SEric Fiselier    return base::__before_begin()->__next_->__value_;
114563b560beSMarshall Clow#endif
11463e519524SHoward Hinnant}
11473e519524SHoward Hinnant
11483e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
11493e519524SHoward Hinnantvoid
11503e519524SHoward Hinnantforward_list<_Tp, _Alloc>::push_front(value_type&& __v)
11513e519524SHoward Hinnant{
11523e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1153c003db1fSHoward Hinnant    typedef __allocator_destructor<__node_allocator> _Dp;
1154c003db1fSHoward Hinnant    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1155ce48a113SHoward Hinnant    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
11563e519524SHoward Hinnant    __h->__next_ = base::__before_begin()->__next_;
11573e519524SHoward Hinnant    base::__before_begin()->__next_ = __h.release();
11583e519524SHoward Hinnant}
11593e519524SHoward Hinnant
116099f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
11613e519524SHoward Hinnant
11623e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
11633e519524SHoward Hinnantvoid
11643e519524SHoward Hinnantforward_list<_Tp, _Alloc>::push_front(const value_type& __v)
11653e519524SHoward Hinnant{
11663e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1167c003db1fSHoward Hinnant    typedef __allocator_destructor<__node_allocator> _Dp;
1168c003db1fSHoward Hinnant    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1169ce48a113SHoward Hinnant    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
11703e519524SHoward Hinnant    __h->__next_ = base::__before_begin()->__next_;
11713e519524SHoward Hinnant    base::__before_begin()->__next_ = __h.release();
11723e519524SHoward Hinnant}
11733e519524SHoward Hinnant
11743e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
11753e519524SHoward Hinnantvoid
11763e519524SHoward Hinnantforward_list<_Tp, _Alloc>::pop_front()
11773e519524SHoward Hinnant{
11783e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
11793e519524SHoward Hinnant    __node_pointer __p = base::__before_begin()->__next_;
11803e519524SHoward Hinnant    base::__before_begin()->__next_ = __p->__next_;
1181ce48a113SHoward Hinnant    __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
11823e519524SHoward Hinnant    __node_traits::deallocate(__a, __p, 1);
11833e519524SHoward Hinnant}
11843e519524SHoward Hinnant
118599f2c001SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
11863e519524SHoward Hinnant
11873e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
11883e519524SHoward Hinnanttemplate <class... _Args>
11893e519524SHoward Hinnanttypename forward_list<_Tp, _Alloc>::iterator
11903e519524SHoward Hinnantforward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
11913e519524SHoward Hinnant{
119207b9cd36SEric Fiselier    __begin_node_pointer const __r = __p.__get_begin();
11933e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1194c003db1fSHoward Hinnant    typedef __allocator_destructor<__node_allocator> _Dp;
1195c003db1fSHoward Hinnant    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1196ce48a113SHoward Hinnant    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1197ce48a113SHoward Hinnant                                  _VSTD::forward<_Args>(__args)...);
11983e519524SHoward Hinnant    __h->__next_ = __r->__next_;
11993e519524SHoward Hinnant    __r->__next_ = __h.release();
12003e519524SHoward Hinnant    return iterator(__r->__next_);
12013e519524SHoward Hinnant}
12023e519524SHoward Hinnant
12033e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
12043e519524SHoward Hinnanttypename forward_list<_Tp, _Alloc>::iterator
12053e519524SHoward Hinnantforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
12063e519524SHoward Hinnant{
120707b9cd36SEric Fiselier    __begin_node_pointer const __r = __p.__get_begin();
12083e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1209c003db1fSHoward Hinnant    typedef __allocator_destructor<__node_allocator> _Dp;
1210c003db1fSHoward Hinnant    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1211ce48a113SHoward Hinnant    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
12123e519524SHoward Hinnant    __h->__next_ = __r->__next_;
12133e519524SHoward Hinnant    __r->__next_ = __h.release();
12143e519524SHoward Hinnant    return iterator(__r->__next_);
12153e519524SHoward Hinnant}
12163e519524SHoward Hinnant
121799f2c001SEric Fiselier#endif // _LIBCPP_CXX03_LANG
12183e519524SHoward Hinnant
12193e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
12203e519524SHoward Hinnanttypename forward_list<_Tp, _Alloc>::iterator
12213e519524SHoward Hinnantforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
12223e519524SHoward Hinnant{
122307b9cd36SEric Fiselier    __begin_node_pointer const __r = __p.__get_begin();
12243e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1225c003db1fSHoward Hinnant    typedef __allocator_destructor<__node_allocator> _Dp;
1226c003db1fSHoward Hinnant    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1227ce48a113SHoward Hinnant    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
12283e519524SHoward Hinnant    __h->__next_ = __r->__next_;
12293e519524SHoward Hinnant    __r->__next_ = __h.release();
12303e519524SHoward Hinnant    return iterator(__r->__next_);
12313e519524SHoward Hinnant}
12323e519524SHoward Hinnant
12333e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
12343e519524SHoward Hinnanttypename forward_list<_Tp, _Alloc>::iterator
12353e519524SHoward Hinnantforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
12363e519524SHoward Hinnant                                        const value_type& __v)
12373e519524SHoward Hinnant{
123807b9cd36SEric Fiselier    __begin_node_pointer __r = __p.__get_begin();
12393e519524SHoward Hinnant    if (__n > 0)
12403e519524SHoward Hinnant    {
12413e519524SHoward Hinnant        __node_allocator& __a = base::__alloc();
1242c003db1fSHoward Hinnant        typedef __allocator_destructor<__node_allocator> _Dp;
1243c003db1fSHoward Hinnant        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1244ce48a113SHoward Hinnant        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
12453e519524SHoward Hinnant        __node_pointer __first = __h.release();
12463e519524SHoward Hinnant        __node_pointer __last = __first;
12473e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
12483e519524SHoward Hinnant        try
12493e519524SHoward Hinnant        {
1250b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
12513e519524SHoward Hinnant            for (--__n; __n != 0; --__n, __last = __last->__next_)
12523e519524SHoward Hinnant            {
12533e519524SHoward Hinnant                __h.reset(__node_traits::allocate(__a, 1));
1254ce48a113SHoward Hinnant                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
12553e519524SHoward Hinnant                __last->__next_ = __h.release();
12563e519524SHoward Hinnant            }
12573e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
12583e519524SHoward Hinnant        }
12593e519524SHoward Hinnant        catch (...)
12603e519524SHoward Hinnant        {
12613e519524SHoward Hinnant            while (__first != nullptr)
12623e519524SHoward Hinnant            {
12633e519524SHoward Hinnant                __node_pointer __next = __first->__next_;
1264ce48a113SHoward Hinnant                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
12653e519524SHoward Hinnant                __node_traits::deallocate(__a, __first, 1);
12663e519524SHoward Hinnant                __first = __next;
12673e519524SHoward Hinnant            }
12683e519524SHoward Hinnant            throw;
12693e519524SHoward Hinnant        }
1270b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
12713e519524SHoward Hinnant        __last->__next_ = __r->__next_;
12723e519524SHoward Hinnant        __r->__next_ = __first;
127307b9cd36SEric Fiselier        __r = static_cast<__begin_node_pointer>(__last);
12743e519524SHoward Hinnant    }
12753e519524SHoward Hinnant    return iterator(__r);
12763e519524SHoward Hinnant}
12773e519524SHoward Hinnant
12783e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
12793e519524SHoward Hinnanttemplate <class _InputIterator>
12804887d047SNikolas Klauser__enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator>
12813e519524SHoward Hinnantforward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
12823e519524SHoward Hinnant                                        _InputIterator __f, _InputIterator __l)
12833e519524SHoward Hinnant{
128407b9cd36SEric Fiselier    __begin_node_pointer __r = __p.__get_begin();
12853e519524SHoward Hinnant    if (__f != __l)
12863e519524SHoward Hinnant    {
12873e519524SHoward Hinnant        __node_allocator& __a = base::__alloc();
1288c003db1fSHoward Hinnant        typedef __allocator_destructor<__node_allocator> _Dp;
1289c003db1fSHoward Hinnant        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1290ce48a113SHoward Hinnant        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
12913e519524SHoward Hinnant        __node_pointer __first = __h.release();
12923e519524SHoward Hinnant        __node_pointer __last = __first;
12933e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
12943e519524SHoward Hinnant        try
12953e519524SHoward Hinnant        {
1296b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
1297910285b2SEric Fiselier            for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
12983e519524SHoward Hinnant            {
12993e519524SHoward Hinnant                __h.reset(__node_traits::allocate(__a, 1));
1300ce48a113SHoward Hinnant                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
13013e519524SHoward Hinnant                __last->__next_ = __h.release();
13023e519524SHoward Hinnant            }
13033e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
13043e519524SHoward Hinnant        }
13053e519524SHoward Hinnant        catch (...)
13063e519524SHoward Hinnant        {
13073e519524SHoward Hinnant            while (__first != nullptr)
13083e519524SHoward Hinnant            {
13093e519524SHoward Hinnant                __node_pointer __next = __first->__next_;
1310ce48a113SHoward Hinnant                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
13113e519524SHoward Hinnant                __node_traits::deallocate(__a, __first, 1);
13123e519524SHoward Hinnant                __first = __next;
13133e519524SHoward Hinnant            }
13143e519524SHoward Hinnant            throw;
13153e519524SHoward Hinnant        }
1316b3371f6fSHoward Hinnant#endif // _LIBCPP_NO_EXCEPTIONS
13173e519524SHoward Hinnant        __last->__next_ = __r->__next_;
13183e519524SHoward Hinnant        __r->__next_ = __first;
131907b9cd36SEric Fiselier        __r = static_cast<__begin_node_pointer>(__last);
13203e519524SHoward Hinnant    }
13213e519524SHoward Hinnant    return iterator(__r);
13223e519524SHoward Hinnant}
13233e519524SHoward Hinnant
13243e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
13253db88036SHoward Hinnanttypename forward_list<_Tp, _Alloc>::iterator
13263e519524SHoward Hinnantforward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
13273e519524SHoward Hinnant{
132807b9cd36SEric Fiselier    __begin_node_pointer __p = __f.__get_begin();
13293e519524SHoward Hinnant    __node_pointer __n = __p->__next_;
13303e519524SHoward Hinnant    __p->__next_ = __n->__next_;
13313e519524SHoward Hinnant    __node_allocator& __a = base::__alloc();
1332ce48a113SHoward Hinnant    __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
13333e519524SHoward Hinnant    __node_traits::deallocate(__a, __n, 1);
13343db88036SHoward Hinnant    return iterator(__p->__next_);
13353e519524SHoward Hinnant}
13363e519524SHoward Hinnant
13373e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
13383db88036SHoward Hinnanttypename forward_list<_Tp, _Alloc>::iterator
13393e519524SHoward Hinnantforward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
13403e519524SHoward Hinnant{
134107b9cd36SEric Fiselier    __node_pointer __e = __l.__get_unsafe_node_pointer();
13423e519524SHoward Hinnant    if (__f != __l)
13433e519524SHoward Hinnant    {
134407b9cd36SEric Fiselier        __begin_node_pointer __bp = __f.__get_begin();
134507b9cd36SEric Fiselier
134607b9cd36SEric Fiselier        __node_pointer __n = __bp->__next_;
13473e519524SHoward Hinnant        if (__n != __e)
13483e519524SHoward Hinnant        {
134907b9cd36SEric Fiselier            __bp->__next_ = __e;
13503e519524SHoward Hinnant            __node_allocator& __a = base::__alloc();
13513e519524SHoward Hinnant            do
13523e519524SHoward Hinnant            {
135307b9cd36SEric Fiselier                __node_pointer __tmp = __n->__next_;
1354ce48a113SHoward Hinnant                __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
13553e519524SHoward Hinnant                __node_traits::deallocate(__a, __n, 1);
135607b9cd36SEric Fiselier                __n = __tmp;
13573e519524SHoward Hinnant            } while (__n != __e);
13583e519524SHoward Hinnant        }
13593e519524SHoward Hinnant    }
13603db88036SHoward Hinnant    return iterator(__e);
13613e519524SHoward Hinnant}
13623e519524SHoward Hinnant
13633e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
13643e519524SHoward Hinnantvoid
13653e519524SHoward Hinnantforward_list<_Tp, _Alloc>::resize(size_type __n)
13663e519524SHoward Hinnant{
13673e519524SHoward Hinnant    size_type __sz = 0;
13683e519524SHoward Hinnant    iterator __p = before_begin();
13693e519524SHoward Hinnant    iterator __i = begin();
13703e519524SHoward Hinnant    iterator __e = end();
13713e519524SHoward Hinnant    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
13723e519524SHoward Hinnant        ;
13733e519524SHoward Hinnant    if (__i != __e)
13743e519524SHoward Hinnant        erase_after(__p, __e);
13753e519524SHoward Hinnant    else
13763e519524SHoward Hinnant    {
13773e519524SHoward Hinnant        __n -= __sz;
13783e519524SHoward Hinnant        if (__n > 0)
13793e519524SHoward Hinnant        {
13803e519524SHoward Hinnant            __node_allocator& __a = base::__alloc();
1381c003db1fSHoward Hinnant            typedef __allocator_destructor<__node_allocator> _Dp;
1382c003db1fSHoward Hinnant            unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
138307b9cd36SEric Fiselier            for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
138407b9cd36SEric Fiselier                                                         __ptr = __ptr->__next_as_begin())
13853e519524SHoward Hinnant            {
13863e519524SHoward Hinnant                __h.reset(__node_traits::allocate(__a, 1));
1387ce48a113SHoward Hinnant                __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
13883e519524SHoward Hinnant                __h->__next_ = nullptr;
13893e519524SHoward Hinnant                __ptr->__next_ = __h.release();
13903e519524SHoward Hinnant            }
13913e519524SHoward Hinnant        }
13923e519524SHoward Hinnant    }
13933e519524SHoward Hinnant}
13943e519524SHoward Hinnant
13953e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
13963e519524SHoward Hinnantvoid
13973e519524SHoward Hinnantforward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
13983e519524SHoward Hinnant{
13993e519524SHoward Hinnant    size_type __sz = 0;
14003e519524SHoward Hinnant    iterator __p = before_begin();
14013e519524SHoward Hinnant    iterator __i = begin();
14023e519524SHoward Hinnant    iterator __e = end();
14033e519524SHoward Hinnant    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
14043e519524SHoward Hinnant        ;
14053e519524SHoward Hinnant    if (__i != __e)
14063e519524SHoward Hinnant        erase_after(__p, __e);
14073e519524SHoward Hinnant    else
14083e519524SHoward Hinnant    {
14093e519524SHoward Hinnant        __n -= __sz;
14103e519524SHoward Hinnant        if (__n > 0)
14113e519524SHoward Hinnant        {
14123e519524SHoward Hinnant            __node_allocator& __a = base::__alloc();
1413c003db1fSHoward Hinnant            typedef __allocator_destructor<__node_allocator> _Dp;
1414c003db1fSHoward Hinnant            unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
141507b9cd36SEric Fiselier            for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
141607b9cd36SEric Fiselier                                                         __ptr = __ptr->__next_as_begin())
14173e519524SHoward Hinnant            {
14183e519524SHoward Hinnant                __h.reset(__node_traits::allocate(__a, 1));
1419ce48a113SHoward Hinnant                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
14203e519524SHoward Hinnant                __h->__next_ = nullptr;
14213e519524SHoward Hinnant                __ptr->__next_ = __h.release();
14223e519524SHoward Hinnant            }
14233e519524SHoward Hinnant        }
14243e519524SHoward Hinnant    }
14253e519524SHoward Hinnant}
14263e519524SHoward Hinnant
14273e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
14283e519524SHoward Hinnantvoid
14293e519524SHoward Hinnantforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
14303e519524SHoward Hinnant                                        forward_list& __x)
14313e519524SHoward Hinnant{
14323e519524SHoward Hinnant    if (!__x.empty())
14333e519524SHoward Hinnant    {
143407b9cd36SEric Fiselier        if (__p.__get_begin()->__next_ != nullptr)
14353e519524SHoward Hinnant        {
14363e519524SHoward Hinnant            const_iterator __lm1 = __x.before_begin();
143707b9cd36SEric Fiselier            while (__lm1.__get_begin()->__next_ != nullptr)
14383e519524SHoward Hinnant                ++__lm1;
143907b9cd36SEric Fiselier            __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
14403e519524SHoward Hinnant        }
144107b9cd36SEric Fiselier        __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
14428a27ba80SHoward Hinnant        __x.__before_begin()->__next_ = nullptr;
14433e519524SHoward Hinnant    }
14443e519524SHoward Hinnant}
14453e519524SHoward Hinnant
14463e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
14473e519524SHoward Hinnantvoid
14483e519524SHoward Hinnantforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1449fd838227SEric Fiselier                                        forward_list& /*__other*/,
14503e519524SHoward Hinnant                                        const_iterator __i)
14513e519524SHoward Hinnant{
1452ce48a113SHoward Hinnant    const_iterator __lm1 = _VSTD::next(__i);
14533e519524SHoward Hinnant    if (__p != __i && __p != __lm1)
14543e519524SHoward Hinnant    {
145507b9cd36SEric Fiselier        __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
145607b9cd36SEric Fiselier        __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
145707b9cd36SEric Fiselier        __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
14583e519524SHoward Hinnant    }
14593e519524SHoward Hinnant}
14603e519524SHoward Hinnant
14613e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
14623e519524SHoward Hinnantvoid
14633e519524SHoward Hinnantforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1464fd838227SEric Fiselier                                        forward_list& /*__other*/,
14653e519524SHoward Hinnant                                        const_iterator __f, const_iterator __l)
14663e519524SHoward Hinnant{
14673e519524SHoward Hinnant    if (__f != __l && __p != __f)
14683e519524SHoward Hinnant    {
14693e519524SHoward Hinnant        const_iterator __lm1 = __f;
147007b9cd36SEric Fiselier        while (__lm1.__get_begin()->__next_ != __l.__get_begin())
14713e519524SHoward Hinnant            ++__lm1;
14723e519524SHoward Hinnant        if (__f != __lm1)
14733e519524SHoward Hinnant        {
147407b9cd36SEric Fiselier            __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
147507b9cd36SEric Fiselier            __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
147607b9cd36SEric Fiselier            __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
14773e519524SHoward Hinnant        }
14783e519524SHoward Hinnant    }
14793e519524SHoward Hinnant}
14803e519524SHoward Hinnant
1481eb92df7eSHoward Hinnanttemplate <class _Tp, class _Alloc>
1482eb92df7eSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1483eb92df7eSHoward Hinnantvoid
1484eb92df7eSHoward Hinnantforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1485eb92df7eSHoward Hinnant                                        forward_list&& __x)
1486eb92df7eSHoward Hinnant{
1487eb92df7eSHoward Hinnant    splice_after(__p, __x);
1488eb92df7eSHoward Hinnant}
1489eb92df7eSHoward Hinnant
1490eb92df7eSHoward Hinnanttemplate <class _Tp, class _Alloc>
1491eb92df7eSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1492eb92df7eSHoward Hinnantvoid
1493eb92df7eSHoward Hinnantforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1494eb92df7eSHoward Hinnant                                        forward_list&& __x,
1495eb92df7eSHoward Hinnant                                        const_iterator __i)
1496eb92df7eSHoward Hinnant{
1497eb92df7eSHoward Hinnant    splice_after(__p, __x, __i);
1498eb92df7eSHoward Hinnant}
1499eb92df7eSHoward Hinnant
1500eb92df7eSHoward Hinnanttemplate <class _Tp, class _Alloc>
1501eb92df7eSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1502eb92df7eSHoward Hinnantvoid
1503eb92df7eSHoward Hinnantforward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1504eb92df7eSHoward Hinnant                                        forward_list&& __x,
1505eb92df7eSHoward Hinnant                                        const_iterator __f, const_iterator __l)
1506eb92df7eSHoward Hinnant{
1507eb92df7eSHoward Hinnant    splice_after(__p, __x, __f, __l);
1508eb92df7eSHoward Hinnant}
1509eb92df7eSHoward Hinnant
15103e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
1511f814dcbaSMarshall Clowtypename forward_list<_Tp, _Alloc>::__remove_return_type
15123e519524SHoward Hinnantforward_list<_Tp, _Alloc>::remove(const value_type& __v)
15133e519524SHoward Hinnant{
1514896b0c7bSMarshall Clow    forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
151524edf8efSMarshall Clow    typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
151624edf8efSMarshall Clow    const iterator __e = end();
151707b9cd36SEric Fiselier    for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
15183e519524SHoward Hinnant    {
151907b9cd36SEric Fiselier        if (__i.__get_begin()->__next_->__value_ == __v)
15203e519524SHoward Hinnant        {
152124edf8efSMarshall Clow            ++__count_removed;
1522ce48a113SHoward Hinnant            iterator __j = _VSTD::next(__i, 2);
15233e519524SHoward Hinnant            for (; __j != __e && *__j == __v; ++__j)
152424edf8efSMarshall Clow                ++__count_removed;
152599d2df95SMarshall Clow            __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
15263e519524SHoward Hinnant            if (__j == __e)
15273e519524SHoward Hinnant                break;
15283e519524SHoward Hinnant            __i = __j;
15293e519524SHoward Hinnant        }
15303e519524SHoward Hinnant        else
15313e519524SHoward Hinnant            ++__i;
15323e519524SHoward Hinnant    }
153324edf8efSMarshall Clow
1534f814dcbaSMarshall Clow    return (__remove_return_type) __count_removed;
15353e519524SHoward Hinnant}
15363e519524SHoward Hinnant
15373e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
15383e519524SHoward Hinnanttemplate <class _Predicate>
1539f814dcbaSMarshall Clowtypename forward_list<_Tp, _Alloc>::__remove_return_type
15403e519524SHoward Hinnantforward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
15413e519524SHoward Hinnant{
1542896b0c7bSMarshall Clow    forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
154324edf8efSMarshall Clow    typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
154424edf8efSMarshall Clow    const iterator __e = end();
154507b9cd36SEric Fiselier    for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
15463e519524SHoward Hinnant    {
154707b9cd36SEric Fiselier        if (__pred(__i.__get_begin()->__next_->__value_))
15483e519524SHoward Hinnant        {
154924edf8efSMarshall Clow            ++__count_removed;
1550ce48a113SHoward Hinnant            iterator __j = _VSTD::next(__i, 2);
15513e519524SHoward Hinnant            for (; __j != __e && __pred(*__j); ++__j)
155224edf8efSMarshall Clow                ++__count_removed;
1553896b0c7bSMarshall Clow            __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
15543e519524SHoward Hinnant            if (__j == __e)
15553e519524SHoward Hinnant                break;
15563e519524SHoward Hinnant            __i = __j;
15573e519524SHoward Hinnant        }
15583e519524SHoward Hinnant        else
15593e519524SHoward Hinnant            ++__i;
15603e519524SHoward Hinnant    }
156124edf8efSMarshall Clow
1562f814dcbaSMarshall Clow    return (__remove_return_type) __count_removed;
15633e519524SHoward Hinnant}
15643e519524SHoward Hinnant
15653e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
15663e519524SHoward Hinnanttemplate <class _BinaryPredicate>
1567f814dcbaSMarshall Clowtypename forward_list<_Tp, _Alloc>::__remove_return_type
15683e519524SHoward Hinnantforward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
15693e519524SHoward Hinnant{
1570896b0c7bSMarshall Clow    forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
157124edf8efSMarshall Clow    typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
15723e519524SHoward Hinnant    for (iterator __i = begin(), __e = end(); __i != __e;)
15733e519524SHoward Hinnant    {
1574ce48a113SHoward Hinnant        iterator __j = _VSTD::next(__i);
15753e519524SHoward Hinnant        for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
157624edf8efSMarshall Clow            ++__count_removed;
157707b9cd36SEric Fiselier        if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
1578896b0c7bSMarshall Clow            __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
15793e519524SHoward Hinnant        __i = __j;
15803e519524SHoward Hinnant    }
158124edf8efSMarshall Clow
1582f814dcbaSMarshall Clow    return (__remove_return_type) __count_removed;
15833e519524SHoward Hinnant}
15843e519524SHoward Hinnant
15853e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
15863e519524SHoward Hinnanttemplate <class _Compare>
15873e519524SHoward Hinnantvoid
15883e519524SHoward Hinnantforward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
15893e519524SHoward Hinnant{
1590f7345de6SMark de Wever    if (this != _VSTD::addressof(__x))
15913e519524SHoward Hinnant    {
15923e519524SHoward Hinnant        base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
15933e519524SHoward Hinnant                                                    __x.__before_begin()->__next_,
15943e519524SHoward Hinnant                                                    __comp);
15953e519524SHoward Hinnant        __x.__before_begin()->__next_ = nullptr;
15963e519524SHoward Hinnant    }
15973e519524SHoward Hinnant}
15983e519524SHoward Hinnant
15993e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
16003e519524SHoward Hinnanttemplate <class _Compare>
16013e519524SHoward Hinnanttypename forward_list<_Tp, _Alloc>::__node_pointer
16023e519524SHoward Hinnantforward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
16033e519524SHoward Hinnant                                   _Compare& __comp)
16043e519524SHoward Hinnant{
16053e519524SHoward Hinnant    if (__f1 == nullptr)
16063e519524SHoward Hinnant        return __f2;
16073e519524SHoward Hinnant    if (__f2 == nullptr)
16083e519524SHoward Hinnant        return __f1;
16093e519524SHoward Hinnant    __node_pointer __r;
16103e519524SHoward Hinnant    if (__comp(__f2->__value_, __f1->__value_))
16113e519524SHoward Hinnant    {
16123e519524SHoward Hinnant        __node_pointer __t = __f2;
16133e519524SHoward Hinnant        while (__t->__next_ != nullptr &&
16143e519524SHoward Hinnant                             __comp(__t->__next_->__value_, __f1->__value_))
16153e519524SHoward Hinnant            __t = __t->__next_;
16163e519524SHoward Hinnant        __r = __f2;
16173e519524SHoward Hinnant        __f2 = __t->__next_;
16183e519524SHoward Hinnant        __t->__next_ = __f1;
16193e519524SHoward Hinnant    }
16203e519524SHoward Hinnant    else
16213e519524SHoward Hinnant        __r = __f1;
16223e519524SHoward Hinnant    __node_pointer __p = __f1;
16233e519524SHoward Hinnant    __f1 = __f1->__next_;
16243e519524SHoward Hinnant    while (__f1 != nullptr && __f2 != nullptr)
16253e519524SHoward Hinnant    {
16263e519524SHoward Hinnant        if (__comp(__f2->__value_, __f1->__value_))
16273e519524SHoward Hinnant        {
16283e519524SHoward Hinnant            __node_pointer __t = __f2;
16293e519524SHoward Hinnant            while (__t->__next_ != nullptr &&
16303e519524SHoward Hinnant                                 __comp(__t->__next_->__value_, __f1->__value_))
16313e519524SHoward Hinnant                __t = __t->__next_;
16323e519524SHoward Hinnant            __p->__next_ = __f2;
16333e519524SHoward Hinnant            __f2 = __t->__next_;
16343e519524SHoward Hinnant            __t->__next_ = __f1;
16353e519524SHoward Hinnant        }
16363e519524SHoward Hinnant        __p = __f1;
16373e519524SHoward Hinnant        __f1 = __f1->__next_;
16383e519524SHoward Hinnant    }
16393e519524SHoward Hinnant    if (__f2 != nullptr)
16403e519524SHoward Hinnant        __p->__next_ = __f2;
16413e519524SHoward Hinnant    return __r;
16423e519524SHoward Hinnant}
16433e519524SHoward Hinnant
16443e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
16453e519524SHoward Hinnanttemplate <class _Compare>
1646cd31b434SEvgeniy Stepanovinline
16473e519524SHoward Hinnantvoid
16483e519524SHoward Hinnantforward_list<_Tp, _Alloc>::sort(_Compare __comp)
16493e519524SHoward Hinnant{
16503e519524SHoward Hinnant    base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1651ce48a113SHoward Hinnant                                       _VSTD::distance(begin(), end()), __comp);
16523e519524SHoward Hinnant}
16533e519524SHoward Hinnant
16543e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
16553e519524SHoward Hinnanttemplate <class _Compare>
16563e519524SHoward Hinnanttypename forward_list<_Tp, _Alloc>::__node_pointer
16573e519524SHoward Hinnantforward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
16583e519524SHoward Hinnant                                  _Compare& __comp)
16593e519524SHoward Hinnant{
16603e519524SHoward Hinnant    switch (__sz)
16613e519524SHoward Hinnant    {
16623e519524SHoward Hinnant    case 0:
16633e519524SHoward Hinnant    case 1:
16643e519524SHoward Hinnant        return __f1;
16653e519524SHoward Hinnant    case 2:
16663e519524SHoward Hinnant        if (__comp(__f1->__next_->__value_, __f1->__value_))
16673e519524SHoward Hinnant        {
16683e519524SHoward Hinnant            __node_pointer __t = __f1->__next_;
16693e519524SHoward Hinnant            __t->__next_ = __f1;
16703e519524SHoward Hinnant            __f1->__next_ = nullptr;
16713e519524SHoward Hinnant            __f1 = __t;
16723e519524SHoward Hinnant        }
16733e519524SHoward Hinnant        return __f1;
16743e519524SHoward Hinnant    }
16753e519524SHoward Hinnant    difference_type __sz1 = __sz / 2;
16763e519524SHoward Hinnant    difference_type __sz2 = __sz - __sz1;
167707b9cd36SEric Fiselier    __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
16783e519524SHoward Hinnant    __node_pointer __f2 = __t->__next_;
16793e519524SHoward Hinnant    __t->__next_ = nullptr;
16803e519524SHoward Hinnant    return __merge(__sort(__f1, __sz1, __comp),
16813e519524SHoward Hinnant                   __sort(__f2, __sz2, __comp), __comp);
16823e519524SHoward Hinnant}
16833e519524SHoward Hinnant
16843e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
16853e519524SHoward Hinnantvoid
1686f9dc2831SHoward Hinnantforward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
16873e519524SHoward Hinnant{
16883e519524SHoward Hinnant    __node_pointer __p = base::__before_begin()->__next_;
16893e519524SHoward Hinnant    if (__p != nullptr)
16903e519524SHoward Hinnant    {
16913e519524SHoward Hinnant        __node_pointer __f = __p->__next_;
16923e519524SHoward Hinnant        __p->__next_ = nullptr;
16933e519524SHoward Hinnant        while (__f != nullptr)
16943e519524SHoward Hinnant        {
16953e519524SHoward Hinnant            __node_pointer __t = __f->__next_;
16963e519524SHoward Hinnant            __f->__next_ = __p;
16973e519524SHoward Hinnant            __p = __f;
16983e519524SHoward Hinnant            __f = __t;
16993e519524SHoward Hinnant        }
17003e519524SHoward Hinnant        base::__before_begin()->__next_ = __p;
17013e519524SHoward Hinnant    }
17023e519524SHoward Hinnant}
17033e519524SHoward Hinnant
17043e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17053e519524SHoward Hinnantbool operator==(const forward_list<_Tp, _Alloc>& __x,
17063e519524SHoward Hinnant                const forward_list<_Tp, _Alloc>& __y)
17073e519524SHoward Hinnant{
1708c003db1fSHoward Hinnant    typedef forward_list<_Tp, _Alloc> _Cp;
1709c003db1fSHoward Hinnant    typedef typename _Cp::const_iterator _Ip;
1710c003db1fSHoward Hinnant    _Ip __ix = __x.begin();
1711c003db1fSHoward Hinnant    _Ip __ex = __x.end();
1712c003db1fSHoward Hinnant    _Ip __iy = __y.begin();
1713c003db1fSHoward Hinnant    _Ip __ey = __y.end();
17143e519524SHoward Hinnant    for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
17153e519524SHoward Hinnant        if (!(*__ix == *__iy))
17163e519524SHoward Hinnant            return false;
17173e519524SHoward Hinnant    return (__ix == __ex) == (__iy == __ey);
17183e519524SHoward Hinnant}
17193e519524SHoward Hinnant
17203e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17210af133f9SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
17223e519524SHoward Hinnantbool operator!=(const forward_list<_Tp, _Alloc>& __x,
17233e519524SHoward Hinnant                const forward_list<_Tp, _Alloc>& __y)
17243e519524SHoward Hinnant{
17253e519524SHoward Hinnant    return !(__x == __y);
17263e519524SHoward Hinnant}
17273e519524SHoward Hinnant
17283e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17290af133f9SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
17303e519524SHoward Hinnantbool operator< (const forward_list<_Tp, _Alloc>& __x,
17313e519524SHoward Hinnant                const forward_list<_Tp, _Alloc>& __y)
17323e519524SHoward Hinnant{
1733ce48a113SHoward Hinnant    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
17343e519524SHoward Hinnant                                         __y.begin(), __y.end());
17353e519524SHoward Hinnant}
17363e519524SHoward Hinnant
17373e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17380af133f9SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
17393e519524SHoward Hinnantbool operator> (const forward_list<_Tp, _Alloc>& __x,
17403e519524SHoward Hinnant                const forward_list<_Tp, _Alloc>& __y)
17413e519524SHoward Hinnant{
17423e519524SHoward Hinnant    return __y < __x;
17433e519524SHoward Hinnant}
17443e519524SHoward Hinnant
17453e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17460af133f9SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
17473e519524SHoward Hinnantbool operator>=(const forward_list<_Tp, _Alloc>& __x,
17483e519524SHoward Hinnant                const forward_list<_Tp, _Alloc>& __y)
17493e519524SHoward Hinnant{
17503e519524SHoward Hinnant    return !(__x < __y);
17513e519524SHoward Hinnant}
17523e519524SHoward Hinnant
17533e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17540af133f9SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
17553e519524SHoward Hinnantbool operator<=(const forward_list<_Tp, _Alloc>& __x,
17563e519524SHoward Hinnant                const forward_list<_Tp, _Alloc>& __y)
17573e519524SHoward Hinnant{
17583e519524SHoward Hinnant    return !(__y < __x);
17593e519524SHoward Hinnant}
17603e519524SHoward Hinnant
17613e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
17620af133f9SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
17633e519524SHoward Hinnantvoid
17643e519524SHoward Hinnantswap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
176591a47507SHoward Hinnant    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
17663e519524SHoward Hinnant{
17673e519524SHoward Hinnant    __x.swap(__y);
17683e519524SHoward Hinnant}
17693e519524SHoward Hinnant
1770f60c63c0SMarshall Clow#if _LIBCPP_STD_VER > 17
1771f60c63c0SMarshall Clowtemplate <class _Tp, class _Allocator, class _Predicate>
1772f60c63c0SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
17733e895085SMarek Kurdej    typename forward_list<_Tp, _Allocator>::size_type
17743e895085SMarek Kurdej    erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
17753e895085SMarek Kurdej  return __c.remove_if(__pred);
17763e895085SMarek Kurdej}
1777f60c63c0SMarshall Clow
1778f60c63c0SMarshall Clowtemplate <class _Tp, class _Allocator, class _Up>
1779f60c63c0SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
17803e895085SMarek Kurdej    typename forward_list<_Tp, _Allocator>::size_type
17813e895085SMarek Kurdej    erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) {
17823e895085SMarek Kurdej  return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
17833e895085SMarek Kurdej}
1784f60c63c0SMarshall Clow#endif
1785f60c63c0SMarshall Clow
17863e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
17873e519524SHoward Hinnant
1788a016efb1SEric Fiselier_LIBCPP_POP_MACROS
1789a016efb1SEric Fiselier
17903e519524SHoward Hinnant#endif // _LIBCPP_FORWARD_LIST
1791