xref: /freebsd/contrib/llvm-project/libcxx/include/forward_list (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_FORWARD_LIST
110b57cec5SDimitry Andric#define _LIBCPP_FORWARD_LIST
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    forward_list synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andrictemplate <class T, class Allocator = allocator<T>>
200b57cec5SDimitry Andricclass forward_list
210b57cec5SDimitry Andric{
220b57cec5SDimitry Andricpublic:
230b57cec5SDimitry Andric    typedef T         value_type;
240b57cec5SDimitry Andric    typedef Allocator allocator_type;
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric    typedef value_type&                                                reference;
270b57cec5SDimitry Andric    typedef const value_type&                                          const_reference;
280b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::pointer         pointer;
290b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
300b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::size_type       size_type;
310b57cec5SDimitry Andric    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric    typedef <details> iterator;
340b57cec5SDimitry Andric    typedef <details> const_iterator;
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric    forward_list()
370b57cec5SDimitry Andric        noexcept(is_nothrow_default_constructible<allocator_type>::value);
380b57cec5SDimitry Andric    explicit forward_list(const allocator_type& a);
390b57cec5SDimitry Andric    explicit forward_list(size_type n);
400b57cec5SDimitry Andric    explicit forward_list(size_type n, const allocator_type& a); // C++14
410b57cec5SDimitry Andric    forward_list(size_type n, const value_type& v);
420b57cec5SDimitry Andric    forward_list(size_type n, const value_type& v, const allocator_type& a);
430b57cec5SDimitry Andric    template <class InputIterator>
440b57cec5SDimitry Andric        forward_list(InputIterator first, InputIterator last);
450b57cec5SDimitry Andric    template <class InputIterator>
460b57cec5SDimitry Andric        forward_list(InputIterator first, InputIterator last, const allocator_type& a);
4706c3fb27SDimitry Andric    template<container-compatible-range<T> R>
4806c3fb27SDimitry Andric        forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
490b57cec5SDimitry Andric    forward_list(const forward_list& x);
500b57cec5SDimitry Andric    forward_list(const forward_list& x, const allocator_type& a);
510b57cec5SDimitry Andric    forward_list(forward_list&& x)
520b57cec5SDimitry Andric        noexcept(is_nothrow_move_constructible<allocator_type>::value);
530b57cec5SDimitry Andric    forward_list(forward_list&& x, const allocator_type& a);
540b57cec5SDimitry Andric    forward_list(initializer_list<value_type> il);
550b57cec5SDimitry Andric    forward_list(initializer_list<value_type> il, const allocator_type& a);
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric    ~forward_list();
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    forward_list& operator=(const forward_list& x);
600b57cec5SDimitry Andric    forward_list& operator=(forward_list&& x)
610b57cec5SDimitry Andric        noexcept(
620b57cec5SDimitry Andric             allocator_type::propagate_on_container_move_assignment::value &&
630b57cec5SDimitry Andric             is_nothrow_move_assignable<allocator_type>::value);
640b57cec5SDimitry Andric    forward_list& operator=(initializer_list<value_type> il);
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric    template <class InputIterator>
670b57cec5SDimitry Andric        void assign(InputIterator first, InputIterator last);
6806c3fb27SDimitry Andric    template<container-compatible-range<T> R>
6906c3fb27SDimitry Andric      void assign_range(R&& rg); // C++23
700b57cec5SDimitry Andric    void assign(size_type n, const value_type& v);
710b57cec5SDimitry Andric    void assign(initializer_list<value_type> il);
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric    allocator_type get_allocator() const noexcept;
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric    iterator       begin() noexcept;
760b57cec5SDimitry Andric    const_iterator begin() const noexcept;
770b57cec5SDimitry Andric    iterator       end() noexcept;
780b57cec5SDimitry Andric    const_iterator end() const noexcept;
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric    const_iterator cbegin() const noexcept;
810b57cec5SDimitry Andric    const_iterator cend() const noexcept;
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric    iterator       before_begin() noexcept;
840b57cec5SDimitry Andric    const_iterator before_begin() const noexcept;
850b57cec5SDimitry Andric    const_iterator cbefore_begin() const noexcept;
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric    bool empty() const noexcept;
880b57cec5SDimitry Andric    size_type max_size() const noexcept;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric    reference       front();
910b57cec5SDimitry Andric    const_reference front() const;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
940b57cec5SDimitry Andric    void push_front(const value_type& v);
950b57cec5SDimitry Andric    void push_front(value_type&& v);
9606c3fb27SDimitry Andric    template<container-compatible-range<T> R>
9706c3fb27SDimitry Andric      void prepend_range(R&& rg); // C++23
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric    void pop_front();
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric    template <class... Args>
1020b57cec5SDimitry Andric        iterator emplace_after(const_iterator p, Args&&... args);
1030b57cec5SDimitry Andric    iterator insert_after(const_iterator p, const value_type& v);
1040b57cec5SDimitry Andric    iterator insert_after(const_iterator p, value_type&& v);
1050b57cec5SDimitry Andric    iterator insert_after(const_iterator p, size_type n, const value_type& v);
1060b57cec5SDimitry Andric    template <class InputIterator>
1070b57cec5SDimitry Andric        iterator insert_after(const_iterator p,
1080b57cec5SDimitry Andric                              InputIterator first, InputIterator last);
10906c3fb27SDimitry Andric    template<container-compatible-range<T> R>
11006c3fb27SDimitry Andric      iterator insert_range_after(const_iterator position, R&& rg); // C++23
1110b57cec5SDimitry Andric    iterator insert_after(const_iterator p, initializer_list<value_type> il);
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric    iterator erase_after(const_iterator p);
1140b57cec5SDimitry Andric    iterator erase_after(const_iterator first, const_iterator last);
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andric    void swap(forward_list& x)
1170b57cec5SDimitry Andric        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric    void resize(size_type n);
1200b57cec5SDimitry Andric    void resize(size_type n, const value_type& v);
1210b57cec5SDimitry Andric    void clear() noexcept;
1220b57cec5SDimitry Andric
1230b57cec5SDimitry Andric    void splice_after(const_iterator p, forward_list& x);
1240b57cec5SDimitry Andric    void splice_after(const_iterator p, forward_list&& x);
1250b57cec5SDimitry Andric    void splice_after(const_iterator p, forward_list& x, const_iterator i);
1260b57cec5SDimitry Andric    void splice_after(const_iterator p, forward_list&& x, const_iterator i);
1270b57cec5SDimitry Andric    void splice_after(const_iterator p, forward_list& x,
1280b57cec5SDimitry Andric                      const_iterator first, const_iterator last);
1290b57cec5SDimitry Andric    void splice_after(const_iterator p, forward_list&& x,
1300b57cec5SDimitry Andric                      const_iterator first, const_iterator last);
1310b57cec5SDimitry Andric    size_type remove(const value_type& v);           // void before C++20
1320b57cec5SDimitry Andric    template <class Predicate>
1330b57cec5SDimitry Andric      size_type remove_if(Predicate pred);           // void before C++20
1340b57cec5SDimitry Andric    size_type unique();                              // void before C++20
1350b57cec5SDimitry Andric    template <class BinaryPredicate>
1360b57cec5SDimitry Andric      size_type unique(BinaryPredicate binary_pred); // void before C++20
1370b57cec5SDimitry Andric    void merge(forward_list& x);
1380b57cec5SDimitry Andric    void merge(forward_list&& x);
1390b57cec5SDimitry Andric    template <class Compare> void merge(forward_list& x, Compare comp);
1400b57cec5SDimitry Andric    template <class Compare> void merge(forward_list&& x, Compare comp);
1410b57cec5SDimitry Andric    void sort();
1420b57cec5SDimitry Andric    template <class Compare> void sort(Compare comp);
1430b57cec5SDimitry Andric    void reverse() noexcept;
1440b57cec5SDimitry Andric};
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andrictemplate <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1480b57cec5SDimitry Andric    forward_list(InputIterator, InputIterator, Allocator = Allocator())
1490b57cec5SDimitry Andric    -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;  // C++17
1500b57cec5SDimitry Andric
15106c3fb27SDimitry Andrictemplate<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
15206c3fb27SDimitry Andric  forward_list(from_range_t, R&&, Allocator = Allocator())
15306c3fb27SDimitry Andric      -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23
15406c3fb27SDimitry Andric
1550b57cec5SDimitry Andrictemplate <class T, class Allocator>
1560b57cec5SDimitry Andric    bool operator==(const forward_list<T, Allocator>& x,
1570b57cec5SDimitry Andric                    const forward_list<T, Allocator>& y);
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andrictemplate <class T, class Allocator>
1600b57cec5SDimitry Andric    bool operator< (const forward_list<T, Allocator>& x,
16106c3fb27SDimitry Andric                    const forward_list<T, Allocator>& y); // removed in C++20
1620b57cec5SDimitry Andric
1630b57cec5SDimitry Andrictemplate <class T, class Allocator>
1640b57cec5SDimitry Andric    bool operator!=(const forward_list<T, Allocator>& x,
16506c3fb27SDimitry Andric                    const forward_list<T, Allocator>& y); // removed in C++20
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andrictemplate <class T, class Allocator>
1680b57cec5SDimitry Andric    bool operator> (const forward_list<T, Allocator>& x,
16906c3fb27SDimitry Andric                    const forward_list<T, Allocator>& y); // removed in C++20
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andrictemplate <class T, class Allocator>
1720b57cec5SDimitry Andric    bool operator>=(const forward_list<T, Allocator>& x,
17306c3fb27SDimitry Andric                    const forward_list<T, Allocator>& y); // removed in C++20
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andrictemplate <class T, class Allocator>
1760b57cec5SDimitry Andric    bool operator<=(const forward_list<T, Allocator>& x,
17706c3fb27SDimitry Andric                    const forward_list<T, Allocator>& y); // removed in C++20
17806c3fb27SDimitry Andric
17906c3fb27SDimitry Andrictemplate<class T, class Allocator>
18006c3fb27SDimitry Andric    synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x,
18106c3fb27SDimitry Andric                                          const forward_list<T, Allocator>& y); // since C++20
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andrictemplate <class T, class Allocator>
1840b57cec5SDimitry Andric    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
1850b57cec5SDimitry Andric         noexcept(noexcept(x.swap(y)));
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andrictemplate <class T, class Allocator, class U>
1885ffd83dbSDimitry Andric    typename forward_list<T, Allocator>::size_type
1895ffd83dbSDimitry Andric    erase(forward_list<T, Allocator>& c, const U& value);       // C++20
1900b57cec5SDimitry Andrictemplate <class T, class Allocator, class Predicate>
1915ffd83dbSDimitry Andric    typename forward_list<T, Allocator>::size_type
1925ffd83dbSDimitry Andric    erase_if(forward_list<T, Allocator>& c, Predicate pred);    // C++20
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric}  // std
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric*/
1970b57cec5SDimitry Andric
19881ad6265SDimitry Andric#include <__algorithm/comp.h>
19981ad6265SDimitry Andric#include <__algorithm/lexicographical_compare.h>
20006c3fb27SDimitry Andric#include <__algorithm/lexicographical_compare_three_way.h>
20181ad6265SDimitry Andric#include <__algorithm/min.h>
2020b57cec5SDimitry Andric#include <__config>
20381ad6265SDimitry Andric#include <__iterator/distance.h>
20481ad6265SDimitry Andric#include <__iterator/iterator_traits.h>
20581ad6265SDimitry Andric#include <__iterator/move_iterator.h>
20681ad6265SDimitry Andric#include <__iterator/next.h>
207bdd1243dSDimitry Andric#include <__memory/addressof.h>
20806c3fb27SDimitry Andric#include <__memory/allocation_guard.h>
209bdd1243dSDimitry Andric#include <__memory/allocator.h>
210bdd1243dSDimitry Andric#include <__memory/allocator_traits.h>
211bdd1243dSDimitry Andric#include <__memory/compressed_pair.h>
2125f757f3fSDimitry Andric#include <__memory/construct_at.h>
213bdd1243dSDimitry Andric#include <__memory/pointer_traits.h>
214972a253aSDimitry Andric#include <__memory/swap_allocator.h>
215bdd1243dSDimitry Andric#include <__memory_resource/polymorphic_allocator.h>
21606c3fb27SDimitry Andric#include <__ranges/access.h>
21706c3fb27SDimitry Andric#include <__ranges/concepts.h>
21806c3fb27SDimitry Andric#include <__ranges/container_compatible_range.h>
21906c3fb27SDimitry Andric#include <__ranges/from_range.h>
22006c3fb27SDimitry Andric#include <__type_traits/conditional.h>
221bdd1243dSDimitry Andric#include <__type_traits/is_allocator.h>
22206c3fb27SDimitry Andric#include <__type_traits/is_const.h>
223*0fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_assignable.h>
224*0fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_constructible.h>
22506c3fb27SDimitry Andric#include <__type_traits/is_pointer.h>
22606c3fb27SDimitry Andric#include <__type_traits/is_same.h>
227*0fca6ea1SDimitry Andric#include <__type_traits/is_swappable.h>
22806c3fb27SDimitry Andric#include <__type_traits/type_identity.h>
229fe6060f1SDimitry Andric#include <__utility/forward.h>
230bdd1243dSDimitry Andric#include <__utility/move.h>
231fe6060f1SDimitry Andric#include <limits>
2325f757f3fSDimitry Andric#include <new> // __launder
2330b57cec5SDimitry Andric#include <version>
2340b57cec5SDimitry Andric
23581ad6265SDimitry Andric// standard-mandated includes
23681ad6265SDimitry Andric
23781ad6265SDimitry Andric// [iterator.range]
23881ad6265SDimitry Andric#include <__iterator/access.h>
23981ad6265SDimitry Andric#include <__iterator/data.h>
24081ad6265SDimitry Andric#include <__iterator/empty.h>
24181ad6265SDimitry Andric#include <__iterator/reverse_access.h>
24281ad6265SDimitry Andric#include <__iterator/size.h>
24381ad6265SDimitry Andric
24481ad6265SDimitry Andric// [forward.list.syn]
24581ad6265SDimitry Andric#include <compare>
24681ad6265SDimitry Andric#include <initializer_list>
24781ad6265SDimitry Andric
2480b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2490b57cec5SDimitry Andric#  pragma GCC system_header
2500b57cec5SDimitry Andric#endif
2510b57cec5SDimitry Andric
2520b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
2530b57cec5SDimitry Andric#include <__undef_macros>
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2560b57cec5SDimitry Andric
257cb14a3feSDimitry Andrictemplate <class _Tp, class _VoidPtr>
258cb14a3feSDimitry Andricstruct __forward_list_node;
259cb14a3feSDimitry Andrictemplate <class _NodePtr>
260cb14a3feSDimitry Andricstruct __forward_begin_node;
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andrictemplate <class>
2630b57cec5SDimitry Andricstruct __forward_list_node_value_type;
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr>
2660b57cec5SDimitry Andricstruct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
2670b57cec5SDimitry Andric  typedef _Tp type;
2680b57cec5SDimitry Andric};
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andrictemplate <class _NodePtr>
2710b57cec5SDimitry Andricstruct __forward_node_traits {
2725f757f3fSDimitry Andric  typedef __remove_cv_t<typename pointer_traits<_NodePtr>::element_type> __node_type;
2735f757f3fSDimitry Andric  typedef typename __forward_list_node_value_type<__node_type>::type __node_value_type;
2740b57cec5SDimitry Andric  typedef _NodePtr __node_pointer;
2750b57cec5SDimitry Andric  typedef __forward_begin_node<_NodePtr> __begin_node;
276bdd1243dSDimitry Andric  typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer;
277bdd1243dSDimitry Andric  typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
2800b57cec5SDimitry Andric  typedef __begin_node_pointer __iter_node_pointer;
2810b57cec5SDimitry Andric#else
282cb14a3feSDimitry Andric  typedef __conditional_t<is_pointer<__void_pointer>::value, __begin_node_pointer, __node_pointer> __iter_node_pointer;
2830b57cec5SDimitry Andric#endif
2840b57cec5SDimitry Andric
285bdd1243dSDimitry Andric  typedef __conditional_t<is_same<__iter_node_pointer, __node_pointer>::value, __begin_node_pointer, __node_pointer>
286bdd1243dSDimitry Andric      __non_iter_node_pointer;
2870b57cec5SDimitry Andric
288cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { return __p; }
289cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
2900b57cec5SDimitry Andric    return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
2910b57cec5SDimitry Andric  }
2920b57cec5SDimitry Andric};
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andrictemplate <class _NodePtr>
295cb14a3feSDimitry Andricstruct __forward_begin_node {
2960b57cec5SDimitry Andric  typedef _NodePtr pointer;
297bdd1243dSDimitry Andric  typedef __rebind_pointer_t<_NodePtr, __forward_begin_node> __begin_node_pointer;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric  pointer __next_;
3000b57cec5SDimitry Andric
3015f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_begin_node() : __next_(nullptr) {}
3025f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_begin_node(pointer __n) : __next_(__n) {}
3030b57cec5SDimitry Andric
304cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __next_as_begin() const {
3050b57cec5SDimitry Andric    return static_cast<__begin_node_pointer>(__next_);
3060b57cec5SDimitry Andric  }
3070b57cec5SDimitry Andric};
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr>
310bdd1243dSDimitry Andricusing __begin_node_of = __forward_begin_node<__rebind_pointer_t<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> > >;
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andrictemplate <class _Tp, class _VoidPtr>
313cb14a3feSDimitry Andricstruct __forward_list_node : public __begin_node_of<_Tp, _VoidPtr> {
3140b57cec5SDimitry Andric  typedef _Tp value_type;
31506c3fb27SDimitry Andric  typedef __begin_node_of<_Tp, _VoidPtr> _Base;
31606c3fb27SDimitry Andric  typedef typename _Base::pointer _NodePtr;
3170b57cec5SDimitry Andric
3185f757f3fSDimitry Andric  // We allow starting the lifetime of nodes without initializing the value held by the node,
3195f757f3fSDimitry Andric  // since that is handled by the list itself in order to be allocator-aware.
3205f757f3fSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
321cb14a3feSDimitry Andric
3225f757f3fSDimitry Andricprivate:
3235f757f3fSDimitry Andric  union {
3245f757f3fSDimitry Andric    _Tp __value_;
3255f757f3fSDimitry Andric  };
32606c3fb27SDimitry Andric
3275f757f3fSDimitry Andricpublic:
3285f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; }
3295f757f3fSDimitry Andric#else
330cb14a3feSDimitry Andric
3315f757f3fSDimitry Andricprivate:
3325f757f3fSDimitry Andric  _ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)];
3335f757f3fSDimitry Andric
3345f757f3fSDimitry Andricpublic:
335cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
3365f757f3fSDimitry Andric#endif
3375f757f3fSDimitry Andric
3385f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_node(_NodePtr __next) : _Base(__next) {}
3395f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~__forward_list_node() {}
3400b57cec5SDimitry Andric};
3410b57cec5SDimitry Andric
342cb14a3feSDimitry Andrictemplate <class _Tp, class _Alloc = allocator<_Tp> >
343cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS forward_list;
344cb14a3feSDimitry Andrictemplate <class _NodeConstPtr>
345cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
3460b57cec5SDimitry Andric
3470b57cec5SDimitry Andrictemplate <class _NodePtr>
348cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __forward_list_iterator {
3490b57cec5SDimitry Andric  typedef __forward_node_traits<_NodePtr> __traits;
3500b57cec5SDimitry Andric  typedef typename __traits::__node_pointer __node_pointer;
3510b57cec5SDimitry Andric  typedef typename __traits::__begin_node_pointer __begin_node_pointer;
3520b57cec5SDimitry Andric  typedef typename __traits::__iter_node_pointer __iter_node_pointer;
3530b57cec5SDimitry Andric  typedef typename __traits::__void_pointer __void_pointer;
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric  __iter_node_pointer __ptr_;
3560b57cec5SDimitry Andric
357cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
358cb14a3feSDimitry Andric    return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__ptr_));
3590b57cec5SDimitry Andric  }
360cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
361cb14a3feSDimitry Andric    return static_cast<__node_pointer>(static_cast<__void_pointer>(__ptr_));
3620b57cec5SDimitry Andric  }
3630b57cec5SDimitry Andric
364cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
3650b57cec5SDimitry Andric
366cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
3670b57cec5SDimitry Andric      : __ptr_(__traits::__as_iter_node(__p)) {}
3680b57cec5SDimitry Andric
369cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
3700b57cec5SDimitry Andric      : __ptr_(__traits::__as_iter_node(__p)) {}
3710b57cec5SDimitry Andric
372cb14a3feSDimitry Andric  template <class, class>
373cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS forward_list;
374cb14a3feSDimitry Andric  template <class>
375cb14a3feSDimitry Andric  friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andricpublic:
3780b57cec5SDimitry Andric  typedef forward_iterator_tag iterator_category;
3790b57cec5SDimitry Andric  typedef typename __traits::__node_value_type value_type;
3800b57cec5SDimitry Andric  typedef value_type& reference;
381cb14a3feSDimitry Andric  typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
382bdd1243dSDimitry Andric  typedef __rebind_pointer_t<__node_pointer, value_type> pointer;
3830b57cec5SDimitry Andric
384cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
3850b57cec5SDimitry Andric
386cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_unsafe_node_pointer()->__get_value(); }
387cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
3885f757f3fSDimitry Andric    return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__get_value());
3890b57cec5SDimitry Andric  }
3900b57cec5SDimitry Andric
391cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_iterator& operator++() {
3920b57cec5SDimitry Andric    __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
3930b57cec5SDimitry Andric    return *this;
3940b57cec5SDimitry Andric  }
395cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_iterator operator++(int) {
3960b57cec5SDimitry Andric    __forward_list_iterator __t(*this);
3970b57cec5SDimitry Andric    ++(*this);
3980b57cec5SDimitry Andric    return __t;
3990b57cec5SDimitry Andric  }
4000b57cec5SDimitry Andric
401cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __forward_list_iterator& __x, const __forward_list_iterator& __y) {
402cb14a3feSDimitry Andric    return __x.__ptr_ == __y.__ptr_;
403cb14a3feSDimitry Andric  }
404cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __forward_list_iterator& __x, const __forward_list_iterator& __y) {
405cb14a3feSDimitry Andric    return !(__x == __y);
406cb14a3feSDimitry Andric  }
4070b57cec5SDimitry Andric};
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andrictemplate <class _NodeConstPtr>
410cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator {
411*0fca6ea1SDimitry Andric  static_assert(!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value, "");
4120b57cec5SDimitry Andric  typedef _NodeConstPtr _NodePtr;
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric  typedef __forward_node_traits<_NodePtr> __traits;
4155f757f3fSDimitry Andric  typedef typename __traits::__node_type __node_type;
4160b57cec5SDimitry Andric  typedef typename __traits::__node_pointer __node_pointer;
4170b57cec5SDimitry Andric  typedef typename __traits::__begin_node_pointer __begin_node_pointer;
4180b57cec5SDimitry Andric  typedef typename __traits::__iter_node_pointer __iter_node_pointer;
4190b57cec5SDimitry Andric  typedef typename __traits::__void_pointer __void_pointer;
4200b57cec5SDimitry Andric
4210b57cec5SDimitry Andric  __iter_node_pointer __ptr_;
4220b57cec5SDimitry Andric
42306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
424cb14a3feSDimitry Andric    return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__ptr_));
4250b57cec5SDimitry Andric  }
42606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
427cb14a3feSDimitry Andric    return static_cast<__node_pointer>(static_cast<__void_pointer>(__ptr_));
4280b57cec5SDimitry Andric  }
4290b57cec5SDimitry Andric
430cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
4310b57cec5SDimitry Andric
432cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
4330b57cec5SDimitry Andric      : __ptr_(__traits::__as_iter_node(__p)) {}
4340b57cec5SDimitry Andric
435cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
4360b57cec5SDimitry Andric      : __ptr_(__traits::__as_iter_node(__p)) {}
4370b57cec5SDimitry Andric
438cb14a3feSDimitry Andric  template <class, class>
439cb14a3feSDimitry Andric  friend class forward_list;
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andricpublic:
4420b57cec5SDimitry Andric  typedef forward_iterator_tag iterator_category;
4430b57cec5SDimitry Andric  typedef typename __traits::__node_value_type value_type;
4440b57cec5SDimitry Andric  typedef const value_type& reference;
445cb14a3feSDimitry Andric  typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
446cb14a3feSDimitry Andric  typedef __rebind_pointer_t<__node_pointer, const value_type> pointer;
4470b57cec5SDimitry Andric
448cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
449cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
4500b57cec5SDimitry Andric      : __ptr_(__p.__ptr_) {}
4510b57cec5SDimitry Andric
452cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_unsafe_node_pointer()->__get_value(); }
453cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
454cb14a3feSDimitry Andric    return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__get_value());
455cb14a3feSDimitry Andric  }
4560b57cec5SDimitry Andric
457cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator& operator++() {
4580b57cec5SDimitry Andric    __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
4590b57cec5SDimitry Andric    return *this;
4600b57cec5SDimitry Andric  }
461cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator operator++(int) {
4620b57cec5SDimitry Andric    __forward_list_const_iterator __t(*this);
4630b57cec5SDimitry Andric    ++(*this);
4640b57cec5SDimitry Andric    return __t;
4650b57cec5SDimitry Andric  }
4660b57cec5SDimitry Andric
467cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool
468cb14a3feSDimitry Andric  operator==(const __forward_list_const_iterator& __x, const __forward_list_const_iterator& __y) {
469cb14a3feSDimitry Andric    return __x.__ptr_ == __y.__ptr_;
470cb14a3feSDimitry Andric  }
471cb14a3feSDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI bool
472cb14a3feSDimitry Andric  operator!=(const __forward_list_const_iterator& __x, const __forward_list_const_iterator& __y) {
473cb14a3feSDimitry Andric    return !(__x == __y);
474cb14a3feSDimitry Andric  }
4750b57cec5SDimitry Andric};
4760b57cec5SDimitry Andric
4770b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
478cb14a3feSDimitry Andricclass __forward_list_base {
4790b57cec5SDimitry Andricprotected:
4800b57cec5SDimitry Andric  typedef _Tp value_type;
4810b57cec5SDimitry Andric  typedef _Alloc allocator_type;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andric  typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
4845f757f3fSDimitry Andric  typedef __forward_list_node<value_type, void_pointer> __node_type;
485bdd1243dSDimitry Andric  typedef __begin_node_of<value_type, void_pointer> __begin_node;
4865f757f3fSDimitry Andric  typedef __rebind_alloc<allocator_traits<allocator_type>, __node_type> __node_allocator;
4870b57cec5SDimitry Andric  typedef allocator_traits<__node_allocator> __node_traits;
4880b57cec5SDimitry Andric  typedef typename __node_traits::pointer __node_pointer;
4890b57cec5SDimitry Andric
490bdd1243dSDimitry Andric  typedef __rebind_alloc<allocator_traits<allocator_type>, __begin_node> __begin_node_allocator;
491cb14a3feSDimitry Andric  typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric  __compressed_pair<__begin_node, __node_allocator> __before_begin_;
4940b57cec5SDimitry Andric
495cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __before_begin() _NOEXCEPT {
496cb14a3feSDimitry Andric    return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());
497cb14a3feSDimitry Andric  }
498cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __before_begin() const _NOEXCEPT {
499cb14a3feSDimitry Andric    return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));
500cb14a3feSDimitry Andric  }
5010b57cec5SDimitry Andric
502cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __node_allocator& __alloc() _NOEXCEPT { return __before_begin_.second(); }
503cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const __node_allocator& __alloc() const _NOEXCEPT { return __before_begin_.second(); }
5040b57cec5SDimitry Andric
5050b57cec5SDimitry Andric  typedef __forward_list_iterator<__node_pointer> iterator;
5060b57cec5SDimitry Andric  typedef __forward_list_const_iterator<__node_pointer> const_iterator;
5070b57cec5SDimitry Andric
508cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_base() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
509480093f4SDimitry Andric      : __before_begin_(__begin_node(), __default_init_tag()) {}
510cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_base(const allocator_type& __a)
5110b57cec5SDimitry Andric      : __before_begin_(__begin_node(), __node_allocator(__a)) {}
512cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __forward_list_base(const __node_allocator& __a)
5130b57cec5SDimitry Andric      : __before_begin_(__begin_node(), __a) {}
514cb14a3feSDimitry Andric
5150b57cec5SDimitry Andricpublic:
516*0fca6ea1SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
517*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI
518*0fca6ea1SDimitry Andric  __forward_list_base(__forward_list_base&& __x) noexcept(is_nothrow_move_constructible<__node_allocator>::value);
519cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
5200b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
5210b57cec5SDimitry Andric
522*0fca6ea1SDimitry Andric  __forward_list_base(const __forward_list_base&)            = delete;
523*0fca6ea1SDimitry Andric  __forward_list_base& operator=(const __forward_list_base&) = delete;
5240b57cec5SDimitry Andric
52506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~__forward_list_base();
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andricprotected:
528cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __forward_list_base& __x) {
529cb14a3feSDimitry Andric    __copy_assign_alloc(__x, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
530cb14a3feSDimitry Andric  }
5310b57cec5SDimitry Andric
532cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x)
5330b57cec5SDimitry Andric      _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
534cb14a3feSDimitry Andric                 is_nothrow_move_assignable<__node_allocator>::value) {
535cb14a3feSDimitry Andric    __move_assign_alloc(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
536cb14a3feSDimitry Andric  }
5370b57cec5SDimitry Andric
5385f757f3fSDimitry Andric  template <class... _Args>
5395f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__node_pointer __next, _Args&&... __args) {
5405f757f3fSDimitry Andric    __node_allocator& __a = __alloc();
5415f757f3fSDimitry Andric    __allocation_guard<__node_allocator> __guard(__a, 1);
5425f757f3fSDimitry Andric    // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
5435f757f3fSDimitry Andric    // held inside the node, since we need to use the allocator's construct() method for that.
5445f757f3fSDimitry Andric    //
5455f757f3fSDimitry Andric    // We don't use the allocator's construct() method to construct the node itself since the
5465f757f3fSDimitry Andric    // Cpp17FooInsertable named requirements don't require the allocator's construct() method
5475f757f3fSDimitry Andric    // to work on anything other than the value_type.
5485f757f3fSDimitry Andric    std::__construct_at(std::addressof(*__guard.__get()), __next);
5495f757f3fSDimitry Andric
5505f757f3fSDimitry Andric    // Now construct the value_type using the allocator's construct() method.
5515f757f3fSDimitry Andric    __node_traits::construct(__a, std::addressof(__guard.__get()->__get_value()), std::forward<_Args>(__args)...);
5525f757f3fSDimitry Andric    return __guard.__release_ptr();
5535f757f3fSDimitry Andric  }
5545f757f3fSDimitry Andric
5555f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) {
5565f757f3fSDimitry Andric    // For the same reason as above, we use the allocator's destroy() method for the value_type,
5575f757f3fSDimitry Andric    // but not for the node itself.
5585f757f3fSDimitry Andric    __node_allocator& __a = __alloc();
5595f757f3fSDimitry Andric    __node_traits::destroy(__a, std::addressof(__node->__get_value()));
5605f757f3fSDimitry Andric    std::__destroy_at(std::addressof(*__node));
5615f757f3fSDimitry Andric    __node_traits::deallocate(__a, __node, 1);
5625f757f3fSDimitry Andric  }
5635f757f3fSDimitry Andric
5640b57cec5SDimitry Andricpublic:
565cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(__forward_list_base& __x)
5660b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
5670b57cec5SDimitry Andric      _NOEXCEPT;
5680b57cec5SDimitry Andric#else
569*0fca6ea1SDimitry Andric      _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>);
5700b57cec5SDimitry Andric#endif
571cb14a3feSDimitry Andric
5720b57cec5SDimitry Andricprotected:
57306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
5740b57cec5SDimitry Andric
5750b57cec5SDimitry Andricprivate:
576cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __forward_list_base&, false_type) {}
577cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __forward_list_base& __x, true_type) {
5780b57cec5SDimitry Andric    if (__alloc() != __x.__alloc())
5790b57cec5SDimitry Andric      clear();
5800b57cec5SDimitry Andric    __alloc() = __x.__alloc();
5810b57cec5SDimitry Andric  }
5820b57cec5SDimitry Andric
583cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT {}
584cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x, true_type)
585cb14a3feSDimitry Andric      _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
586cb14a3feSDimitry Andric    __alloc() = std::move(__x.__alloc());
587cb14a3feSDimitry Andric  }
5880b57cec5SDimitry Andric};
5890b57cec5SDimitry Andric
5900b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
5910b57cec5SDimitry Andric
5920b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
593*0fca6ea1SDimitry Andricinline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) noexcept(
594*0fca6ea1SDimitry Andric    is_nothrow_move_constructible<__node_allocator>::value)
595cb14a3feSDimitry Andric    : __before_begin_(std::move(__x.__before_begin_)) {
5960b57cec5SDimitry Andric  __x.__before_begin()->__next_ = nullptr;
5970b57cec5SDimitry Andric}
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
600cb14a3feSDimitry Andricinline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, const allocator_type& __a)
601cb14a3feSDimitry Andric    : __before_begin_(__begin_node(), __node_allocator(__a)) {
602cb14a3feSDimitry Andric  if (__alloc() == __x.__alloc()) {
6030b57cec5SDimitry Andric    __before_begin()->__next_     = __x.__before_begin()->__next_;
6040b57cec5SDimitry Andric    __x.__before_begin()->__next_ = nullptr;
6050b57cec5SDimitry Andric  }
6060b57cec5SDimitry Andric}
6070b57cec5SDimitry Andric
6080b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
611cb14a3feSDimitry Andric__forward_list_base<_Tp, _Alloc>::~__forward_list_base() {
6120b57cec5SDimitry Andric  clear();
6130b57cec5SDimitry Andric}
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
616cb14a3feSDimitry Andricinline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
6170b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
6180b57cec5SDimitry Andric    _NOEXCEPT
6190b57cec5SDimitry Andric#else
620*0fca6ea1SDimitry Andric    _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
6210b57cec5SDimitry Andric#endif
6220b57cec5SDimitry Andric{
623cb14a3feSDimitry Andric  std::__swap_allocator(
624cb14a3feSDimitry Andric      __alloc(), __x.__alloc(), integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
6255f757f3fSDimitry Andric  using std::swap;
6260b57cec5SDimitry Andric  swap(__before_begin()->__next_, __x.__before_begin()->__next_);
6270b57cec5SDimitry Andric}
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
630cb14a3feSDimitry Andricvoid __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT {
631cb14a3feSDimitry Andric  for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) {
6320b57cec5SDimitry Andric    __node_pointer __next = __p->__next_;
6335f757f3fSDimitry Andric    __delete_node(__p);
6340b57cec5SDimitry Andric    __p = __next;
6350b57cec5SDimitry Andric  }
6360b57cec5SDimitry Andric  __before_begin()->__next_ = nullptr;
6370b57cec5SDimitry Andric}
6380b57cec5SDimitry Andric
6390b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc /*= allocator<_Tp>*/>
640cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS forward_list : private __forward_list_base<_Tp, _Alloc> {
6410b57cec5SDimitry Andric  typedef __forward_list_base<_Tp, _Alloc> base;
6420b57cec5SDimitry Andric  typedef typename base::__node_allocator __node_allocator;
6435f757f3fSDimitry Andric  typedef typename base::__node_type __node_type;
6440b57cec5SDimitry Andric  typedef typename base::__node_traits __node_traits;
6450b57cec5SDimitry Andric  typedef typename base::__node_pointer __node_pointer;
6460b57cec5SDimitry Andric  typedef typename base::__begin_node_pointer __begin_node_pointer;
6470b57cec5SDimitry Andric
6480b57cec5SDimitry Andricpublic:
6490b57cec5SDimitry Andric  typedef _Tp value_type;
6500b57cec5SDimitry Andric  typedef _Alloc allocator_type;
6510b57cec5SDimitry Andric
652*0fca6ea1SDimitry Andric  static_assert(__check_valid_allocator<allocator_type>::value, "");
653*0fca6ea1SDimitry Andric
65406c3fb27SDimitry Andric  static_assert(is_same<value_type, typename allocator_type::value_type>::value,
6550b57cec5SDimitry Andric                "Allocator::value_type must be same type as value_type");
6560b57cec5SDimitry Andric
657*0fca6ea1SDimitry Andric  static_assert(!is_same<allocator_type, __node_allocator>::value,
658*0fca6ea1SDimitry Andric                "internal allocator type must differ from user-specified type; otherwise overload resolution breaks");
65906c3fb27SDimitry Andric
6600b57cec5SDimitry Andric  typedef value_type& reference;
6610b57cec5SDimitry Andric  typedef const value_type& const_reference;
6620b57cec5SDimitry Andric  typedef typename allocator_traits<allocator_type>::pointer pointer;
6630b57cec5SDimitry Andric  typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
6644824e7fdSDimitry Andric  typedef typename allocator_traits<allocator_type>::size_type size_type;
6650b57cec5SDimitry Andric  typedef typename allocator_traits<allocator_type>::difference_type difference_type;
6660b57cec5SDimitry Andric
6670b57cec5SDimitry Andric  typedef typename base::iterator iterator;
6680b57cec5SDimitry Andric  typedef typename base::const_iterator const_iterator;
66906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
6700b57cec5SDimitry Andric  typedef size_type __remove_return_type;
6710b57cec5SDimitry Andric#else
6720b57cec5SDimitry Andric  typedef void __remove_return_type;
6730b57cec5SDimitry Andric#endif
6740b57cec5SDimitry Andric
675cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {
676cb14a3feSDimitry Andric  } // = default;
677cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit forward_list(const allocator_type& __a);
67806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n);
67906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
68006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a);
6810b57cec5SDimitry Andric#endif
68206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v);
6834824e7fdSDimitry Andric
684*0fca6ea1SDimitry Andric  template <__enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
685cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) {
6864824e7fdSDimitry Andric    insert_after(cbefore_begin(), __n, __v);
6874824e7fdSDimitry Andric  }
6884824e7fdSDimitry Andric
689*0fca6ea1SDimitry Andric  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
690*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l);
691*0fca6ea1SDimitry Andric
692*0fca6ea1SDimitry Andric  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
693*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a);
6940b57cec5SDimitry Andric
69506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
69606c3fb27SDimitry Andric  template <_ContainerCompatibleRange<_Tp> _Range>
697cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
698cb14a3feSDimitry Andric      : base(__a) {
69906c3fb27SDimitry Andric    prepend_range(std::forward<_Range>(__range));
70006c3fb27SDimitry Andric  }
70106c3fb27SDimitry Andric#endif
70206c3fb27SDimitry Andric
70306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x);
70406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
70506c3fb27SDimitry Andric
70606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x);
7070b57cec5SDimitry Andric
7080b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
709*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x) noexcept(is_nothrow_move_constructible<base>::value)
7105f757f3fSDimitry Andric      : base(std::move(__x)) {}
71106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
7120b57cec5SDimitry Andric
71306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il);
71406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a);
7150b57cec5SDimitry Andric
716*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list& operator=(forward_list&& __x) noexcept(
717*0fca6ea1SDimitry Andric      __node_traits::propagate_on_container_move_assignment::value &&
718*0fca6ea1SDimitry Andric      is_nothrow_move_assignable<allocator_type>::value);
7190b57cec5SDimitry Andric
720cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI forward_list& operator=(initializer_list<value_type> __il);
7210b57cec5SDimitry Andric
722cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il);
7230b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
7240b57cec5SDimitry Andric
7250b57cec5SDimitry Andric  // ~forward_list() = default;
7260b57cec5SDimitry Andric
7275f757f3fSDimitry Andric  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
728cb14a3feSDimitry Andric  void _LIBCPP_HIDE_FROM_ABI assign(_InputIterator __f, _InputIterator __l);
72906c3fb27SDimitry Andric
73006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
73106c3fb27SDimitry Andric  template <_ContainerCompatibleRange<_Tp> _Range>
732cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) {
73306c3fb27SDimitry Andric    __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
73406c3fb27SDimitry Andric  }
73506c3fb27SDimitry Andric#endif
73606c3fb27SDimitry Andric
73706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
7380b57cec5SDimitry Andric
739cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(base::__alloc()); }
7400b57cec5SDimitry Andric
741cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(base::__before_begin()->__next_); }
742cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
743cb14a3feSDimitry Andric    return const_iterator(base::__before_begin()->__next_);
744cb14a3feSDimitry Andric  }
745cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); }
746cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(nullptr); }
7470b57cec5SDimitry Andric
748cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
749cb14a3feSDimitry Andric    return const_iterator(base::__before_begin()->__next_);
750cb14a3feSDimitry Andric  }
751cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return const_iterator(nullptr); }
7520b57cec5SDimitry Andric
753cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT { return iterator(base::__before_begin()); }
754cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT { return const_iterator(base::__before_begin()); }
755cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
756cb14a3feSDimitry Andric    return const_iterator(base::__before_begin());
7570b57cec5SDimitry Andric  }
7580b57cec5SDimitry Andric
759*0fca6ea1SDimitry Andric  _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
760cb14a3feSDimitry Andric    return base::__before_begin()->__next_ == nullptr;
761cb14a3feSDimitry Andric  }
762cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
763cb14a3feSDimitry Andric    return std::min<size_type>(__node_traits::max_size(base::__alloc()), numeric_limits<difference_type>::max());
764cb14a3feSDimitry Andric  }
765cb14a3feSDimitry Andric
766cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference front() { return base::__before_begin()->__next_->__get_value(); }
767cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const_reference front() const { return base::__before_begin()->__next_->__get_value(); }
7680b57cec5SDimitry Andric
7690b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
77006c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
77106c3fb27SDimitry Andric  template <class... _Args>
77206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
7730b57cec5SDimitry Andric#  else
77406c3fb27SDimitry Andric  template <class... _Args>
77506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args);
7760b57cec5SDimitry Andric#  endif
77706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
7780b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
77906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
7800b57cec5SDimitry Andric
78106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
78206c3fb27SDimitry Andric  template <_ContainerCompatibleRange<_Tp> _Range>
783cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) {
78406c3fb27SDimitry Andric    insert_range_after(cbefore_begin(), std::forward<_Range>(__range));
78506c3fb27SDimitry Andric  }
78606c3fb27SDimitry Andric#endif
78706c3fb27SDimitry Andric
78806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void pop_front();
7890b57cec5SDimitry Andric
7900b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
7910b57cec5SDimitry Andric  template <class... _Args>
79206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator emplace_after(const_iterator __p, _Args&&... __args);
7930b57cec5SDimitry Andric
79406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, value_type&& __v);
795cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, initializer_list<value_type> __il) {
796cb14a3feSDimitry Andric    return insert_after(__p, __il.begin(), __il.end());
797cb14a3feSDimitry Andric  }
7980b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
79906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, const value_type& __v);
80006c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
8015f757f3fSDimitry Andric  template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
802cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
8030b57cec5SDimitry Andric
80406c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
80506c3fb27SDimitry Andric  template <_ContainerCompatibleRange<_Tp> _Range>
806cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator insert_range_after(const_iterator __position, _Range&& __range) {
80706c3fb27SDimitry Andric    return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
80806c3fb27SDimitry Andric  }
80906c3fb27SDimitry Andric#endif
81006c3fb27SDimitry Andric
81106c3fb27SDimitry Andric  template <class _InputIterator, class _Sentinel>
812cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l);
81306c3fb27SDimitry Andric
81406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p);
81506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l);
8160b57cec5SDimitry Andric
817cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(forward_list& __x)
8180b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
8190b57cec5SDimitry Andric      _NOEXCEPT
8200b57cec5SDimitry Andric#else
821*0fca6ea1SDimitry Andric      _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
8220b57cec5SDimitry Andric#endif
823cb14a3feSDimitry Andric  {
824cb14a3feSDimitry Andric    base::swap(__x);
825cb14a3feSDimitry Andric  }
8260b57cec5SDimitry Andric
82706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
82806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
829cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { base::clear(); }
8300b57cec5SDimitry Andric
831cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list&& __x);
832cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
833cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void
834cb14a3feSDimitry Andric  splice_after(const_iterator __p, forward_list&& __x, const_iterator __f, const_iterator __l);
83506c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x);
83606c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
837cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void
838cb14a3feSDimitry Andric  splice_after(const_iterator __p, forward_list& __x, const_iterator __f, const_iterator __l);
83906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __v);
84006c3fb27SDimitry Andric  template <class _Predicate>
84106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Predicate __pred);
842cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __remove_return_type unique() { return unique(__equal_to()); }
84306c3fb27SDimitry Andric  template <class _BinaryPredicate>
84406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred);
8450b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
846cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(forward_list&& __x) { merge(__x, __less<>()); }
8470b57cec5SDimitry Andric  template <class _Compare>
848cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(forward_list&& __x, _Compare __comp) {
849cb14a3feSDimitry Andric    merge(__x, std::move(__comp));
850cb14a3feSDimitry Andric  }
8510b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
852cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x) { merge(__x, __less<>()); }
85306c3fb27SDimitry Andric  template <class _Compare>
85406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp);
855cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void sort() { sort(__less<>()); }
856cb14a3feSDimitry Andric  template <class _Compare>
857cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void sort(_Compare __comp);
85806c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andricprivate:
8610b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
86206c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type)
8630b57cec5SDimitry Andric      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
86406c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type);
8650b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
8660b57cec5SDimitry Andric
86706c3fb27SDimitry Andric  template <class _Iter, class _Sent>
868cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iter __f, _Sent __l);
86906c3fb27SDimitry Andric
8700b57cec5SDimitry Andric  template <class _Compare>
871cb14a3feSDimitry Andric  static _LIBCPP_HIDE_FROM_ABI __node_pointer __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
8720b57cec5SDimitry Andric
87306c3fb27SDimitry Andric  // TODO: Make this _LIBCPP_HIDE_FROM_ABI
8740b57cec5SDimitry Andric  template <class _Compare>
875cb14a3feSDimitry Andric  static _LIBCPP_HIDDEN __node_pointer __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
8760b57cec5SDimitry Andric};
8770b57cec5SDimitry Andric
878349cc55cSDimitry Andric#if _LIBCPP_STD_VER >= 17
8790b57cec5SDimitry Andrictemplate <class _InputIterator,
880fe6060f1SDimitry Andric          class _Alloc = allocator<__iter_value_type<_InputIterator>>,
88106c3fb27SDimitry Andric          class        = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
882cb14a3feSDimitry Andric          class        = enable_if_t<__is_allocator<_Alloc>::value> >
883cb14a3feSDimitry Andricforward_list(_InputIterator, _InputIterator) -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
8840b57cec5SDimitry Andric
8850b57cec5SDimitry Andrictemplate <class _InputIterator,
8860b57cec5SDimitry Andric          class _Alloc,
88706c3fb27SDimitry Andric          class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
888cb14a3feSDimitry Andric          class = enable_if_t<__is_allocator<_Alloc>::value> >
889cb14a3feSDimitry Andricforward_list(_InputIterator, _InputIterator, _Alloc) -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
8900b57cec5SDimitry Andric#endif
8910b57cec5SDimitry Andric
89206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23
89306c3fb27SDimitry Andrictemplate <ranges::input_range _Range,
89406c3fb27SDimitry Andric          class _Alloc = allocator<ranges::range_value_t<_Range>>,
895cb14a3feSDimitry Andric          class        = enable_if_t<__is_allocator<_Alloc>::value> >
896cb14a3feSDimitry Andricforward_list(from_range_t, _Range&&, _Alloc = _Alloc()) -> forward_list<ranges::range_value_t<_Range>, _Alloc>;
89706c3fb27SDimitry Andric#endif
89806c3fb27SDimitry Andric
8990b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
900cb14a3feSDimitry Andricinline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : base(__a) {}
9010b57cec5SDimitry Andric
9020b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
903cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(size_type __n) {
904cb14a3feSDimitry Andric  if (__n > 0) {
905cb14a3feSDimitry Andric    for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
9065f757f3fSDimitry Andric      __p->__next_ = this->__create_node(/* next = */ nullptr);
9070b57cec5SDimitry Andric    }
9080b57cec5SDimitry Andric  }
9090b57cec5SDimitry Andric}
9100b57cec5SDimitry Andric
91106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
9120b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
913cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc) : base(__base_alloc) {
914cb14a3feSDimitry Andric  if (__n > 0) {
915cb14a3feSDimitry Andric    for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
9165f757f3fSDimitry Andric      __p->__next_ = this->__create_node(/* next = */ nullptr);
9170b57cec5SDimitry Andric    }
9180b57cec5SDimitry Andric  }
9190b57cec5SDimitry Andric}
9200b57cec5SDimitry Andric#endif
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
923cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) {
9240b57cec5SDimitry Andric  insert_after(cbefore_begin(), __n, __v);
9250b57cec5SDimitry Andric}
9260b57cec5SDimitry Andric
9270b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
928*0fca6ea1SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
929*0fca6ea1SDimitry Andricforward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l) {
9300b57cec5SDimitry Andric  insert_after(cbefore_begin(), __f, __l);
9310b57cec5SDimitry Andric}
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
934*0fca6ea1SDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
935*0fca6ea1SDimitry Andricforward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : base(__a) {
9360b57cec5SDimitry Andric  insert_after(cbefore_begin(), __f, __l);
9370b57cec5SDimitry Andric}
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
9400b57cec5SDimitry Andricforward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
941cb14a3feSDimitry Andric    : base(__node_traits::select_on_container_copy_construction(__x.__alloc())) {
9420b57cec5SDimitry Andric  insert_after(cbefore_begin(), __x.begin(), __x.end());
9430b57cec5SDimitry Andric}
9440b57cec5SDimitry Andric
9450b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
946cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a)
947cb14a3feSDimitry Andric    : base(__a) {
9480b57cec5SDimitry Andric  insert_after(cbefore_begin(), __x.begin(), __x.end());
9490b57cec5SDimitry Andric}
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
952cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) {
953cb14a3feSDimitry Andric  if (this != std::addressof(__x)) {
9540b57cec5SDimitry Andric    base::__copy_assign_alloc(__x);
9550b57cec5SDimitry Andric    assign(__x.begin(), __x.end());
9560b57cec5SDimitry Andric  }
9570b57cec5SDimitry Andric  return *this;
9580b57cec5SDimitry Andric}
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9610b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
962cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a)
963cb14a3feSDimitry Andric    : base(std::move(__x), __a) {
964cb14a3feSDimitry Andric  if (base::__alloc() != __x.__alloc()) {
9650b57cec5SDimitry Andric    typedef move_iterator<iterator> _Ip;
9660b57cec5SDimitry Andric    insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
9670b57cec5SDimitry Andric  }
9680b57cec5SDimitry Andric}
9690b57cec5SDimitry Andric
9700b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
971cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il) {
9720b57cec5SDimitry Andric  insert_after(cbefore_begin(), __il.begin(), __il.end());
9730b57cec5SDimitry Andric}
9740b57cec5SDimitry Andric
9750b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
976cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, const allocator_type& __a) : base(__a) {
9770b57cec5SDimitry Andric  insert_after(cbefore_begin(), __il.begin(), __il.end());
9780b57cec5SDimitry Andric}
9790b57cec5SDimitry Andric
9800b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
981cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
982cb14a3feSDimitry Andric    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
9830b57cec5SDimitry Andric  clear();
9840b57cec5SDimitry Andric  base::__move_assign_alloc(__x);
9850b57cec5SDimitry Andric  base::__before_begin()->__next_ = __x.__before_begin()->__next_;
9860b57cec5SDimitry Andric  __x.__before_begin()->__next_   = nullptr;
9870b57cec5SDimitry Andric}
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
990cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) {
9910b57cec5SDimitry Andric  if (base::__alloc() == __x.__alloc())
9920b57cec5SDimitry Andric    __move_assign(__x, true_type());
993cb14a3feSDimitry Andric  else {
9940b57cec5SDimitry Andric    typedef move_iterator<iterator> _Ip;
9950b57cec5SDimitry Andric    assign(_Ip(__x.begin()), _Ip(__x.end()));
9960b57cec5SDimitry Andric  }
9970b57cec5SDimitry Andric}
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1000cb14a3feSDimitry Andricinline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) _NOEXCEPT_(
1001cb14a3feSDimitry Andric    __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<allocator_type>::value) {
1002cb14a3feSDimitry Andric  __move_assign(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
10030b57cec5SDimitry Andric  return *this;
10040b57cec5SDimitry Andric}
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1007cb14a3feSDimitry Andricinline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) {
10080b57cec5SDimitry Andric  assign(__il.begin(), __il.end());
10090b57cec5SDimitry Andric  return *this;
10100b57cec5SDimitry Andric}
10110b57cec5SDimitry Andric
10120b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
10130b57cec5SDimitry Andric
10140b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
10155f757f3fSDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
1016cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) {
101706c3fb27SDimitry Andric  __assign_with_sentinel(__f, __l);
101806c3fb27SDimitry Andric}
101906c3fb27SDimitry Andric
102006c3fb27SDimitry Andrictemplate <class _Tp, class _Alloc>
102106c3fb27SDimitry Andrictemplate <class _Iter, class _Sent>
1022cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI void forward_list<_Tp, _Alloc>::__assign_with_sentinel(_Iter __f, _Sent __l) {
10230b57cec5SDimitry Andric  iterator __i = before_begin();
10245f757f3fSDimitry Andric  iterator __j = std::next(__i);
10250b57cec5SDimitry Andric  iterator __e = end();
10260b57cec5SDimitry Andric  for (; __j != __e && __f != __l; ++__i, (void)++__j, ++__f)
10270b57cec5SDimitry Andric    *__j = *__f;
10280b57cec5SDimitry Andric  if (__j == __e)
102906c3fb27SDimitry Andric    __insert_after_with_sentinel(__i, std::move(__f), std::move(__l));
10300b57cec5SDimitry Andric  else
10310b57cec5SDimitry Andric    erase_after(__i, __e);
10320b57cec5SDimitry Andric}
10330b57cec5SDimitry Andric
10340b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1035cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) {
10360b57cec5SDimitry Andric  iterator __i = before_begin();
10375f757f3fSDimitry Andric  iterator __j = std::next(__i);
10380b57cec5SDimitry Andric  iterator __e = end();
10390b57cec5SDimitry Andric  for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
10400b57cec5SDimitry Andric    *__j = __v;
10410b57cec5SDimitry Andric  if (__j == __e)
10420b57cec5SDimitry Andric    insert_after(__i, __n, __v);
10430b57cec5SDimitry Andric  else
10440b57cec5SDimitry Andric    erase_after(__i, __e);
10450b57cec5SDimitry Andric}
10460b57cec5SDimitry Andric
10470b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1050cb14a3feSDimitry Andricinline void forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) {
10510b57cec5SDimitry Andric  assign(__il.begin(), __il.end());
10520b57cec5SDimitry Andric}
10530b57cec5SDimitry Andric
10540b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
10550b57cec5SDimitry Andrictemplate <class... _Args>
105606c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
10570b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::reference
10580b57cec5SDimitry Andric#  else
10590b57cec5SDimitry Andricvoid
10600b57cec5SDimitry Andric#  endif
1061cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) {
1062cb14a3feSDimitry Andric  base::__before_begin()->__next_ =
1063cb14a3feSDimitry Andric      this->__create_node(/* next = */ base::__before_begin()->__next_, std::forward<_Args>(__args)...);
106406c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
10655f757f3fSDimitry Andric  return base::__before_begin()->__next_->__get_value();
10660b57cec5SDimitry Andric#  endif
10670b57cec5SDimitry Andric}
10680b57cec5SDimitry Andric
10690b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1070cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::push_front(value_type&& __v) {
10715f757f3fSDimitry Andric  base::__before_begin()->__next_ = this->__create_node(/* next = */ base::__before_begin()->__next_, std::move(__v));
10720b57cec5SDimitry Andric}
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
10750b57cec5SDimitry Andric
10760b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1077cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::push_front(const value_type& __v) {
10785f757f3fSDimitry Andric  base::__before_begin()->__next_ = this->__create_node(/* next = */ base::__before_begin()->__next_, __v);
10790b57cec5SDimitry Andric}
10800b57cec5SDimitry Andric
10810b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1082cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::pop_front() {
10830b57cec5SDimitry Andric  __node_pointer __p              = base::__before_begin()->__next_;
10840b57cec5SDimitry Andric  base::__before_begin()->__next_ = __p->__next_;
10855f757f3fSDimitry Andric  this->__delete_node(__p);
10860b57cec5SDimitry Andric}
10870b57cec5SDimitry Andric
10880b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10890b57cec5SDimitry Andric
10900b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
10910b57cec5SDimitry Andrictemplate <class... _Args>
10920b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator
1093cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) {
10940b57cec5SDimitry Andric  __begin_node_pointer const __r = __p.__get_begin();
10955f757f3fSDimitry Andric  __r->__next_                   = this->__create_node(/* next = */ __r->__next_, std::forward<_Args>(__args)...);
10960b57cec5SDimitry Andric  return iterator(__r->__next_);
10970b57cec5SDimitry Andric}
10980b57cec5SDimitry Andric
10990b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
11000b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator
1101cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) {
11020b57cec5SDimitry Andric  __begin_node_pointer const __r = __p.__get_begin();
11035f757f3fSDimitry Andric  __r->__next_                   = this->__create_node(/* next = */ __r->__next_, std::move(__v));
11040b57cec5SDimitry Andric  return iterator(__r->__next_);
11050b57cec5SDimitry Andric}
11060b57cec5SDimitry Andric
11070b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
11080b57cec5SDimitry Andric
11090b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
11100b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator
1111cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) {
11120b57cec5SDimitry Andric  __begin_node_pointer const __r = __p.__get_begin();
11135f757f3fSDimitry Andric  __r->__next_                   = this->__create_node(/* next = */ __r->__next_, __v);
11140b57cec5SDimitry Andric  return iterator(__r->__next_);
11150b57cec5SDimitry Andric}
11160b57cec5SDimitry Andric
11170b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
11180b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator
1119cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, const value_type& __v) {
11200b57cec5SDimitry Andric  __begin_node_pointer __r = __p.__get_begin();
1121cb14a3feSDimitry Andric  if (__n > 0) {
11225f757f3fSDimitry Andric    __node_pointer __first = this->__create_node(/* next = */ nullptr, __v);
11230b57cec5SDimitry Andric    __node_pointer __last  = __first;
112406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1125cb14a3feSDimitry Andric    try {
112606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1127cb14a3feSDimitry Andric      for (--__n; __n != 0; --__n, __last = __last->__next_) {
11285f757f3fSDimitry Andric        __last->__next_ = this->__create_node(/* next = */ nullptr, __v);
11290b57cec5SDimitry Andric      }
113006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1131cb14a3feSDimitry Andric    } catch (...) {
1132cb14a3feSDimitry Andric      while (__first != nullptr) {
11330b57cec5SDimitry Andric        __node_pointer __next = __first->__next_;
11345f757f3fSDimitry Andric        this->__delete_node(__first);
11350b57cec5SDimitry Andric        __first = __next;
11360b57cec5SDimitry Andric      }
11370b57cec5SDimitry Andric      throw;
11380b57cec5SDimitry Andric    }
113906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
11400b57cec5SDimitry Andric    __last->__next_ = __r->__next_;
11410b57cec5SDimitry Andric    __r->__next_    = __first;
11420b57cec5SDimitry Andric    __r             = static_cast<__begin_node_pointer>(__last);
11430b57cec5SDimitry Andric  }
11440b57cec5SDimitry Andric  return iterator(__r);
11450b57cec5SDimitry Andric}
11460b57cec5SDimitry Andric
11470b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
11485f757f3fSDimitry Andrictemplate <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
11495f757f3fSDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator
1150cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l) {
115106c3fb27SDimitry Andric  return __insert_after_with_sentinel(__p, std::move(__f), std::move(__l));
115206c3fb27SDimitry Andric}
115306c3fb27SDimitry Andric
115406c3fb27SDimitry Andrictemplate <class _Tp, class _Alloc>
115506c3fb27SDimitry Andrictemplate <class _InputIterator, class _Sentinel>
1156cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Alloc>::iterator
115706c3fb27SDimitry Andricforward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) {
11580b57cec5SDimitry Andric  __begin_node_pointer __r = __p.__get_begin();
115906c3fb27SDimitry Andric
1160cb14a3feSDimitry Andric  if (__f != __l) {
11615f757f3fSDimitry Andric    __node_pointer __first = this->__create_node(/* next = */ nullptr, *__f);
11620b57cec5SDimitry Andric    __node_pointer __last  = __first;
116306c3fb27SDimitry Andric
116406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1165cb14a3feSDimitry Andric    try {
116606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
1167cb14a3feSDimitry Andric      for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) {
11685f757f3fSDimitry Andric        __last->__next_ = this->__create_node(/* next = */ nullptr, *__f);
11690b57cec5SDimitry Andric      }
117006c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1171cb14a3feSDimitry Andric    } catch (...) {
1172cb14a3feSDimitry Andric      while (__first != nullptr) {
11730b57cec5SDimitry Andric        __node_pointer __next = __first->__next_;
11745f757f3fSDimitry Andric        this->__delete_node(__first);
11750b57cec5SDimitry Andric        __first = __next;
11760b57cec5SDimitry Andric      }
11770b57cec5SDimitry Andric      throw;
11780b57cec5SDimitry Andric    }
117906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
118006c3fb27SDimitry Andric
11810b57cec5SDimitry Andric    __last->__next_ = __r->__next_;
11820b57cec5SDimitry Andric    __r->__next_    = __first;
11830b57cec5SDimitry Andric    __r             = static_cast<__begin_node_pointer>(__last);
11840b57cec5SDimitry Andric  }
118506c3fb27SDimitry Andric
11860b57cec5SDimitry Andric  return iterator(__r);
11870b57cec5SDimitry Andric}
11880b57cec5SDimitry Andric
11890b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1190cb14a3feSDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) {
11910b57cec5SDimitry Andric  __begin_node_pointer __p = __f.__get_begin();
11920b57cec5SDimitry Andric  __node_pointer __n       = __p->__next_;
11930b57cec5SDimitry Andric  __p->__next_             = __n->__next_;
11945f757f3fSDimitry Andric  this->__delete_node(__n);
11950b57cec5SDimitry Andric  return iterator(__p->__next_);
11960b57cec5SDimitry Andric}
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
11990b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::iterator
1200cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) {
12010b57cec5SDimitry Andric  __node_pointer __e = __l.__get_unsafe_node_pointer();
1202cb14a3feSDimitry Andric  if (__f != __l) {
12030b57cec5SDimitry Andric    __begin_node_pointer __bp = __f.__get_begin();
12040b57cec5SDimitry Andric
12050b57cec5SDimitry Andric    __node_pointer __n = __bp->__next_;
1206cb14a3feSDimitry Andric    if (__n != __e) {
12070b57cec5SDimitry Andric      __bp->__next_ = __e;
1208cb14a3feSDimitry Andric      do {
12090b57cec5SDimitry Andric        __node_pointer __tmp = __n->__next_;
12105f757f3fSDimitry Andric        this->__delete_node(__n);
12110b57cec5SDimitry Andric        __n = __tmp;
12120b57cec5SDimitry Andric      } while (__n != __e);
12130b57cec5SDimitry Andric    }
12140b57cec5SDimitry Andric  }
12150b57cec5SDimitry Andric  return iterator(__e);
12160b57cec5SDimitry Andric}
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1219cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::resize(size_type __n) {
12200b57cec5SDimitry Andric  size_type __sz = 0;
12210b57cec5SDimitry Andric  iterator __p   = before_begin();
12220b57cec5SDimitry Andric  iterator __i   = begin();
12230b57cec5SDimitry Andric  iterator __e   = end();
12240b57cec5SDimitry Andric  for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
12250b57cec5SDimitry Andric    ;
12260b57cec5SDimitry Andric  if (__i != __e)
12270b57cec5SDimitry Andric    erase_after(__p, __e);
1228cb14a3feSDimitry Andric  else {
12290b57cec5SDimitry Andric    __n -= __sz;
1230cb14a3feSDimitry Andric    if (__n > 0) {
1231cb14a3feSDimitry Andric      for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) {
12325f757f3fSDimitry Andric        __ptr->__next_ = this->__create_node(/* next = */ nullptr);
12330b57cec5SDimitry Andric      }
12340b57cec5SDimitry Andric    }
12350b57cec5SDimitry Andric  }
12360b57cec5SDimitry Andric}
12370b57cec5SDimitry Andric
12380b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1239cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) {
12400b57cec5SDimitry Andric  size_type __sz = 0;
12410b57cec5SDimitry Andric  iterator __p   = before_begin();
12420b57cec5SDimitry Andric  iterator __i   = begin();
12430b57cec5SDimitry Andric  iterator __e   = end();
12440b57cec5SDimitry Andric  for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
12450b57cec5SDimitry Andric    ;
12460b57cec5SDimitry Andric  if (__i != __e)
12470b57cec5SDimitry Andric    erase_after(__p, __e);
1248cb14a3feSDimitry Andric  else {
12490b57cec5SDimitry Andric    __n -= __sz;
1250cb14a3feSDimitry Andric    if (__n > 0) {
1251cb14a3feSDimitry Andric      for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) {
12525f757f3fSDimitry Andric        __ptr->__next_ = this->__create_node(/* next = */ nullptr, __v);
12530b57cec5SDimitry Andric      }
12540b57cec5SDimitry Andric    }
12550b57cec5SDimitry Andric  }
12560b57cec5SDimitry Andric}
12570b57cec5SDimitry Andric
12580b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1259cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list& __x) {
1260cb14a3feSDimitry Andric  if (!__x.empty()) {
1261cb14a3feSDimitry Andric    if (__p.__get_begin()->__next_ != nullptr) {
12620b57cec5SDimitry Andric      const_iterator __lm1 = __x.before_begin();
12630b57cec5SDimitry Andric      while (__lm1.__get_begin()->__next_ != nullptr)
12640b57cec5SDimitry Andric        ++__lm1;
12650b57cec5SDimitry Andric      __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
12660b57cec5SDimitry Andric    }
12670b57cec5SDimitry Andric    __p.__get_begin()->__next_    = __x.__before_begin()->__next_;
12680b57cec5SDimitry Andric    __x.__before_begin()->__next_ = nullptr;
12690b57cec5SDimitry Andric  }
12700b57cec5SDimitry Andric}
12710b57cec5SDimitry Andric
12720b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1273cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list& /*__other*/, const_iterator __i) {
12745f757f3fSDimitry Andric  const_iterator __lm1 = std::next(__i);
1275cb14a3feSDimitry Andric  if (__p != __i && __p != __lm1) {
12760b57cec5SDimitry Andric    __i.__get_begin()->__next_   = __lm1.__get_begin()->__next_;
12770b57cec5SDimitry Andric    __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
12780b57cec5SDimitry Andric    __p.__get_begin()->__next_   = __lm1.__get_unsafe_node_pointer();
12790b57cec5SDimitry Andric  }
12800b57cec5SDimitry Andric}
12810b57cec5SDimitry Andric
12820b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1283cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::splice_after(
1284cb14a3feSDimitry Andric    const_iterator __p, forward_list& /*__other*/, const_iterator __f, const_iterator __l) {
1285cb14a3feSDimitry Andric  if (__f != __l && __p != __f) {
12860b57cec5SDimitry Andric    const_iterator __lm1 = __f;
12870b57cec5SDimitry Andric    while (__lm1.__get_begin()->__next_ != __l.__get_begin())
12880b57cec5SDimitry Andric      ++__lm1;
1289cb14a3feSDimitry Andric    if (__f != __lm1) {
12900b57cec5SDimitry Andric      __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
12910b57cec5SDimitry Andric      __p.__get_begin()->__next_   = __f.__get_begin()->__next_;
12920b57cec5SDimitry Andric      __f.__get_begin()->__next_   = __l.__get_unsafe_node_pointer();
12930b57cec5SDimitry Andric    }
12940b57cec5SDimitry Andric  }
12950b57cec5SDimitry Andric}
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1298cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list&& __x) {
12990b57cec5SDimitry Andric  splice_after(__p, __x);
13000b57cec5SDimitry Andric}
13010b57cec5SDimitry Andric
13020b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1303cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void
1304cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list&& __x, const_iterator __i) {
13050b57cec5SDimitry Andric  splice_after(__p, __x, __i);
13060b57cec5SDimitry Andric}
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1309cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void forward_list<_Tp, _Alloc>::splice_after(
1310cb14a3feSDimitry Andric    const_iterator __p, forward_list&& __x, const_iterator __f, const_iterator __l) {
13110b57cec5SDimitry Andric  splice_after(__p, __x, __f, __l);
13120b57cec5SDimitry Andric}
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1315cb14a3feSDimitry Andrictypename forward_list<_Tp, _Alloc>::__remove_return_type forward_list<_Tp, _Alloc>::remove(const value_type& __v) {
13160b57cec5SDimitry Andric  forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
13170b57cec5SDimitry Andric  typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
13180b57cec5SDimitry Andric  const iterator __e                                            = end();
1319cb14a3feSDimitry Andric  for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) {
1320cb14a3feSDimitry Andric    if (__i.__get_begin()->__next_->__get_value() == __v) {
13210b57cec5SDimitry Andric      ++__count_removed;
13225f757f3fSDimitry Andric      iterator __j = std::next(__i, 2);
13230b57cec5SDimitry Andric      for (; __j != __e && *__j == __v; ++__j)
13240b57cec5SDimitry Andric        ++__count_removed;
13250b57cec5SDimitry Andric      __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
13260b57cec5SDimitry Andric      if (__j == __e)
13270b57cec5SDimitry Andric        break;
13280b57cec5SDimitry Andric      __i = __j;
1329cb14a3feSDimitry Andric    } else
13300b57cec5SDimitry Andric      ++__i;
13310b57cec5SDimitry Andric  }
13320b57cec5SDimitry Andric
13330b57cec5SDimitry Andric  return (__remove_return_type)__count_removed;
13340b57cec5SDimitry Andric}
13350b57cec5SDimitry Andric
13360b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
13370b57cec5SDimitry Andrictemplate <class _Predicate>
1338cb14a3feSDimitry Andrictypename forward_list<_Tp, _Alloc>::__remove_return_type forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) {
13390b57cec5SDimitry Andric  forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
13400b57cec5SDimitry Andric  typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
13410b57cec5SDimitry Andric  const iterator __e                                            = end();
1342cb14a3feSDimitry Andric  for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) {
1343cb14a3feSDimitry Andric    if (__pred(__i.__get_begin()->__next_->__get_value())) {
13440b57cec5SDimitry Andric      ++__count_removed;
13455f757f3fSDimitry Andric      iterator __j = std::next(__i, 2);
13460b57cec5SDimitry Andric      for (; __j != __e && __pred(*__j); ++__j)
13470b57cec5SDimitry Andric        ++__count_removed;
13480b57cec5SDimitry Andric      __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
13490b57cec5SDimitry Andric      if (__j == __e)
13500b57cec5SDimitry Andric        break;
13510b57cec5SDimitry Andric      __i = __j;
1352cb14a3feSDimitry Andric    } else
13530b57cec5SDimitry Andric      ++__i;
13540b57cec5SDimitry Andric  }
13550b57cec5SDimitry Andric
13560b57cec5SDimitry Andric  return (__remove_return_type)__count_removed;
13570b57cec5SDimitry Andric}
13580b57cec5SDimitry Andric
13590b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
13600b57cec5SDimitry Andrictemplate <class _BinaryPredicate>
13610b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::__remove_return_type
1362cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) {
13630b57cec5SDimitry Andric  forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
13640b57cec5SDimitry Andric  typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1365cb14a3feSDimitry Andric  for (iterator __i = begin(), __e = end(); __i != __e;) {
13665f757f3fSDimitry Andric    iterator __j = std::next(__i);
13670b57cec5SDimitry Andric    for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
13680b57cec5SDimitry Andric      ++__count_removed;
13690b57cec5SDimitry Andric    if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
13700b57cec5SDimitry Andric      __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
13710b57cec5SDimitry Andric    __i = __j;
13720b57cec5SDimitry Andric  }
13730b57cec5SDimitry Andric
13740b57cec5SDimitry Andric  return (__remove_return_type)__count_removed;
13750b57cec5SDimitry Andric}
13760b57cec5SDimitry Andric
13770b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
13780b57cec5SDimitry Andrictemplate <class _Compare>
1379cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) {
1380cb14a3feSDimitry Andric  if (this != std::addressof(__x)) {
1381cb14a3feSDimitry Andric    base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_, __x.__before_begin()->__next_, __comp);
13820b57cec5SDimitry Andric    __x.__before_begin()->__next_   = nullptr;
13830b57cec5SDimitry Andric  }
13840b57cec5SDimitry Andric}
13850b57cec5SDimitry Andric
13860b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
13870b57cec5SDimitry Andrictemplate <class _Compare>
13880b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::__node_pointer
1389cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp) {
13900b57cec5SDimitry Andric  if (__f1 == nullptr)
13910b57cec5SDimitry Andric    return __f2;
13920b57cec5SDimitry Andric  if (__f2 == nullptr)
13930b57cec5SDimitry Andric    return __f1;
13940b57cec5SDimitry Andric  __node_pointer __r;
1395cb14a3feSDimitry Andric  if (__comp(__f2->__get_value(), __f1->__get_value())) {
13960b57cec5SDimitry Andric    __node_pointer __t = __f2;
1397cb14a3feSDimitry Andric    while (__t->__next_ != nullptr && __comp(__t->__next_->__get_value(), __f1->__get_value()))
13980b57cec5SDimitry Andric      __t = __t->__next_;
13990b57cec5SDimitry Andric    __r          = __f2;
14000b57cec5SDimitry Andric    __f2         = __t->__next_;
14010b57cec5SDimitry Andric    __t->__next_ = __f1;
1402cb14a3feSDimitry Andric  } else
14030b57cec5SDimitry Andric    __r = __f1;
14040b57cec5SDimitry Andric  __node_pointer __p = __f1;
14050b57cec5SDimitry Andric  __f1               = __f1->__next_;
1406cb14a3feSDimitry Andric  while (__f1 != nullptr && __f2 != nullptr) {
1407cb14a3feSDimitry Andric    if (__comp(__f2->__get_value(), __f1->__get_value())) {
14080b57cec5SDimitry Andric      __node_pointer __t = __f2;
1409cb14a3feSDimitry Andric      while (__t->__next_ != nullptr && __comp(__t->__next_->__get_value(), __f1->__get_value()))
14100b57cec5SDimitry Andric        __t = __t->__next_;
14110b57cec5SDimitry Andric      __p->__next_ = __f2;
14120b57cec5SDimitry Andric      __f2         = __t->__next_;
14130b57cec5SDimitry Andric      __t->__next_ = __f1;
14140b57cec5SDimitry Andric    }
14150b57cec5SDimitry Andric    __p  = __f1;
14160b57cec5SDimitry Andric    __f1 = __f1->__next_;
14170b57cec5SDimitry Andric  }
14180b57cec5SDimitry Andric  if (__f2 != nullptr)
14190b57cec5SDimitry Andric    __p->__next_ = __f2;
14200b57cec5SDimitry Andric  return __r;
14210b57cec5SDimitry Andric}
14220b57cec5SDimitry Andric
14230b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
14240b57cec5SDimitry Andrictemplate <class _Compare>
1425cb14a3feSDimitry Andricinline void forward_list<_Tp, _Alloc>::sort(_Compare __comp) {
1426cb14a3feSDimitry Andric  base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_, std::distance(begin(), end()), __comp);
14270b57cec5SDimitry Andric}
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
14300b57cec5SDimitry Andrictemplate <class _Compare>
14310b57cec5SDimitry Andrictypename forward_list<_Tp, _Alloc>::__node_pointer
1432cb14a3feSDimitry Andricforward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, _Compare& __comp) {
1433cb14a3feSDimitry Andric  switch (__sz) {
14340b57cec5SDimitry Andric  case 0:
14350b57cec5SDimitry Andric  case 1:
14360b57cec5SDimitry Andric    return __f1;
14370b57cec5SDimitry Andric  case 2:
1438cb14a3feSDimitry Andric    if (__comp(__f1->__next_->__get_value(), __f1->__get_value())) {
14390b57cec5SDimitry Andric      __node_pointer __t = __f1->__next_;
14400b57cec5SDimitry Andric      __t->__next_       = __f1;
14410b57cec5SDimitry Andric      __f1->__next_      = nullptr;
14420b57cec5SDimitry Andric      __f1               = __t;
14430b57cec5SDimitry Andric    }
14440b57cec5SDimitry Andric    return __f1;
14450b57cec5SDimitry Andric  }
14460b57cec5SDimitry Andric  difference_type __sz1 = __sz / 2;
14470b57cec5SDimitry Andric  difference_type __sz2 = __sz - __sz1;
14485f757f3fSDimitry Andric  __node_pointer __t    = std::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
14490b57cec5SDimitry Andric  __node_pointer __f2   = __t->__next_;
14500b57cec5SDimitry Andric  __t->__next_          = nullptr;
1451cb14a3feSDimitry Andric  return __merge(__sort(__f1, __sz1, __comp), __sort(__f2, __sz2, __comp), __comp);
14520b57cec5SDimitry Andric}
14530b57cec5SDimitry Andric
14540b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1455cb14a3feSDimitry Andricvoid forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT {
14560b57cec5SDimitry Andric  __node_pointer __p = base::__before_begin()->__next_;
1457cb14a3feSDimitry Andric  if (__p != nullptr) {
14580b57cec5SDimitry Andric    __node_pointer __f = __p->__next_;
14590b57cec5SDimitry Andric    __p->__next_       = nullptr;
1460cb14a3feSDimitry Andric    while (__f != nullptr) {
14610b57cec5SDimitry Andric      __node_pointer __t = __f->__next_;
14620b57cec5SDimitry Andric      __f->__next_       = __p;
14630b57cec5SDimitry Andric      __p                = __f;
14640b57cec5SDimitry Andric      __f                = __t;
14650b57cec5SDimitry Andric    }
14660b57cec5SDimitry Andric    base::__before_begin()->__next_ = __p;
14670b57cec5SDimitry Andric  }
14680b57cec5SDimitry Andric}
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1471cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
14720b57cec5SDimitry Andric  typedef forward_list<_Tp, _Alloc> _Cp;
14730b57cec5SDimitry Andric  typedef typename _Cp::const_iterator _Ip;
14740b57cec5SDimitry Andric  _Ip __ix = __x.begin();
14750b57cec5SDimitry Andric  _Ip __ex = __x.end();
14760b57cec5SDimitry Andric  _Ip __iy = __y.begin();
14770b57cec5SDimitry Andric  _Ip __ey = __y.end();
14780b57cec5SDimitry Andric  for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
14790b57cec5SDimitry Andric    if (!(*__ix == *__iy))
14800b57cec5SDimitry Andric      return false;
14810b57cec5SDimitry Andric  return (__ix == __ex) == (__iy == __ey);
14820b57cec5SDimitry Andric}
14830b57cec5SDimitry Andric
148406c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17
148506c3fb27SDimitry Andric
14860b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1487cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1488cb14a3feSDimitry Andricoperator!=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
14890b57cec5SDimitry Andric  return !(__x == __y);
14900b57cec5SDimitry Andric}
14910b57cec5SDimitry Andric
14920b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1493cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1494cb14a3feSDimitry Andricoperator<(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1495cb14a3feSDimitry Andric  return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
14960b57cec5SDimitry Andric}
14970b57cec5SDimitry Andric
14980b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1499cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1500cb14a3feSDimitry Andricoperator>(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
15010b57cec5SDimitry Andric  return __y < __x;
15020b57cec5SDimitry Andric}
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1505cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1506cb14a3feSDimitry Andricoperator>=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
15070b57cec5SDimitry Andric  return !(__x < __y);
15080b57cec5SDimitry Andric}
15090b57cec5SDimitry Andric
15100b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1511cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
1512cb14a3feSDimitry Andricoperator<=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
15130b57cec5SDimitry Andric  return !(__y < __x);
15140b57cec5SDimitry Andric}
15150b57cec5SDimitry Andric
151606c3fb27SDimitry Andric#else // #if _LIBCPP_STD_VER <= 17
151706c3fb27SDimitry Andric
151806c3fb27SDimitry Andrictemplate <class _Tp, class _Allocator>
151906c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
152006c3fb27SDimitry Andricoperator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _Allocator>& __y) {
152106c3fb27SDimitry Andric  return std::lexicographical_compare_three_way(
1522*0fca6ea1SDimitry Andric      __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
152306c3fb27SDimitry Andric}
152406c3fb27SDimitry Andric
152506c3fb27SDimitry Andric#endif // #if _LIBCPP_STD_VER <= 17
152606c3fb27SDimitry Andric
15270b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
1528cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1529cb14a3feSDimitry Andric    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
15300b57cec5SDimitry Andric  __x.swap(__y);
15310b57cec5SDimitry Andric}
15320b57cec5SDimitry Andric
153306c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20
15340b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Predicate>
1535cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
15365ffd83dbSDimitry Andricerase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
15375ffd83dbSDimitry Andric  return __c.remove_if(__pred);
15385ffd83dbSDimitry Andric}
15390b57cec5SDimitry Andric
15400b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator, class _Up>
1541cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
15425ffd83dbSDimitry Andricerase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) {
15435f757f3fSDimitry Andric  return std::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
15445ffd83dbSDimitry Andric}
15450b57cec5SDimitry Andric#endif
15460b57cec5SDimitry Andric
15470b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
15480b57cec5SDimitry Andric
154906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1550bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
1551bdd1243dSDimitry Andricnamespace pmr {
1552bdd1243dSDimitry Andrictemplate <class _ValueT>
155306c3fb27SDimitry Andricusing forward_list _LIBCPP_AVAILABILITY_PMR = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
1554bdd1243dSDimitry Andric} // namespace pmr
1555bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD
1556bdd1243dSDimitry Andric#endif
1557bdd1243dSDimitry Andric
15580b57cec5SDimitry Andric_LIBCPP_POP_MACROS
15590b57cec5SDimitry Andric
1560bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1561bdd1243dSDimitry Andric#  include <algorithm>
1562bdd1243dSDimitry Andric#  include <atomic>
1563bdd1243dSDimitry Andric#  include <concepts>
15645f757f3fSDimitry Andric#  include <cstdint>
156506c3fb27SDimitry Andric#  include <cstdlib>
15665f757f3fSDimitry Andric#  include <cstring>
1567bdd1243dSDimitry Andric#  include <functional>
1568bdd1243dSDimitry Andric#  include <iosfwd>
1569bdd1243dSDimitry Andric#  include <iterator>
15705f757f3fSDimitry Andric#  include <stdexcept>
157106c3fb27SDimitry Andric#  include <type_traits>
1572bdd1243dSDimitry Andric#  include <typeinfo>
1573bdd1243dSDimitry Andric#endif
1574bdd1243dSDimitry Andric
15750b57cec5SDimitry Andric#endif // _LIBCPP_FORWARD_LIST
1576