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