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