Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/c++/v1/forward_list is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP_FORWARD_LIST
0011 #define _LIBCPP_FORWARD_LIST
0012 
0013 /*
0014     forward_list synopsis
0015 
0016 namespace std
0017 {
0018 
0019 template <class T, class Allocator = allocator<T>>
0020 class forward_list
0021 {
0022 public:
0023     typedef T         value_type;
0024     typedef Allocator allocator_type;
0025 
0026     typedef value_type&                                                reference;
0027     typedef const value_type&                                          const_reference;
0028     typedef typename allocator_traits<allocator_type>::pointer         pointer;
0029     typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
0030     typedef typename allocator_traits<allocator_type>::size_type       size_type;
0031     typedef typename allocator_traits<allocator_type>::difference_type difference_type;
0032 
0033     typedef <details> iterator;
0034     typedef <details> const_iterator;
0035 
0036     forward_list()
0037         noexcept(is_nothrow_default_constructible<allocator_type>::value);
0038     explicit forward_list(const allocator_type& a);
0039     explicit forward_list(size_type n);
0040     explicit forward_list(size_type n, const allocator_type& a); // C++14
0041     forward_list(size_type n, const value_type& v);
0042     forward_list(size_type n, const value_type& v, const allocator_type& a);
0043     template <class InputIterator>
0044         forward_list(InputIterator first, InputIterator last);
0045     template <class InputIterator>
0046         forward_list(InputIterator first, InputIterator last, const allocator_type& a);
0047     template<container-compatible-range<T> R>
0048         forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
0049     forward_list(const forward_list& x);
0050     forward_list(const forward_list& x, const allocator_type& a);
0051     forward_list(forward_list&& x)
0052         noexcept(is_nothrow_move_constructible<allocator_type>::value);
0053     forward_list(forward_list&& x, const allocator_type& a);
0054     forward_list(initializer_list<value_type> il);
0055     forward_list(initializer_list<value_type> il, const allocator_type& a);
0056 
0057     ~forward_list();
0058 
0059     forward_list& operator=(const forward_list& x);
0060     forward_list& operator=(forward_list&& x)
0061         noexcept(
0062              allocator_type::propagate_on_container_move_assignment::value &&
0063              is_nothrow_move_assignable<allocator_type>::value);
0064     forward_list& operator=(initializer_list<value_type> il);
0065 
0066     template <class InputIterator>
0067         void assign(InputIterator first, InputIterator last);
0068     template<container-compatible-range<T> R>
0069       void assign_range(R&& rg); // C++23
0070     void assign(size_type n, const value_type& v);
0071     void assign(initializer_list<value_type> il);
0072 
0073     allocator_type get_allocator() const noexcept;
0074 
0075     iterator       begin() noexcept;
0076     const_iterator begin() const noexcept;
0077     iterator       end() noexcept;
0078     const_iterator end() const noexcept;
0079 
0080     const_iterator cbegin() const noexcept;
0081     const_iterator cend() const noexcept;
0082 
0083     iterator       before_begin() noexcept;
0084     const_iterator before_begin() const noexcept;
0085     const_iterator cbefore_begin() const noexcept;
0086 
0087     bool empty() const noexcept;
0088     size_type max_size() const noexcept;
0089 
0090     reference       front();
0091     const_reference front() const;
0092 
0093     template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
0094     void push_front(const value_type& v);
0095     void push_front(value_type&& v);
0096     template<container-compatible-range<T> R>
0097       void prepend_range(R&& rg); // C++23
0098 
0099     void pop_front();
0100 
0101     template <class... Args>
0102         iterator emplace_after(const_iterator p, Args&&... args);
0103     iterator insert_after(const_iterator p, const value_type& v);
0104     iterator insert_after(const_iterator p, value_type&& v);
0105     iterator insert_after(const_iterator p, size_type n, const value_type& v);
0106     template <class InputIterator>
0107         iterator insert_after(const_iterator p,
0108                               InputIterator first, InputIterator last);
0109     template<container-compatible-range<T> R>
0110       iterator insert_range_after(const_iterator position, R&& rg); // C++23
0111     iterator insert_after(const_iterator p, initializer_list<value_type> il);
0112 
0113     iterator erase_after(const_iterator p);
0114     iterator erase_after(const_iterator first, const_iterator last);
0115 
0116     void swap(forward_list& x)
0117         noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
0118 
0119     void resize(size_type n);
0120     void resize(size_type n, const value_type& v);
0121     void clear() noexcept;
0122 
0123     void splice_after(const_iterator p, forward_list& x);
0124     void splice_after(const_iterator p, forward_list&& x);
0125     void splice_after(const_iterator p, forward_list& x, const_iterator i);
0126     void splice_after(const_iterator p, forward_list&& x, const_iterator i);
0127     void splice_after(const_iterator p, forward_list& x,
0128                       const_iterator first, const_iterator last);
0129     void splice_after(const_iterator p, forward_list&& x,
0130                       const_iterator first, const_iterator last);
0131     size_type remove(const value_type& v);           // void before C++20
0132     template <class Predicate>
0133       size_type remove_if(Predicate pred);           // void before C++20
0134     size_type unique();                              // void before C++20
0135     template <class BinaryPredicate>
0136       size_type unique(BinaryPredicate binary_pred); // void before C++20
0137     void merge(forward_list& x);
0138     void merge(forward_list&& x);
0139     template <class Compare> void merge(forward_list& x, Compare comp);
0140     template <class Compare> void merge(forward_list&& x, Compare comp);
0141     void sort();
0142     template <class Compare> void sort(Compare comp);
0143     void reverse() noexcept;
0144 };
0145 
0146 
0147 template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
0148     forward_list(InputIterator, InputIterator, Allocator = Allocator())
0149     -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;  // C++17
0150 
0151 template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
0152   forward_list(from_range_t, R&&, Allocator = Allocator())
0153       -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23
0154 
0155 template <class T, class Allocator>
0156     bool operator==(const forward_list<T, Allocator>& x,
0157                     const forward_list<T, Allocator>& y);
0158 
0159 template <class T, class Allocator>
0160     bool operator< (const forward_list<T, Allocator>& x,
0161                     const forward_list<T, Allocator>& y); // removed in C++20
0162 
0163 template <class T, class Allocator>
0164     bool operator!=(const forward_list<T, Allocator>& x,
0165                     const forward_list<T, Allocator>& y); // removed in C++20
0166 
0167 template <class T, class Allocator>
0168     bool operator> (const forward_list<T, Allocator>& x,
0169                     const forward_list<T, Allocator>& y); // removed in C++20
0170 
0171 template <class T, class Allocator>
0172     bool operator>=(const forward_list<T, Allocator>& x,
0173                     const forward_list<T, Allocator>& y); // removed in C++20
0174 
0175 template <class T, class Allocator>
0176     bool operator<=(const forward_list<T, Allocator>& x,
0177                     const forward_list<T, Allocator>& y); // removed in C++20
0178 
0179 template<class T, class Allocator>
0180     synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x,
0181                                           const forward_list<T, Allocator>& y); // since C++20
0182 
0183 template <class T, class Allocator>
0184     void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
0185          noexcept(noexcept(x.swap(y)));
0186 
0187 template <class T, class Allocator, class U>
0188     typename forward_list<T, Allocator>::size_type
0189     erase(forward_list<T, Allocator>& c, const U& value);       // C++20
0190 template <class T, class Allocator, class Predicate>
0191     typename forward_list<T, Allocator>::size_type
0192     erase_if(forward_list<T, Allocator>& c, Predicate pred);    // C++20
0193 
0194 }  // std
0195 
0196 */
0197 
0198 #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0199 #  include <__cxx03/forward_list>
0200 #else
0201 #  include <__algorithm/comp.h>
0202 #  include <__algorithm/lexicographical_compare.h>
0203 #  include <__algorithm/lexicographical_compare_three_way.h>
0204 #  include <__algorithm/min.h>
0205 #  include <__assert>
0206 #  include <__config>
0207 #  include <__cstddef/nullptr_t.h>
0208 #  include <__iterator/distance.h>
0209 #  include <__iterator/iterator_traits.h>
0210 #  include <__iterator/move_iterator.h>
0211 #  include <__iterator/next.h>
0212 #  include <__memory/addressof.h>
0213 #  include <__memory/allocation_guard.h>
0214 #  include <__memory/allocator.h>
0215 #  include <__memory/allocator_traits.h>
0216 #  include <__memory/compressed_pair.h>
0217 #  include <__memory/construct_at.h>
0218 #  include <__memory/pointer_traits.h>
0219 #  include <__memory/swap_allocator.h>
0220 #  include <__memory_resource/polymorphic_allocator.h>
0221 #  include <__new/launder.h>
0222 #  include <__ranges/access.h>
0223 #  include <__ranges/concepts.h>
0224 #  include <__ranges/container_compatible_range.h>
0225 #  include <__ranges/from_range.h>
0226 #  include <__type_traits/conditional.h>
0227 #  include <__type_traits/container_traits.h>
0228 #  include <__type_traits/enable_if.h>
0229 #  include <__type_traits/is_allocator.h>
0230 #  include <__type_traits/is_const.h>
0231 #  include <__type_traits/is_nothrow_assignable.h>
0232 #  include <__type_traits/is_nothrow_constructible.h>
0233 #  include <__type_traits/is_pointer.h>
0234 #  include <__type_traits/is_same.h>
0235 #  include <__type_traits/is_swappable.h>
0236 #  include <__type_traits/type_identity.h>
0237 #  include <__utility/forward.h>
0238 #  include <__utility/move.h>
0239 #  include <__utility/swap.h>
0240 #  include <limits>
0241 #  include <version>
0242 
0243 // standard-mandated includes
0244 
0245 // [iterator.range]
0246 #  include <__iterator/access.h>
0247 #  include <__iterator/data.h>
0248 #  include <__iterator/empty.h>
0249 #  include <__iterator/reverse_access.h>
0250 #  include <__iterator/size.h>
0251 
0252 // [forward.list.syn]
0253 #  include <compare>
0254 #  include <initializer_list>
0255 
0256 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0257 #    pragma GCC system_header
0258 #  endif
0259 
0260 _LIBCPP_PUSH_MACROS
0261 #  include <__undef_macros>
0262 
0263 _LIBCPP_BEGIN_NAMESPACE_STD
0264 
0265 template <class _Tp, class _VoidPtr>
0266 struct __forward_list_node;
0267 template <class _NodePtr>
0268 struct __forward_begin_node;
0269 
0270 template <class>
0271 struct __forward_list_node_value_type;
0272 
0273 template <class _Tp, class _VoidPtr>
0274 struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
0275   typedef _Tp type;
0276 };
0277 
0278 template <class _NodePtr>
0279 struct __forward_node_traits {
0280   typedef __remove_cv_t<typename pointer_traits<_NodePtr>::element_type> __node_type;
0281   typedef typename __forward_list_node_value_type<__node_type>::type __node_value_type;
0282   typedef _NodePtr __node_pointer;
0283   typedef __forward_begin_node<_NodePtr> __begin_node;
0284   typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer;
0285   typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
0286 
0287 // TODO(LLVM 22): Remove this check
0288 #  ifndef _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
0289   static_assert(sizeof(__begin_node_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__begin_node_pointer) ==
0290                     _LIBCPP_ALIGNOF(__node_pointer),
0291                 "It looks like you are using std::forward_list with a fancy pointer type that thas a different "
0292                 "representation depending on whether it points to a forward_list base pointer or a forward_list node "
0293                 "pointer (both of which are implementation details of the standard library). This means that your ABI "
0294                 "is being broken between LLVM 19 and LLVM 20. If you don't care about your ABI being broken, define "
0295                 "the _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB macro to silence this diagnostic.");
0296 #  endif
0297 
0298   _LIBCPP_HIDE_FROM_ABI static __begin_node_pointer __as_iter_node(__begin_node_pointer __p) { return __p; }
0299   _LIBCPP_HIDE_FROM_ABI static __begin_node_pointer __as_iter_node(__node_pointer __p) {
0300     return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__p));
0301   }
0302 };
0303 
0304 template <class _NodePtr>
0305 struct __forward_begin_node {
0306   typedef _NodePtr pointer;
0307   typedef __rebind_pointer_t<_NodePtr, __forward_begin_node> __begin_node_pointer;
0308 
0309   pointer __next_;
0310 
0311   _LIBCPP_HIDE_FROM_ABI __forward_begin_node() : __next_(nullptr) {}
0312   _LIBCPP_HIDE_FROM_ABI explicit __forward_begin_node(pointer __n) : __next_(__n) {}
0313 
0314   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __next_as_begin() const {
0315     return static_cast<__begin_node_pointer>(__next_);
0316   }
0317 };
0318 
0319 template <class _Tp, class _VoidPtr>
0320 using __begin_node_of _LIBCPP_NODEBUG =
0321     __forward_begin_node<__rebind_pointer_t<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> > >;
0322 
0323 template <class _Tp, class _VoidPtr>
0324 struct __forward_list_node : public __begin_node_of<_Tp, _VoidPtr> {
0325   typedef _Tp value_type;
0326   typedef __begin_node_of<_Tp, _VoidPtr> _Base;
0327   typedef typename _Base::pointer _NodePtr;
0328 
0329   // We allow starting the lifetime of nodes without initializing the value held by the node,
0330   // since that is handled by the list itself in order to be allocator-aware.
0331 #  ifndef _LIBCPP_CXX03_LANG
0332 
0333 private:
0334   union {
0335     _Tp __value_;
0336   };
0337 
0338 public:
0339   _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; }
0340 #  else
0341 
0342 private:
0343   _ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)];
0344 
0345 public:
0346   _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
0347 #  endif
0348 
0349   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_node(_NodePtr __next) : _Base(__next) {}
0350   _LIBCPP_HIDE_FROM_ABI ~__forward_list_node() {}
0351 };
0352 
0353 template <class _Tp, class _Alloc = allocator<_Tp> >
0354 class _LIBCPP_TEMPLATE_VIS forward_list;
0355 template <class _NodeConstPtr>
0356 class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
0357 
0358 template <class _NodePtr>
0359 class _LIBCPP_TEMPLATE_VIS __forward_list_iterator {
0360   typedef __forward_node_traits<_NodePtr> __traits;
0361   typedef typename __traits::__node_pointer __node_pointer;
0362   typedef typename __traits::__begin_node_pointer __begin_node_pointer;
0363   typedef typename __traits::__void_pointer __void_pointer;
0364 
0365   __begin_node_pointer __ptr_;
0366 
0367   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
0368     return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__ptr_));
0369   }
0370   _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
0371     return static_cast<__node_pointer>(static_cast<__void_pointer>(__ptr_));
0372   }
0373 
0374   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
0375 
0376   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
0377       : __ptr_(__traits::__as_iter_node(__p)) {}
0378 
0379   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
0380       : __ptr_(__traits::__as_iter_node(__p)) {}
0381 
0382   template <class, class>
0383   friend class _LIBCPP_TEMPLATE_VIS forward_list;
0384   template <class>
0385   friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
0386 
0387 public:
0388   typedef forward_iterator_tag iterator_category;
0389   typedef typename __traits::__node_value_type value_type;
0390   typedef value_type& reference;
0391   typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
0392   typedef __rebind_pointer_t<__node_pointer, value_type> pointer;
0393 
0394   _LIBCPP_HIDE_FROM_ABI __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
0395 
0396   _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_unsafe_node_pointer()->__get_value(); }
0397   _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
0398     return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__get_value());
0399   }
0400 
0401   _LIBCPP_HIDE_FROM_ABI __forward_list_iterator& operator++() {
0402     __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
0403     return *this;
0404   }
0405   _LIBCPP_HIDE_FROM_ABI __forward_list_iterator operator++(int) {
0406     __forward_list_iterator __t(*this);
0407     ++(*this);
0408     return __t;
0409   }
0410 
0411   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __forward_list_iterator& __x, const __forward_list_iterator& __y) {
0412     return __x.__ptr_ == __y.__ptr_;
0413   }
0414   friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __forward_list_iterator& __x, const __forward_list_iterator& __y) {
0415     return !(__x == __y);
0416   }
0417 };
0418 
0419 template <class _NodeConstPtr>
0420 class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator {
0421   static_assert(!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value, "");
0422   typedef _NodeConstPtr _NodePtr;
0423 
0424   typedef __forward_node_traits<_NodePtr> __traits;
0425   typedef typename __traits::__node_type __node_type;
0426   typedef typename __traits::__node_pointer __node_pointer;
0427   typedef typename __traits::__begin_node_pointer __begin_node_pointer;
0428   typedef typename __traits::__void_pointer __void_pointer;
0429 
0430   __begin_node_pointer __ptr_;
0431 
0432   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
0433     return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__ptr_));
0434   }
0435   _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
0436     return static_cast<__node_pointer>(static_cast<__void_pointer>(__ptr_));
0437   }
0438 
0439   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
0440 
0441   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
0442       : __ptr_(__traits::__as_iter_node(__p)) {}
0443 
0444   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
0445       : __ptr_(__traits::__as_iter_node(__p)) {}
0446 
0447   template <class, class>
0448   friend class forward_list;
0449 
0450 public:
0451   typedef forward_iterator_tag iterator_category;
0452   typedef typename __traits::__node_value_type value_type;
0453   typedef const value_type& reference;
0454   typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
0455   typedef __rebind_pointer_t<__node_pointer, const value_type> pointer;
0456 
0457   _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
0458   _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
0459       : __ptr_(__p.__ptr_) {}
0460 
0461   _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_unsafe_node_pointer()->__get_value(); }
0462   _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
0463     return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__get_value());
0464   }
0465 
0466   _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator& operator++() {
0467     __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
0468     return *this;
0469   }
0470   _LIBCPP_HIDE_FROM_ABI __forward_list_const_iterator operator++(int) {
0471     __forward_list_const_iterator __t(*this);
0472     ++(*this);
0473     return __t;
0474   }
0475 
0476   friend _LIBCPP_HIDE_FROM_ABI bool
0477   operator==(const __forward_list_const_iterator& __x, const __forward_list_const_iterator& __y) {
0478     return __x.__ptr_ == __y.__ptr_;
0479   }
0480   friend _LIBCPP_HIDE_FROM_ABI bool
0481   operator!=(const __forward_list_const_iterator& __x, const __forward_list_const_iterator& __y) {
0482     return !(__x == __y);
0483   }
0484 };
0485 
0486 template <class _Tp, class _Alloc>
0487 class __forward_list_base {
0488 protected:
0489   typedef _Tp value_type;
0490   typedef _Alloc allocator_type;
0491 
0492   typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
0493   typedef __forward_list_node<value_type, void_pointer> __node_type;
0494   typedef __begin_node_of<value_type, void_pointer> __begin_node;
0495   typedef __rebind_alloc<allocator_traits<allocator_type>, __node_type> __node_allocator;
0496   typedef allocator_traits<__node_allocator> __node_traits;
0497   typedef typename __node_traits::pointer __node_pointer;
0498 
0499   typedef __rebind_alloc<allocator_traits<allocator_type>, __begin_node> __begin_node_allocator;
0500   typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
0501 
0502   _LIBCPP_COMPRESSED_PAIR(__begin_node, __before_begin_, __node_allocator, __alloc_);
0503 
0504   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __before_begin() _NOEXCEPT {
0505     return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_);
0506   }
0507   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __before_begin() const _NOEXCEPT {
0508     return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_));
0509   }
0510 
0511   typedef __forward_list_iterator<__node_pointer> iterator;
0512   typedef __forward_list_const_iterator<__node_pointer> const_iterator;
0513 
0514   _LIBCPP_HIDE_FROM_ABI __forward_list_base() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
0515       : __before_begin_(__begin_node()) {}
0516   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_base(const allocator_type& __a)
0517       : __before_begin_(__begin_node()), __alloc_(__node_allocator(__a)) {}
0518   _LIBCPP_HIDE_FROM_ABI explicit __forward_list_base(const __node_allocator& __a)
0519       : __before_begin_(__begin_node()), __alloc_(__a) {}
0520 
0521 public:
0522 #  ifndef _LIBCPP_CXX03_LANG
0523   _LIBCPP_HIDE_FROM_ABI
0524   __forward_list_base(__forward_list_base&& __x) noexcept(is_nothrow_move_constructible<__node_allocator>::value);
0525   _LIBCPP_HIDE_FROM_ABI __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
0526 #  endif // _LIBCPP_CXX03_LANG
0527 
0528   __forward_list_base(const __forward_list_base&)            = delete;
0529   __forward_list_base& operator=(const __forward_list_base&) = delete;
0530 
0531   _LIBCPP_HIDE_FROM_ABI ~__forward_list_base();
0532 
0533 protected:
0534   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __forward_list_base& __x) {
0535     __copy_assign_alloc(__x, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
0536   }
0537 
0538   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x)
0539       _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
0540                  is_nothrow_move_assignable<__node_allocator>::value) {
0541     __move_assign_alloc(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
0542   }
0543 
0544   template <class... _Args>
0545   _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__node_pointer __next, _Args&&... __args) {
0546     __allocation_guard<__node_allocator> __guard(__alloc_, 1);
0547     // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
0548     // held inside the node, since we need to use the allocator's construct() method for that.
0549     //
0550     // We don't use the allocator's construct() method to construct the node itself since the
0551     // Cpp17FooInsertable named requirements don't require the allocator's construct() method
0552     // to work on anything other than the value_type.
0553     std::__construct_at(std::addressof(*__guard.__get()), __next);
0554 
0555     // Now construct the value_type using the allocator's construct() method.
0556     __node_traits::construct(__alloc_, std::addressof(__guard.__get()->__get_value()), std::forward<_Args>(__args)...);
0557     return __guard.__release_ptr();
0558   }
0559 
0560   _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) {
0561     // For the same reason as above, we use the allocator's destroy() method for the value_type,
0562     // but not for the node itself.
0563     __node_traits::destroy(__alloc_, std::addressof(__node->__get_value()));
0564     std::__destroy_at(std::addressof(*__node));
0565     __node_traits::deallocate(__alloc_, __node, 1);
0566   }
0567 
0568 public:
0569   _LIBCPP_HIDE_FROM_ABI void swap(__forward_list_base& __x)
0570 #  if _LIBCPP_STD_VER >= 14
0571       _NOEXCEPT;
0572 #  else
0573       _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>);
0574 #  endif
0575 
0576 protected:
0577   _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
0578 
0579 private:
0580   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __forward_list_base&, false_type) {}
0581   _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __forward_list_base& __x, true_type) {
0582     if (__alloc_ != __x.__alloc_)
0583       clear();
0584     __alloc_ = __x.__alloc_;
0585   }
0586 
0587   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT {}
0588   _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__forward_list_base& __x, true_type)
0589       _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
0590     __alloc_ = std::move(__x.__alloc_);
0591   }
0592 };
0593 
0594 #  ifndef _LIBCPP_CXX03_LANG
0595 
0596 template <class _Tp, class _Alloc>
0597 inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) noexcept(
0598     is_nothrow_move_constructible<__node_allocator>::value)
0599     : __before_begin_(std::move(__x.__before_begin_)), __alloc_(std::move(__x.__alloc_)) {
0600   __x.__before_begin()->__next_ = nullptr;
0601 }
0602 
0603 template <class _Tp, class _Alloc>
0604 inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, const allocator_type& __a)
0605     : __before_begin_(__begin_node()), __alloc_(__node_allocator(__a)) {
0606   if (__alloc_ == __x.__alloc_) {
0607     __before_begin()->__next_     = __x.__before_begin()->__next_;
0608     __x.__before_begin()->__next_ = nullptr;
0609   }
0610 }
0611 
0612 #  endif // _LIBCPP_CXX03_LANG
0613 
0614 template <class _Tp, class _Alloc>
0615 __forward_list_base<_Tp, _Alloc>::~__forward_list_base() {
0616   clear();
0617 }
0618 
0619 template <class _Tp, class _Alloc>
0620 inline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
0621 #  if _LIBCPP_STD_VER >= 14
0622     _NOEXCEPT
0623 #  else
0624     _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
0625 #  endif
0626 {
0627   std::__swap_allocator(__alloc_, __x.__alloc_);
0628   using std::swap;
0629   swap(__before_begin()->__next_, __x.__before_begin()->__next_);
0630 }
0631 
0632 template <class _Tp, class _Alloc>
0633 void __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT {
0634   for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) {
0635     __node_pointer __next = __p->__next_;
0636     __delete_node(__p);
0637     __p = __next;
0638   }
0639   __before_begin()->__next_ = nullptr;
0640 }
0641 
0642 template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
0643 class _LIBCPP_TEMPLATE_VIS forward_list : private __forward_list_base<_Tp, _Alloc> {
0644   typedef __forward_list_base<_Tp, _Alloc> __base;
0645   typedef typename __base::__node_allocator __node_allocator;
0646   typedef typename __base::__node_type __node_type;
0647   typedef typename __base::__node_traits __node_traits;
0648   typedef typename __base::__node_pointer __node_pointer;
0649   typedef typename __base::__begin_node_pointer __begin_node_pointer;
0650 
0651 public:
0652   typedef _Tp value_type;
0653   typedef _Alloc allocator_type;
0654 
0655   static_assert(__check_valid_allocator<allocator_type>::value, "");
0656 
0657   static_assert(is_same<value_type, typename allocator_type::value_type>::value,
0658                 "Allocator::value_type must be same type as value_type");
0659 
0660   static_assert(!is_same<allocator_type, __node_allocator>::value,
0661                 "internal allocator type must differ from user-specified type; otherwise overload resolution breaks");
0662 
0663   typedef value_type& reference;
0664   typedef const value_type& const_reference;
0665   typedef typename allocator_traits<allocator_type>::pointer pointer;
0666   typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
0667   typedef typename allocator_traits<allocator_type>::size_type size_type;
0668   typedef typename allocator_traits<allocator_type>::difference_type difference_type;
0669 
0670   typedef typename __base::iterator iterator;
0671   typedef typename __base::const_iterator const_iterator;
0672 #  if _LIBCPP_STD_VER >= 20
0673   typedef size_type __remove_return_type;
0674 #  else
0675   typedef void __remove_return_type;
0676 #  endif
0677 
0678   _LIBCPP_HIDE_FROM_ABI forward_list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {
0679   } // = default;
0680   _LIBCPP_HIDE_FROM_ABI explicit forward_list(const allocator_type& __a);
0681   _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n);
0682 #  if _LIBCPP_STD_VER >= 14
0683   _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a);
0684 #  endif
0685   _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v);
0686 
0687   template <__enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
0688   _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : __base(__a) {
0689     insert_after(cbefore_begin(), __n, __v);
0690   }
0691 
0692   template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
0693   _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l);
0694 
0695   template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
0696   _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a);
0697 
0698 #  if _LIBCPP_STD_VER >= 23
0699   template <_ContainerCompatibleRange<_Tp> _Range>
0700   _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
0701       : __base(__a) {
0702     prepend_range(std::forward<_Range>(__range));
0703   }
0704 #  endif
0705 
0706   _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x);
0707   _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a);
0708 
0709   _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x);
0710 
0711 #  ifndef _LIBCPP_CXX03_LANG
0712   _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x) noexcept(is_nothrow_move_constructible<__base>::value)
0713       : __base(std::move(__x)) {}
0714   _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
0715 
0716   _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il);
0717   _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a);
0718 
0719   _LIBCPP_HIDE_FROM_ABI forward_list& operator=(forward_list&& __x) noexcept(
0720       __node_traits::propagate_on_container_move_assignment::value &&
0721       is_nothrow_move_assignable<allocator_type>::value);
0722 
0723   _LIBCPP_HIDE_FROM_ABI forward_list& operator=(initializer_list<value_type> __il);
0724 
0725   _LIBCPP_HIDE_FROM_ABI void assign(initializer_list<value_type> __il);
0726 #  endif // _LIBCPP_CXX03_LANG
0727 
0728   // ~forward_list() = default;
0729 
0730   template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
0731   void _LIBCPP_HIDE_FROM_ABI assign(_InputIterator __f, _InputIterator __l);
0732 
0733 #  if _LIBCPP_STD_VER >= 23
0734   template <_ContainerCompatibleRange<_Tp> _Range>
0735   _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) {
0736     __assign_with_sentinel(ranges::begin(__range), ranges::end(__range));
0737   }
0738 #  endif
0739 
0740   _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
0741 
0742   _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(this->__alloc_); }
0743 
0744   _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__base::__before_begin()->__next_); }
0745   _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
0746     return const_iterator(__base::__before_begin()->__next_);
0747   }
0748   _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); }
0749   _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(nullptr); }
0750 
0751   _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
0752     return const_iterator(__base::__before_begin()->__next_);
0753   }
0754   _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return const_iterator(nullptr); }
0755 
0756   _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT { return iterator(__base::__before_begin()); }
0757   _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
0758     return const_iterator(__base::__before_begin());
0759   }
0760   _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
0761     return const_iterator(__base::__before_begin());
0762   }
0763 
0764   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
0765     return __base::__before_begin()->__next_ == nullptr;
0766   }
0767   _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
0768     return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
0769   }
0770 
0771   _LIBCPP_HIDE_FROM_ABI reference front() {
0772     _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
0773     return __base::__before_begin()->__next_->__get_value();
0774   }
0775   _LIBCPP_HIDE_FROM_ABI const_reference front() const {
0776     _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
0777     return __base::__before_begin()->__next_->__get_value();
0778   }
0779 
0780 #  ifndef _LIBCPP_CXX03_LANG
0781 #    if _LIBCPP_STD_VER >= 17
0782   template <class... _Args>
0783   _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args);
0784 #    else
0785   template <class... _Args>
0786   _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args);
0787 #    endif
0788   _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v);
0789 #  endif // _LIBCPP_CXX03_LANG
0790   _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v);
0791 
0792 #  if _LIBCPP_STD_VER >= 23
0793   template <_ContainerCompatibleRange<_Tp> _Range>
0794   _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) {
0795     insert_range_after(cbefore_begin(), std::forward<_Range>(__range));
0796   }
0797 #  endif
0798 
0799   _LIBCPP_HIDE_FROM_ABI void pop_front();
0800 
0801 #  ifndef _LIBCPP_CXX03_LANG
0802   template <class... _Args>
0803   _LIBCPP_HIDE_FROM_ABI iterator emplace_after(const_iterator __p, _Args&&... __args);
0804 
0805   _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, value_type&& __v);
0806   _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, initializer_list<value_type> __il) {
0807     return insert_after(__p, __il.begin(), __il.end());
0808   }
0809 #  endif // _LIBCPP_CXX03_LANG
0810   _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, const value_type& __v);
0811   _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
0812   template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
0813   _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
0814 
0815 #  if _LIBCPP_STD_VER >= 23
0816   template <_ContainerCompatibleRange<_Tp> _Range>
0817   _LIBCPP_HIDE_FROM_ABI iterator insert_range_after(const_iterator __position, _Range&& __range) {
0818     return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
0819   }
0820 #  endif
0821 
0822   template <class _InputIterator, class _Sentinel>
0823   _LIBCPP_HIDE_FROM_ABI iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l);
0824 
0825   _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p);
0826   _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l);
0827 
0828   _LIBCPP_HIDE_FROM_ABI void swap(forward_list& __x)
0829 #  if _LIBCPP_STD_VER >= 14
0830       _NOEXCEPT
0831 #  else
0832       _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
0833 #  endif
0834   {
0835     __base::swap(__x);
0836   }
0837 
0838   _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
0839   _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
0840   _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __base::clear(); }
0841 
0842   _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list&& __x);
0843   _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
0844   _LIBCPP_HIDE_FROM_ABI void
0845   splice_after(const_iterator __p, forward_list&& __x, const_iterator __f, const_iterator __l);
0846   _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x);
0847   _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
0848   _LIBCPP_HIDE_FROM_ABI void
0849   splice_after(const_iterator __p, forward_list& __x, const_iterator __f, const_iterator __l);
0850   _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __v);
0851   template <class _Predicate>
0852   _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Predicate __pred);
0853   _LIBCPP_HIDE_FROM_ABI __remove_return_type unique() { return unique(__equal_to()); }
0854   template <class _BinaryPredicate>
0855   _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred);
0856 #  ifndef _LIBCPP_CXX03_LANG
0857   _LIBCPP_HIDE_FROM_ABI void merge(forward_list&& __x) { merge(__x, __less<>()); }
0858   template <class _Compare>
0859   _LIBCPP_HIDE_FROM_ABI void merge(forward_list&& __x, _Compare __comp) {
0860     merge(__x, std::move(__comp));
0861   }
0862 #  endif // _LIBCPP_CXX03_LANG
0863   _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x) { merge(__x, __less<>()); }
0864   template <class _Compare>
0865   _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp);
0866   _LIBCPP_HIDE_FROM_ABI void sort() { sort(__less<>()); }
0867   template <class _Compare>
0868   _LIBCPP_HIDE_FROM_ABI void sort(_Compare __comp);
0869   _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
0870 
0871 private:
0872 #  ifndef _LIBCPP_CXX03_LANG
0873   _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type)
0874       _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
0875   _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type);
0876 #  endif // _LIBCPP_CXX03_LANG
0877 
0878   template <class _Iter, class _Sent>
0879   _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iter __f, _Sent __l);
0880 
0881   template <class _Compare>
0882   static _LIBCPP_HIDE_FROM_ABI __node_pointer __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
0883 
0884   // TODO: Make this _LIBCPP_HIDE_FROM_ABI
0885   template <class _Compare>
0886   static _LIBCPP_HIDDEN __node_pointer __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
0887 };
0888 
0889 #  if _LIBCPP_STD_VER >= 17
0890 template <class _InputIterator,
0891           class _Alloc = allocator<__iter_value_type<_InputIterator>>,
0892           class        = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
0893           class        = enable_if_t<__is_allocator<_Alloc>::value> >
0894 forward_list(_InputIterator, _InputIterator) -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
0895 
0896 template <class _InputIterator,
0897           class _Alloc,
0898           class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>,
0899           class = enable_if_t<__is_allocator<_Alloc>::value> >
0900 forward_list(_InputIterator, _InputIterator, _Alloc) -> forward_list<__iter_value_type<_InputIterator>, _Alloc>;
0901 #  endif
0902 
0903 #  if _LIBCPP_STD_VER >= 23
0904 template <ranges::input_range _Range,
0905           class _Alloc = allocator<ranges::range_value_t<_Range>>,
0906           class        = enable_if_t<__is_allocator<_Alloc>::value> >
0907 forward_list(from_range_t, _Range&&, _Alloc = _Alloc()) -> forward_list<ranges::range_value_t<_Range>, _Alloc>;
0908 #  endif
0909 
0910 template <class _Tp, class _Alloc>
0911 inline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : __base(__a) {}
0912 
0913 template <class _Tp, class _Alloc>
0914 forward_list<_Tp, _Alloc>::forward_list(size_type __n) {
0915   if (__n > 0) {
0916     for (__begin_node_pointer __p = __base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
0917       __p->__next_ = this->__create_node(/* next = */ nullptr);
0918     }
0919   }
0920 }
0921 
0922 #  if _LIBCPP_STD_VER >= 14
0923 template <class _Tp, class _Alloc>
0924 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc) : __base(__base_alloc) {
0925   if (__n > 0) {
0926     for (__begin_node_pointer __p = __base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
0927       __p->__next_ = this->__create_node(/* next = */ nullptr);
0928     }
0929   }
0930 }
0931 #  endif
0932 
0933 template <class _Tp, class _Alloc>
0934 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) {
0935   insert_after(cbefore_begin(), __n, __v);
0936 }
0937 
0938 template <class _Tp, class _Alloc>
0939 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
0940 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l) {
0941   insert_after(cbefore_begin(), __f, __l);
0942 }
0943 
0944 template <class _Tp, class _Alloc>
0945 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
0946 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
0947     : __base(__a) {
0948   insert_after(cbefore_begin(), __f, __l);
0949 }
0950 
0951 template <class _Tp, class _Alloc>
0952 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
0953     : __base(__node_traits::select_on_container_copy_construction(__x.__alloc_)) {
0954   insert_after(cbefore_begin(), __x.begin(), __x.end());
0955 }
0956 
0957 template <class _Tp, class _Alloc>
0958 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a)
0959     : __base(__a) {
0960   insert_after(cbefore_begin(), __x.begin(), __x.end());
0961 }
0962 
0963 template <class _Tp, class _Alloc>
0964 forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) {
0965   if (this != std::addressof(__x)) {
0966     __base::__copy_assign_alloc(__x);
0967     assign(__x.begin(), __x.end());
0968   }
0969   return *this;
0970 }
0971 
0972 #  ifndef _LIBCPP_CXX03_LANG
0973 template <class _Tp, class _Alloc>
0974 forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a)
0975     : __base(std::move(__x), __a) {
0976   if (this->__alloc_ != __x.__alloc_) {
0977     typedef move_iterator<iterator> _Ip;
0978     insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
0979   }
0980 }
0981 
0982 template <class _Tp, class _Alloc>
0983 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il) {
0984   insert_after(cbefore_begin(), __il.begin(), __il.end());
0985 }
0986 
0987 template <class _Tp, class _Alloc>
0988 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, const allocator_type& __a) : __base(__a) {
0989   insert_after(cbefore_begin(), __il.begin(), __il.end());
0990 }
0991 
0992 template <class _Tp, class _Alloc>
0993 void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
0994     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
0995   clear();
0996   __base::__move_assign_alloc(__x);
0997   __base::__before_begin()->__next_ = __x.__before_begin()->__next_;
0998   __x.__before_begin()->__next_     = nullptr;
0999 }
1000 
1001 template <class _Tp, class _Alloc>
1002 void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) {
1003   if (this->__alloc_ == __x.__alloc_)
1004     __move_assign(__x, true_type());
1005   else {
1006     typedef move_iterator<iterator> _Ip;
1007     assign(_Ip(__x.begin()), _Ip(__x.end()));
1008   }
1009 }
1010 
1011 template <class _Tp, class _Alloc>
1012 inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) _NOEXCEPT_(
1013     __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<allocator_type>::value) {
1014   __move_assign(__x, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
1015   return *this;
1016 }
1017 
1018 template <class _Tp, class _Alloc>
1019 inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) {
1020   assign(__il.begin(), __il.end());
1021   return *this;
1022 }
1023 
1024 #  endif // _LIBCPP_CXX03_LANG
1025 
1026 template <class _Tp, class _Alloc>
1027 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
1028 void forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) {
1029   __assign_with_sentinel(__f, __l);
1030 }
1031 
1032 template <class _Tp, class _Alloc>
1033 template <class _Iter, class _Sent>
1034 _LIBCPP_HIDE_FROM_ABI void forward_list<_Tp, _Alloc>::__assign_with_sentinel(_Iter __f, _Sent __l) {
1035   iterator __i = before_begin();
1036   iterator __j = std::next(__i);
1037   iterator __e = end();
1038   for (; __j != __e && __f != __l; ++__i, (void)++__j, ++__f)
1039     *__j = *__f;
1040   if (__j == __e)
1041     __insert_after_with_sentinel(__i, std::move(__f), std::move(__l));
1042   else
1043     erase_after(__i, __e);
1044 }
1045 
1046 template <class _Tp, class _Alloc>
1047 void forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) {
1048   iterator __i = before_begin();
1049   iterator __j = std::next(__i);
1050   iterator __e = end();
1051   for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1052     *__j = __v;
1053   if (__j == __e)
1054     insert_after(__i, __n, __v);
1055   else
1056     erase_after(__i, __e);
1057 }
1058 
1059 #  ifndef _LIBCPP_CXX03_LANG
1060 
1061 template <class _Tp, class _Alloc>
1062 inline void forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) {
1063   assign(__il.begin(), __il.end());
1064 }
1065 
1066 template <class _Tp, class _Alloc>
1067 template <class... _Args>
1068 #    if _LIBCPP_STD_VER >= 17
1069 typename forward_list<_Tp, _Alloc>::reference
1070 #    else
1071 void
1072 #    endif
1073 forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) {
1074   __base::__before_begin()->__next_ =
1075       this->__create_node(/* next = */ __base::__before_begin()->__next_, std::forward<_Args>(__args)...);
1076 #    if _LIBCPP_STD_VER >= 17
1077   return __base::__before_begin()->__next_->__get_value();
1078 #    endif
1079 }
1080 
1081 template <class _Tp, class _Alloc>
1082 void forward_list<_Tp, _Alloc>::push_front(value_type&& __v) {
1083   __base::__before_begin()->__next_ =
1084       this->__create_node(/* next = */ __base::__before_begin()->__next_, std::move(__v));
1085 }
1086 
1087 #  endif // _LIBCPP_CXX03_LANG
1088 
1089 template <class _Tp, class _Alloc>
1090 void forward_list<_Tp, _Alloc>::push_front(const value_type& __v) {
1091   __base::__before_begin()->__next_ = this->__create_node(/* next = */ __base::__before_begin()->__next_, __v);
1092 }
1093 
1094 template <class _Tp, class _Alloc>
1095 void forward_list<_Tp, _Alloc>::pop_front() {
1096   _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::pop_front called on an empty list");
1097   __node_pointer __p                = __base::__before_begin()->__next_;
1098   __base::__before_begin()->__next_ = __p->__next_;
1099   this->__delete_node(__p);
1100 }
1101 
1102 #  ifndef _LIBCPP_CXX03_LANG
1103 
1104 template <class _Tp, class _Alloc>
1105 template <class... _Args>
1106 typename forward_list<_Tp, _Alloc>::iterator
1107 forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) {
1108   __begin_node_pointer const __r = __p.__get_begin();
1109   __r->__next_                   = this->__create_node(/* next = */ __r->__next_, std::forward<_Args>(__args)...);
1110   return iterator(__r->__next_);
1111 }
1112 
1113 template <class _Tp, class _Alloc>
1114 typename forward_list<_Tp, _Alloc>::iterator
1115 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) {
1116   __begin_node_pointer const __r = __p.__get_begin();
1117   __r->__next_                   = this->__create_node(/* next = */ __r->__next_, std::move(__v));
1118   return iterator(__r->__next_);
1119 }
1120 
1121 #  endif // _LIBCPP_CXX03_LANG
1122 
1123 template <class _Tp, class _Alloc>
1124 typename forward_list<_Tp, _Alloc>::iterator
1125 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) {
1126   __begin_node_pointer const __r = __p.__get_begin();
1127   __r->__next_                   = this->__create_node(/* next = */ __r->__next_, __v);
1128   return iterator(__r->__next_);
1129 }
1130 
1131 template <class _Tp, class _Alloc>
1132 typename forward_list<_Tp, _Alloc>::iterator
1133 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, const value_type& __v) {
1134   __begin_node_pointer __r = __p.__get_begin();
1135   if (__n > 0) {
1136     __node_pointer __first = this->__create_node(/* next = */ nullptr, __v);
1137     __node_pointer __last  = __first;
1138 #  if _LIBCPP_HAS_EXCEPTIONS
1139     try {
1140 #  endif // _LIBCPP_HAS_EXCEPTIONS
1141       for (--__n; __n != 0; --__n, __last = __last->__next_) {
1142         __last->__next_ = this->__create_node(/* next = */ nullptr, __v);
1143       }
1144 #  if _LIBCPP_HAS_EXCEPTIONS
1145     } catch (...) {
1146       while (__first != nullptr) {
1147         __node_pointer __next = __first->__next_;
1148         this->__delete_node(__first);
1149         __first = __next;
1150       }
1151       throw;
1152     }
1153 #  endif // _LIBCPP_HAS_EXCEPTIONS
1154     __last->__next_ = __r->__next_;
1155     __r->__next_    = __first;
1156     __r             = static_cast<__begin_node_pointer>(__last);
1157   }
1158   return iterator(__r);
1159 }
1160 
1161 template <class _Tp, class _Alloc>
1162 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
1163 typename forward_list<_Tp, _Alloc>::iterator
1164 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l) {
1165   return __insert_after_with_sentinel(__p, std::move(__f), std::move(__l));
1166 }
1167 
1168 template <class _Tp, class _Alloc>
1169 template <class _InputIterator, class _Sentinel>
1170 _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Alloc>::iterator
1171 forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) {
1172   __begin_node_pointer __r = __p.__get_begin();
1173 
1174   if (__f != __l) {
1175     __node_pointer __first = this->__create_node(/* next = */ nullptr, *__f);
1176     __node_pointer __last  = __first;
1177 
1178 #  if _LIBCPP_HAS_EXCEPTIONS
1179     try {
1180 #  endif // _LIBCPP_HAS_EXCEPTIONS
1181       for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) {
1182         __last->__next_ = this->__create_node(/* next = */ nullptr, *__f);
1183       }
1184 #  if _LIBCPP_HAS_EXCEPTIONS
1185     } catch (...) {
1186       while (__first != nullptr) {
1187         __node_pointer __next = __first->__next_;
1188         this->__delete_node(__first);
1189         __first = __next;
1190       }
1191       throw;
1192     }
1193 #  endif // _LIBCPP_HAS_EXCEPTIONS
1194 
1195     __last->__next_ = __r->__next_;
1196     __r->__next_    = __first;
1197     __r             = static_cast<__begin_node_pointer>(__last);
1198   }
1199 
1200   return iterator(__r);
1201 }
1202 
1203 template <class _Tp, class _Alloc>
1204 typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) {
1205   __begin_node_pointer __p = __f.__get_begin();
1206   __node_pointer __n       = __p->__next_;
1207   __p->__next_             = __n->__next_;
1208   this->__delete_node(__n);
1209   return iterator(__p->__next_);
1210 }
1211 
1212 template <class _Tp, class _Alloc>
1213 typename forward_list<_Tp, _Alloc>::iterator
1214 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) {
1215   __node_pointer __e = __l.__get_unsafe_node_pointer();
1216   if (__f != __l) {
1217     __begin_node_pointer __bp = __f.__get_begin();
1218 
1219     __node_pointer __n = __bp->__next_;
1220     if (__n != __e) {
1221       __bp->__next_ = __e;
1222       do {
1223         __node_pointer __tmp = __n->__next_;
1224         this->__delete_node(__n);
1225         __n = __tmp;
1226       } while (__n != __e);
1227     }
1228   }
1229   return iterator(__e);
1230 }
1231 
1232 template <class _Tp, class _Alloc>
1233 void forward_list<_Tp, _Alloc>::resize(size_type __n) {
1234   size_type __sz = 0;
1235   iterator __p   = before_begin();
1236   iterator __i   = begin();
1237   iterator __e   = end();
1238   for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1239     ;
1240   if (__i != __e)
1241     erase_after(__p, __e);
1242   else {
1243     __n -= __sz;
1244     if (__n > 0) {
1245       for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) {
1246         __ptr->__next_ = this->__create_node(/* next = */ nullptr);
1247       }
1248     }
1249   }
1250 }
1251 
1252 template <class _Tp, class _Alloc>
1253 void forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) {
1254   size_type __sz = 0;
1255   iterator __p   = before_begin();
1256   iterator __i   = begin();
1257   iterator __e   = end();
1258   for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1259     ;
1260   if (__i != __e)
1261     erase_after(__p, __e);
1262   else {
1263     __n -= __sz;
1264     if (__n > 0) {
1265       for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) {
1266         __ptr->__next_ = this->__create_node(/* next = */ nullptr, __v);
1267       }
1268     }
1269   }
1270 }
1271 
1272 template <class _Tp, class _Alloc>
1273 void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list& __x) {
1274   if (!__x.empty()) {
1275     if (__p.__get_begin()->__next_ != nullptr) {
1276       const_iterator __lm1 = __x.before_begin();
1277       while (__lm1.__get_begin()->__next_ != nullptr)
1278         ++__lm1;
1279       __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1280     }
1281     __p.__get_begin()->__next_    = __x.__before_begin()->__next_;
1282     __x.__before_begin()->__next_ = nullptr;
1283   }
1284 }
1285 
1286 template <class _Tp, class _Alloc>
1287 void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list& /*__other*/, const_iterator __i) {
1288   const_iterator __lm1 = std::next(__i);
1289   if (__p != __i && __p != __lm1) {
1290     __i.__get_begin()->__next_   = __lm1.__get_begin()->__next_;
1291     __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1292     __p.__get_begin()->__next_   = __lm1.__get_unsafe_node_pointer();
1293   }
1294 }
1295 
1296 template <class _Tp, class _Alloc>
1297 void forward_list<_Tp, _Alloc>::splice_after(
1298     const_iterator __p, forward_list& /*__other*/, const_iterator __f, const_iterator __l) {
1299   if (__f != __l && __p != __f) {
1300     const_iterator __lm1 = __f;
1301     while (__lm1.__get_begin()->__next_ != __l.__get_begin())
1302       ++__lm1;
1303     if (__f != __lm1) {
1304       __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1305       __p.__get_begin()->__next_   = __f.__get_begin()->__next_;
1306       __f.__get_begin()->__next_   = __l.__get_unsafe_node_pointer();
1307     }
1308   }
1309 }
1310 
1311 template <class _Tp, class _Alloc>
1312 inline _LIBCPP_HIDE_FROM_ABI void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list&& __x) {
1313   splice_after(__p, __x);
1314 }
1315 
1316 template <class _Tp, class _Alloc>
1317 inline _LIBCPP_HIDE_FROM_ABI void
1318 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, forward_list&& __x, const_iterator __i) {
1319   splice_after(__p, __x, __i);
1320 }
1321 
1322 template <class _Tp, class _Alloc>
1323 inline _LIBCPP_HIDE_FROM_ABI void forward_list<_Tp, _Alloc>::splice_after(
1324     const_iterator __p, forward_list&& __x, const_iterator __f, const_iterator __l) {
1325   splice_after(__p, __x, __f, __l);
1326 }
1327 
1328 template <class _Tp, class _Alloc>
1329 typename forward_list<_Tp, _Alloc>::__remove_return_type forward_list<_Tp, _Alloc>::remove(const value_type& __v) {
1330   forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
1331   typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1332   const iterator __e                                            = end();
1333   for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) {
1334     if (__i.__get_begin()->__next_->__get_value() == __v) {
1335       ++__count_removed;
1336       iterator __j = std::next(__i, 2);
1337       for (; __j != __e && *__j == __v; ++__j)
1338         ++__count_removed;
1339       __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1340       if (__j == __e)
1341         break;
1342       __i = __j;
1343     } else
1344       ++__i;
1345   }
1346 
1347   return (__remove_return_type)__count_removed;
1348 }
1349 
1350 template <class _Tp, class _Alloc>
1351 template <class _Predicate>
1352 typename forward_list<_Tp, _Alloc>::__remove_return_type forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) {
1353   forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
1354   typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1355   const iterator __e                                            = end();
1356   for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) {
1357     if (__pred(__i.__get_begin()->__next_->__get_value())) {
1358       ++__count_removed;
1359       iterator __j = std::next(__i, 2);
1360       for (; __j != __e && __pred(*__j); ++__j)
1361         ++__count_removed;
1362       __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1363       if (__j == __e)
1364         break;
1365       __i = __j;
1366     } else
1367       ++__i;
1368   }
1369 
1370   return (__remove_return_type)__count_removed;
1371 }
1372 
1373 template <class _Tp, class _Alloc>
1374 template <class _BinaryPredicate>
1375 typename forward_list<_Tp, _Alloc>::__remove_return_type
1376 forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) {
1377   forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
1378   typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1379   for (iterator __i = begin(), __e = end(); __i != __e;) {
1380     iterator __j = std::next(__i);
1381     for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1382       ++__count_removed;
1383     if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
1384       __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1385     __i = __j;
1386   }
1387 
1388   return (__remove_return_type)__count_removed;
1389 }
1390 
1391 template <class _Tp, class _Alloc>
1392 template <class _Compare>
1393 void forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) {
1394   if (this != std::addressof(__x)) {
1395     __base::__before_begin()->__next_ =
1396         __merge(__base::__before_begin()->__next_, __x.__before_begin()->__next_, __comp);
1397     __x.__before_begin()->__next_ = nullptr;
1398   }
1399 }
1400 
1401 template <class _Tp, class _Alloc>
1402 template <class _Compare>
1403 typename forward_list<_Tp, _Alloc>::__node_pointer
1404 forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp) {
1405   if (__f1 == nullptr)
1406     return __f2;
1407   if (__f2 == nullptr)
1408     return __f1;
1409   __node_pointer __r;
1410   if (__comp(__f2->__get_value(), __f1->__get_value())) {
1411     __node_pointer __t = __f2;
1412     while (__t->__next_ != nullptr && __comp(__t->__next_->__get_value(), __f1->__get_value()))
1413       __t = __t->__next_;
1414     __r          = __f2;
1415     __f2         = __t->__next_;
1416     __t->__next_ = __f1;
1417   } else
1418     __r = __f1;
1419   __node_pointer __p = __f1;
1420   __f1               = __f1->__next_;
1421   while (__f1 != nullptr && __f2 != nullptr) {
1422     if (__comp(__f2->__get_value(), __f1->__get_value())) {
1423       __node_pointer __t = __f2;
1424       while (__t->__next_ != nullptr && __comp(__t->__next_->__get_value(), __f1->__get_value()))
1425         __t = __t->__next_;
1426       __p->__next_ = __f2;
1427       __f2         = __t->__next_;
1428       __t->__next_ = __f1;
1429     }
1430     __p  = __f1;
1431     __f1 = __f1->__next_;
1432   }
1433   if (__f2 != nullptr)
1434     __p->__next_ = __f2;
1435   return __r;
1436 }
1437 
1438 template <class _Tp, class _Alloc>
1439 template <class _Compare>
1440 inline void forward_list<_Tp, _Alloc>::sort(_Compare __comp) {
1441   __base::__before_begin()->__next_ = __sort(__base::__before_begin()->__next_, std::distance(begin(), end()), __comp);
1442 }
1443 
1444 template <class _Tp, class _Alloc>
1445 template <class _Compare>
1446 typename forward_list<_Tp, _Alloc>::__node_pointer
1447 forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, _Compare& __comp) {
1448   switch (__sz) {
1449   case 0:
1450   case 1:
1451     return __f1;
1452   case 2:
1453     if (__comp(__f1->__next_->__get_value(), __f1->__get_value())) {
1454       __node_pointer __t = __f1->__next_;
1455       __t->__next_       = __f1;
1456       __f1->__next_      = nullptr;
1457       __f1               = __t;
1458     }
1459     return __f1;
1460   }
1461   difference_type __sz1 = __sz / 2;
1462   difference_type __sz2 = __sz - __sz1;
1463   __node_pointer __t    = std::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
1464   __node_pointer __f2   = __t->__next_;
1465   __t->__next_          = nullptr;
1466   return __merge(__sort(__f1, __sz1, __comp), __sort(__f2, __sz2, __comp), __comp);
1467 }
1468 
1469 template <class _Tp, class _Alloc>
1470 void forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT {
1471   __node_pointer __p = __base::__before_begin()->__next_;
1472   if (__p != nullptr) {
1473     __node_pointer __f = __p->__next_;
1474     __p->__next_       = nullptr;
1475     while (__f != nullptr) {
1476       __node_pointer __t = __f->__next_;
1477       __f->__next_       = __p;
1478       __p                = __f;
1479       __f                = __t;
1480     }
1481     __base::__before_begin()->__next_ = __p;
1482   }
1483 }
1484 
1485 template <class _Tp, class _Alloc>
1486 _LIBCPP_HIDE_FROM_ABI bool operator==(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1487   typedef forward_list<_Tp, _Alloc> _Cp;
1488   typedef typename _Cp::const_iterator _Ip;
1489   _Ip __ix = __x.begin();
1490   _Ip __ex = __x.end();
1491   _Ip __iy = __y.begin();
1492   _Ip __ey = __y.end();
1493   for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1494     if (!(*__ix == *__iy))
1495       return false;
1496   return (__ix == __ex) == (__iy == __ey);
1497 }
1498 
1499 #  if _LIBCPP_STD_VER <= 17
1500 
1501 template <class _Tp, class _Alloc>
1502 inline _LIBCPP_HIDE_FROM_ABI bool
1503 operator!=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1504   return !(__x == __y);
1505 }
1506 
1507 template <class _Tp, class _Alloc>
1508 inline _LIBCPP_HIDE_FROM_ABI bool
1509 operator<(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1510   return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1511 }
1512 
1513 template <class _Tp, class _Alloc>
1514 inline _LIBCPP_HIDE_FROM_ABI bool
1515 operator>(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1516   return __y < __x;
1517 }
1518 
1519 template <class _Tp, class _Alloc>
1520 inline _LIBCPP_HIDE_FROM_ABI bool
1521 operator>=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1522   return !(__x < __y);
1523 }
1524 
1525 template <class _Tp, class _Alloc>
1526 inline _LIBCPP_HIDE_FROM_ABI bool
1527 operator<=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
1528   return !(__y < __x);
1529 }
1530 
1531 #  else // #if _LIBCPP_STD_VER <= 17
1532 
1533 template <class _Tp, class _Allocator>
1534 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
1535 operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _Allocator>& __y) {
1536   return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
1537 }
1538 
1539 #  endif // #if _LIBCPP_STD_VER <= 17
1540 
1541 template <class _Tp, class _Alloc>
1542 inline _LIBCPP_HIDE_FROM_ABI void swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1543     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
1544   __x.swap(__y);
1545 }
1546 
1547 #  if _LIBCPP_STD_VER >= 20
1548 template <class _Tp, class _Allocator, class _Predicate>
1549 inline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
1550 erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
1551   return __c.remove_if(__pred);
1552 }
1553 
1554 template <class _Tp, class _Allocator, class _Up>
1555 inline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
1556 erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) {
1557   return std::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
1558 }
1559 #  endif
1560 
1561 template <class _Tp, class _Allocator>
1562 struct __container_traits<forward_list<_Tp, _Allocator> > {
1563   // http://eel.is/c++draft/container.reqmts
1564   // Unless otherwise specified (see [associative.reqmts.except], [unord.req.except], [deque.modifiers],
1565   // [inplace.vector.modifiers], and [vector.modifiers]) all container types defined in this Clause meet the following
1566   // additional requirements:
1567   // - If an exception is thrown by an insert() or emplace() function while inserting a single element, that
1568   // function has no effects.
1569   static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;
1570 };
1571 
1572 _LIBCPP_END_NAMESPACE_STD
1573 
1574 #  if _LIBCPP_STD_VER >= 17
1575 _LIBCPP_BEGIN_NAMESPACE_STD
1576 namespace pmr {
1577 template <class _ValueT>
1578 using forward_list _LIBCPP_AVAILABILITY_PMR = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>;
1579 } // namespace pmr
1580 _LIBCPP_END_NAMESPACE_STD
1581 #  endif
1582 
1583 _LIBCPP_POP_MACROS
1584 
1585 #  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1586 #    include <algorithm>
1587 #    include <atomic>
1588 #    include <concepts>
1589 #    include <cstdint>
1590 #    include <cstdlib>
1591 #    include <cstring>
1592 #    include <functional>
1593 #    include <iosfwd>
1594 #    include <iterator>
1595 #    include <stdexcept>
1596 #    include <type_traits>
1597 #    include <typeinfo>
1598 #  endif
1599 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1600 
1601 #endif // _LIBCPP_FORWARD_LIST