blob: f9a71f0330ae6484db86aa8e0ab639663d2c1d5b [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------- forward_list ---------------------------------===//
3//
Howard Hinnant5b08a8a2010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:16 +00005//
Howard Hinnant412dbeb2010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FORWARD_LIST
12#define _LIBCPP_FORWARD_LIST
13
14/*
15 forward_list synopsis
16
17namespace std
18{
19
20template <class T, class Allocator = allocator<T>>
21class forward_list
22{
23public:
24 typedef T value_type;
25 typedef Allocator allocator_type;
26
27 typedef value_type& reference;
28 typedef const value_type& const_reference;
29 typedef typename allocator_traits<allocator_type>::pointer pointer;
30 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
31 typedef typename allocator_traits<allocator_type>::size_type size_type;
32 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
33
34 typedef <details> iterator;
35 typedef <details> const_iterator;
36
Howard Hinnant91a47502011-06-03 16:20:53 +000037 forward_list()
38 noexcept(is_nothrow_default_constructible<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000039 explicit forward_list(const allocator_type& a);
40 explicit forward_list(size_type n);
Marshall Clowf1b6d1b2013-09-09 18:19:45 +000041 explicit forward_list(size_type n, const allocator_type& a); // C++14
Howard Hinnant3e519522010-05-11 19:42:16 +000042 forward_list(size_type n, const value_type& v);
43 forward_list(size_type n, const value_type& v, const allocator_type& a);
44 template <class InputIterator>
45 forward_list(InputIterator first, InputIterator last);
46 template <class InputIterator>
47 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
48 forward_list(const forward_list& x);
49 forward_list(const forward_list& x, const allocator_type& a);
Howard Hinnant91a47502011-06-03 16:20:53 +000050 forward_list(forward_list&& x)
51 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000052 forward_list(forward_list&& x, const allocator_type& a);
53 forward_list(initializer_list<value_type> il);
54 forward_list(initializer_list<value_type> il, const allocator_type& a);
55
56 ~forward_list();
57
58 forward_list& operator=(const forward_list& x);
Howard Hinnant91a47502011-06-03 16:20:53 +000059 forward_list& operator=(forward_list&& x)
60 noexcept(
61 allocator_type::propagate_on_container_move_assignment::value &&
62 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000063 forward_list& operator=(initializer_list<value_type> il);
64
65 template <class InputIterator>
66 void assign(InputIterator first, InputIterator last);
67 void assign(size_type n, const value_type& v);
68 void assign(initializer_list<value_type> il);
69
Howard Hinnantf9dc2832011-06-02 16:44:28 +000070 allocator_type get_allocator() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000071
Howard Hinnantf9dc2832011-06-02 16:44:28 +000072 iterator begin() noexcept;
73 const_iterator begin() const noexcept;
74 iterator end() noexcept;
75 const_iterator end() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000076
Howard Hinnantf9dc2832011-06-02 16:44:28 +000077 const_iterator cbegin() const noexcept;
78 const_iterator cend() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000079
Howard Hinnantf9dc2832011-06-02 16:44:28 +000080 iterator before_begin() noexcept;
81 const_iterator before_begin() const noexcept;
82 const_iterator cbefore_begin() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000083
Howard Hinnantf9dc2832011-06-02 16:44:28 +000084 bool empty() const noexcept;
85 size_type max_size() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000086
87 reference front();
88 const_reference front() const;
89
Marshall Clow63b560b2017-01-24 23:09:12 +000090 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
Howard Hinnant3e519522010-05-11 19:42:16 +000091 void push_front(const value_type& v);
92 void push_front(value_type&& v);
93
94 void pop_front();
95
96 template <class... Args>
97 iterator emplace_after(const_iterator p, Args&&... args);
98 iterator insert_after(const_iterator p, const value_type& v);
99 iterator insert_after(const_iterator p, value_type&& v);
100 iterator insert_after(const_iterator p, size_type n, const value_type& v);
101 template <class InputIterator>
102 iterator insert_after(const_iterator p,
103 InputIterator first, InputIterator last);
104 iterator insert_after(const_iterator p, initializer_list<value_type> il);
105
Howard Hinnant3db88032010-08-21 20:58:44 +0000106 iterator erase_after(const_iterator p);
107 iterator erase_after(const_iterator first, const_iterator last);
Howard Hinnant3e519522010-05-11 19:42:16 +0000108
Howard Hinnant91a47502011-06-03 16:20:53 +0000109 void swap(forward_list& x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000110 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
Howard Hinnant3e519522010-05-11 19:42:16 +0000111
112 void resize(size_type n);
113 void resize(size_type n, const value_type& v);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000114 void clear() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000115
Howard Hinnanteb92df72011-01-27 21:00:35 +0000116 void splice_after(const_iterator p, forward_list& x);
Howard Hinnant3e519522010-05-11 19:42:16 +0000117 void splice_after(const_iterator p, forward_list&& x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000118 void splice_after(const_iterator p, forward_list& x, const_iterator i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000119 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000120 void splice_after(const_iterator p, forward_list& x,
121 const_iterator first, const_iterator last);
Howard Hinnant3e519522010-05-11 19:42:16 +0000122 void splice_after(const_iterator p, forward_list&& x,
123 const_iterator first, const_iterator last);
124 void remove(const value_type& v);
125 template <class Predicate> void remove_if(Predicate pred);
126 void unique();
127 template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000128 void merge(forward_list& x);
Howard Hinnant3e519522010-05-11 19:42:16 +0000129 void merge(forward_list&& x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000130 template <class Compare> void merge(forward_list& x, Compare comp);
Howard Hinnant3e519522010-05-11 19:42:16 +0000131 template <class Compare> void merge(forward_list&& x, Compare comp);
132 void sort();
133 template <class Compare> void sort(Compare comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000134 void reverse() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000135};
136
Marshall Clowe0767002018-05-19 16:02:05 +0000137
138template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
139 forward_list(InputIterator, InputIterator, Allocator = Allocator())
140 -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
141
Howard Hinnant3e519522010-05-11 19:42:16 +0000142template <class T, class Allocator>
143 bool operator==(const forward_list<T, Allocator>& x,
144 const forward_list<T, Allocator>& y);
145
146template <class T, class Allocator>
147 bool operator< (const forward_list<T, Allocator>& x,
148 const forward_list<T, Allocator>& y);
149
150template <class T, class Allocator>
151 bool operator!=(const forward_list<T, Allocator>& x,
152 const forward_list<T, Allocator>& y);
153
154template <class T, class Allocator>
155 bool operator> (const forward_list<T, Allocator>& x,
156 const forward_list<T, Allocator>& y);
157
158template <class T, class Allocator>
159 bool operator>=(const forward_list<T, Allocator>& x,
160 const forward_list<T, Allocator>& y);
161
162template <class T, class Allocator>
163 bool operator<=(const forward_list<T, Allocator>& x,
164 const forward_list<T, Allocator>& y);
165
166template <class T, class Allocator>
Howard Hinnant91a47502011-06-03 16:20:53 +0000167 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
Howard Hinnant45900102011-06-03 17:30:28 +0000168 noexcept(noexcept(x.swap(y)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000169
170} // std
171
172*/
173
174#include <__config>
Howard Hinnant3e519522010-05-11 19:42:16 +0000175#include <initializer_list>
176#include <memory>
177#include <limits>
178#include <iterator>
179#include <algorithm>
Marshall Clowf56972e2018-09-12 19:41:40 +0000180#include <version>
Howard Hinnant3e519522010-05-11 19:42:16 +0000181
Howard Hinnant073458b2011-10-17 20:05:10 +0000182#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +0000183#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000184#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000185
Eric Fiseliera016efb2017-05-31 22:07:49 +0000186_LIBCPP_PUSH_MACROS
187#include <__undef_macros>
188
189
Howard Hinnant3e519522010-05-11 19:42:16 +0000190_LIBCPP_BEGIN_NAMESPACE_STD
191
Howard Hinnantce534202011-06-14 19:58:17 +0000192template <class _Tp, class _VoidPtr> struct __forward_list_node;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000193template <class _NodePtr> struct __forward_begin_node;
194
195
196template <class>
197struct __forward_list_node_value_type;
198
199template <class _Tp, class _VoidPtr>
200struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
201 typedef _Tp type;
202};
203
204template <class _NodePtr>
205struct __forward_node_traits {
206
207 typedef typename remove_cv<
208 typename pointer_traits<_NodePtr>::element_type>::type __node;
209 typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
210 typedef _NodePtr __node_pointer;
211 typedef __forward_begin_node<_NodePtr> __begin_node;
212 typedef typename __rebind_pointer<_NodePtr, __begin_node>::type
213 __begin_node_pointer;
214 typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer;
215
216#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
217 typedef __begin_node_pointer __iter_node_pointer;
218#else
219 typedef typename conditional<
220 is_pointer<__void_pointer>::value,
221 __begin_node_pointer,
222 __node_pointer
223 >::type __iter_node_pointer;
224#endif
225
226 typedef typename conditional<
227 is_same<__iter_node_pointer, __node_pointer>::value,
228 __begin_node_pointer,
229 __node_pointer
230 >::type __non_iter_node_pointer;
231
232 _LIBCPP_INLINE_VISIBILITY
233 static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) {
234 return __p;
235 }
236 _LIBCPP_INLINE_VISIBILITY
237 static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
238 return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
239 }
240};
Howard Hinnant3e519522010-05-11 19:42:16 +0000241
242template <class _NodePtr>
243struct __forward_begin_node
244{
Howard Hinnant3e519522010-05-11 19:42:16 +0000245 typedef _NodePtr pointer;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000246 typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000247
248 pointer __next_;
249
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000250 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
251
252 _LIBCPP_INLINE_VISIBILITY
253 __begin_node_pointer __next_as_begin() const {
254 return static_cast<__begin_node_pointer>(__next_);
255 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000256};
257
258template <class _Tp, class _VoidPtr>
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000259struct _LIBCPP_HIDDEN __begin_node_of
260{
Eric Fiselier934b0922015-12-30 21:52:00 +0000261 typedef __forward_begin_node<
262 typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
263 > type;
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000264};
265
266template <class _Tp, class _VoidPtr>
267struct __forward_list_node
268 : public __begin_node_of<_Tp, _VoidPtr>::type
Howard Hinnant3e519522010-05-11 19:42:16 +0000269{
270 typedef _Tp value_type;
271
272 value_type __value_;
273};
274
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000275
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000276template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list;
277template<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000278
279template <class _NodePtr>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000280class _LIBCPP_TEMPLATE_VIS __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000281{
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000282 typedef __forward_node_traits<_NodePtr> __traits;
283 typedef typename __traits::__node_pointer __node_pointer;
284 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
285 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
286 typedef typename __traits::__void_pointer __void_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000287
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000288 __iter_node_pointer __ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +0000289
Howard Hinnant0af133f2010-09-21 22:55:27 +0000290 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000291 __begin_node_pointer __get_begin() const {
292 return static_cast<__begin_node_pointer>(
293 static_cast<__void_pointer>(__ptr_));
294 }
295 _LIBCPP_INLINE_VISIBILITY
296 __node_pointer __get_unsafe_node_pointer() const {
297 return static_cast<__node_pointer>(
298 static_cast<__void_pointer>(__ptr_));
299 }
300
301 _LIBCPP_INLINE_VISIBILITY
302 explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
303
304 _LIBCPP_INLINE_VISIBILITY
305 explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
306 : __ptr_(__traits::__as_iter_node(__p)) {}
307
308 _LIBCPP_INLINE_VISIBILITY
309 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
310 : __ptr_(__traits::__as_iter_node(__p)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000311
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000312 template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list;
313 template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000314
315public:
316 typedef forward_iterator_tag iterator_category;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000317 typedef typename __traits::__node_value_type value_type;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000318 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000319 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000320 difference_type;
Eric Fiselier934b0922015-12-30 21:52:00 +0000321 typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000322
Howard Hinnant0af133f2010-09-21 22:55:27 +0000323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000324 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000325
Howard Hinnant0af133f2010-09-21 22:55:27 +0000326 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000327 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000328 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000329 pointer operator->() const {
330 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
331 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000332
Howard Hinnant0af133f2010-09-21 22:55:27 +0000333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000334 __forward_list_iterator& operator++()
335 {
Eric Fiselier4de5f982016-01-27 00:49:20 +0000336 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000337 return *this;
338 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000340 __forward_list_iterator operator++(int)
341 {
342 __forward_list_iterator __t(*this);
343 ++(*this);
344 return __t;
345 }
346
Howard Hinnant0af133f2010-09-21 22:55:27 +0000347 friend _LIBCPP_INLINE_VISIBILITY
348 bool operator==(const __forward_list_iterator& __x,
349 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000350 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000351 friend _LIBCPP_INLINE_VISIBILITY
352 bool operator!=(const __forward_list_iterator& __x,
353 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000354 {return !(__x == __y);}
355};
356
357template <class _NodeConstPtr>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000358class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000359{
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000360 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
361 typedef _NodeConstPtr _NodePtr;
Howard Hinnant3e519522010-05-11 19:42:16 +0000362
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000363 typedef __forward_node_traits<_NodePtr> __traits;
364 typedef typename __traits::__node __node;
365 typedef typename __traits::__node_pointer __node_pointer;
366 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
367 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
368 typedef typename __traits::__void_pointer __void_pointer;
369
370 __iter_node_pointer __ptr_;
371
372 __begin_node_pointer __get_begin() const {
373 return static_cast<__begin_node_pointer>(
374 static_cast<__void_pointer>(__ptr_));
375 }
376 __node_pointer __get_unsafe_node_pointer() const {
377 return static_cast<__node_pointer>(
378 static_cast<__void_pointer>(__ptr_));
379 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000380
Howard Hinnant0af133f2010-09-21 22:55:27 +0000381 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000382 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
383 : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000384
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000385 _LIBCPP_INLINE_VISIBILITY
386 explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
387 : __ptr_(__traits::__as_iter_node(__p)) {}
388
389 _LIBCPP_INLINE_VISIBILITY
390 explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
391 : __ptr_(__traits::__as_iter_node(__p)) {}
392
Howard Hinnant3e519522010-05-11 19:42:16 +0000393
394 template<class, class> friend class forward_list;
395
396public:
397 typedef forward_iterator_tag iterator_category;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000398 typedef typename __traits::__node_value_type value_type;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000399 typedef const value_type& reference;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000400 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000401 difference_type;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000402 typedef typename __rebind_pointer<__node_pointer, const value_type>::type
403 pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000404
Howard Hinnant0af133f2010-09-21 22:55:27 +0000405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000406 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000408 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000409 : __ptr_(__p.__ptr_) {}
410
Howard Hinnant0af133f2010-09-21 22:55:27 +0000411 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000412 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000413 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000414 pointer operator->() const {return pointer_traits<pointer>::pointer_to(
415 __get_unsafe_node_pointer()->__value_);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000416
Howard Hinnant0af133f2010-09-21 22:55:27 +0000417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000418 __forward_list_const_iterator& operator++()
419 {
Eric Fiselier4de5f982016-01-27 00:49:20 +0000420 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000421 return *this;
422 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000424 __forward_list_const_iterator operator++(int)
425 {
426 __forward_list_const_iterator __t(*this);
427 ++(*this);
428 return __t;
429 }
430
Howard Hinnant0af133f2010-09-21 22:55:27 +0000431 friend _LIBCPP_INLINE_VISIBILITY
432 bool operator==(const __forward_list_const_iterator& __x,
433 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000434 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000435 friend _LIBCPP_INLINE_VISIBILITY
436 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000437 const __forward_list_const_iterator& __y)
438 {return !(__x == __y);}
439};
440
441template <class _Tp, class _Alloc>
442class __forward_list_base
443{
444protected:
445 typedef _Tp value_type;
446 typedef _Alloc allocator_type;
447
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000448 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
449 typedef __forward_list_node<value_type, void_pointer> __node;
450 typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
Marshall Clow1f508012015-04-07 05:21:38 +0000451 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000452 typedef allocator_traits<__node_allocator> __node_traits;
453 typedef typename __node_traits::pointer __node_pointer;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000454
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000455 typedef typename __rebind_alloc_helper<
456 allocator_traits<allocator_type>, __begin_node
457 >::type __begin_node_allocator;
458 typedef typename allocator_traits<__begin_node_allocator>::pointer
459 __begin_node_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000460
Eric Fiselier8cef7fd2018-06-05 22:32:52 +0000461 static_assert((!is_same<allocator_type, __node_allocator>::value),
462 "internal allocator type must differ from user-specified "
463 "type; otherwise overload resolution breaks");
464
Howard Hinnant3e519522010-05-11 19:42:16 +0000465 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
466
Howard Hinnant0af133f2010-09-21 22:55:27 +0000467 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000468 __begin_node_pointer __before_begin() _NOEXCEPT
469 {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000470 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000471 __begin_node_pointer __before_begin() const _NOEXCEPT
472 {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));}
Howard Hinnant3e519522010-05-11 19:42:16 +0000473
Howard Hinnant0af133f2010-09-21 22:55:27 +0000474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000475 __node_allocator& __alloc() _NOEXCEPT
476 {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000478 const __node_allocator& __alloc() const _NOEXCEPT
479 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000480
481 typedef __forward_list_iterator<__node_pointer> iterator;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000482 typedef __forward_list_const_iterator<__node_pointer> const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000483
Howard Hinnant0af133f2010-09-21 22:55:27 +0000484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000485 __forward_list_base()
Howard Hinnant91a47502011-06-03 16:20:53 +0000486 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000487 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000488 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier8cef7fd2018-06-05 22:32:52 +0000489 explicit __forward_list_base(const allocator_type& __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000490 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
Eric Fiselier8cef7fd2018-06-05 22:32:52 +0000491 _LIBCPP_INLINE_VISIBILITY
492 explicit __forward_list_base(const __node_allocator& __a)
493 : __before_begin_(__begin_node(), __a) {}
Eric Fiselier99f2c002017-04-16 04:02:01 +0000494#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant91a47502011-06-03 16:20:53 +0000495public:
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000496 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000497 __forward_list_base(__forward_list_base&& __x)
498 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000499 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000500 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000501#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000502
503private:
504 __forward_list_base(const __forward_list_base&);
505 __forward_list_base& operator=(const __forward_list_base&);
Howard Hinnant3e519522010-05-11 19:42:16 +0000506
Howard Hinnant91a47502011-06-03 16:20:53 +0000507public:
Howard Hinnant3e519522010-05-11 19:42:16 +0000508 ~__forward_list_base();
509
Howard Hinnant91a47502011-06-03 16:20:53 +0000510protected:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000512 void __copy_assign_alloc(const __forward_list_base& __x)
513 {__copy_assign_alloc(__x, integral_constant<bool,
514 __node_traits::propagate_on_container_copy_assignment::value>());}
515
Howard Hinnant0af133f2010-09-21 22:55:27 +0000516 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000517 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000518 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
519 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000520 {__move_assign_alloc(__x, integral_constant<bool,
521 __node_traits::propagate_on_container_move_assignment::value>());}
522
Howard Hinnant91a47502011-06-03 16:20:53 +0000523public:
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000525 void swap(__forward_list_base& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000526#if _LIBCPP_STD_VER >= 14
527 _NOEXCEPT;
528#else
529 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
530 __is_nothrow_swappable<__node_allocator>::value);
531#endif
Howard Hinnant91a47502011-06-03 16:20:53 +0000532protected:
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000533 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000534
535private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000537 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000539 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
540 {
541 if (__alloc() != __x.__alloc())
542 clear();
543 __alloc() = __x.__alloc();
544 }
545
Howard Hinnant0af133f2010-09-21 22:55:27 +0000546 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfd838222016-12-23 23:37:52 +0000547 void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT
Howard Hinnant91a47502011-06-03 16:20:53 +0000548 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000550 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000551 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000552 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000553};
554
Eric Fiselier99f2c002017-04-16 04:02:01 +0000555#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000556
557template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000558inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000559__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000560 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000561 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnant3e519522010-05-11 19:42:16 +0000562{
563 __x.__before_begin()->__next_ = nullptr;
564}
565
566template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000567inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000568__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
569 const allocator_type& __a)
570 : __before_begin_(__begin_node(), __node_allocator(__a))
571{
572 if (__alloc() == __x.__alloc())
573 {
574 __before_begin()->__next_ = __x.__before_begin()->__next_;
575 __x.__before_begin()->__next_ = nullptr;
576 }
577}
578
Eric Fiselier99f2c002017-04-16 04:02:01 +0000579#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000580
581template <class _Tp, class _Alloc>
582__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
583{
584 clear();
585}
586
587template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000588inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000589void
590__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000591#if _LIBCPP_STD_VER >= 14
592 _NOEXCEPT
593#else
594 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
595 __is_nothrow_swappable<__node_allocator>::value)
596#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000597{
Marshall Clowe3fbe142015-07-13 20:04:56 +0000598 __swap_allocator(__alloc(), __x.__alloc(),
599 integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
Howard Hinnantce48a112011-06-30 21:18:19 +0000600 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000601 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
602}
603
604template <class _Tp, class _Alloc>
605void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000606__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000607{
608 __node_allocator& __a = __alloc();
609 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
610 {
611 __node_pointer __next = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000612 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000613 __node_traits::deallocate(__a, __p, 1);
614 __p = __next;
615 }
616 __before_begin()->__next_ = nullptr;
617}
618
Marshall Clowb5d34aa2015-02-18 17:24:08 +0000619template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000620class _LIBCPP_TEMPLATE_VIS forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000621 : private __forward_list_base<_Tp, _Alloc>
622{
623 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnant91a47502011-06-03 16:20:53 +0000624 typedef typename base::__node_allocator __node_allocator;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000625 typedef typename base::__node __node;
626 typedef typename base::__node_traits __node_traits;
627 typedef typename base::__node_pointer __node_pointer;
628 typedef typename base::__begin_node_pointer __begin_node_pointer;
Howard Hinnant91a47502011-06-03 16:20:53 +0000629
Howard Hinnant3e519522010-05-11 19:42:16 +0000630public:
631 typedef _Tp value_type;
632 typedef _Alloc allocator_type;
633
Marshall Clow94f89ae2015-11-26 01:24:04 +0000634 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
635 "Allocator::value_type must be same type as value_type");
636
Howard Hinnant3e519522010-05-11 19:42:16 +0000637 typedef value_type& reference;
638 typedef const value_type& const_reference;
639 typedef typename allocator_traits<allocator_type>::pointer pointer;
640 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
641 typedef typename allocator_traits<allocator_type>::size_type size_type;
642 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
643
644 typedef typename base::iterator iterator;
645 typedef typename base::const_iterator const_iterator;
646
Howard Hinnant91a47502011-06-03 16:20:53 +0000647 _LIBCPP_INLINE_VISIBILITY
648 forward_list()
649 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
650 {} // = default;
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000651 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000652 explicit forward_list(const allocator_type& __a);
653 explicit forward_list(size_type __n);
Marshall Clowfb829762013-09-08 19:11:51 +0000654#if _LIBCPP_STD_VER > 11
655 explicit forward_list(size_type __n, const allocator_type& __a);
656#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000657 forward_list(size_type __n, const value_type& __v);
658 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
659 template <class _InputIterator>
660 forward_list(_InputIterator __f, _InputIterator __l,
661 typename enable_if<
662 __is_input_iterator<_InputIterator>::value
663 >::type* = nullptr);
664 template <class _InputIterator>
665 forward_list(_InputIterator __f, _InputIterator __l,
666 const allocator_type& __a,
667 typename enable_if<
668 __is_input_iterator<_InputIterator>::value
669 >::type* = nullptr);
670 forward_list(const forward_list& __x);
671 forward_list(const forward_list& __x, const allocator_type& __a);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000672
673 forward_list& operator=(const forward_list& __x);
674
675#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant0af133f2010-09-21 22:55:27 +0000676 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000677 forward_list(forward_list&& __x)
678 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000679 : base(_VSTD::move(__x)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000680 forward_list(forward_list&& __x, const allocator_type& __a);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000681
Howard Hinnant3e519522010-05-11 19:42:16 +0000682 forward_list(initializer_list<value_type> __il);
683 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
684
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000686 forward_list& operator=(forward_list&& __x)
687 _NOEXCEPT_(
688 __node_traits::propagate_on_container_move_assignment::value &&
689 is_nothrow_move_assignable<allocator_type>::value);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000690
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000691 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000692 forward_list& operator=(initializer_list<value_type> __il);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000693
694 _LIBCPP_INLINE_VISIBILITY
695 void assign(initializer_list<value_type> __il);
696#endif // _LIBCPP_CXX03_LANG
697
698 // ~forward_list() = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000699
700 template <class _InputIterator>
701 typename enable_if
702 <
703 __is_input_iterator<_InputIterator>::value,
704 void
705 >::type
706 assign(_InputIterator __f, _InputIterator __l);
707 void assign(size_type __n, const value_type& __v);
Howard Hinnant3e519522010-05-11 19:42:16 +0000708
Howard Hinnant0af133f2010-09-21 22:55:27 +0000709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000710 allocator_type get_allocator() const _NOEXCEPT
711 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000712
Howard Hinnant0af133f2010-09-21 22:55:27 +0000713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000714 iterator begin() _NOEXCEPT
715 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000717 const_iterator begin() const _NOEXCEPT
718 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000720 iterator end() _NOEXCEPT
721 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000723 const_iterator end() const _NOEXCEPT
724 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000725
Howard Hinnant0af133f2010-09-21 22:55:27 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000727 const_iterator cbegin() const _NOEXCEPT
728 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000730 const_iterator cend() const _NOEXCEPT
731 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000732
Howard Hinnant0af133f2010-09-21 22:55:27 +0000733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000734 iterator before_begin() _NOEXCEPT
735 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000737 const_iterator before_begin() const _NOEXCEPT
738 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000739 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000740 const_iterator cbefore_begin() const _NOEXCEPT
741 {return const_iterator(base::__before_begin());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000742
Marshall Clow72c8fad2017-11-15 05:51:26 +0000743 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000744 bool empty() const _NOEXCEPT
745 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000746 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier55b31b4e2016-11-23 01:18:56 +0000747 size_type max_size() const _NOEXCEPT {
748 return std::min<size_type>(
749 __node_traits::max_size(base::__alloc()),
750 numeric_limits<difference_type>::max());
751 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000752
Howard Hinnant0af133f2010-09-21 22:55:27 +0000753 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000754 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000755 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000756 const_reference front() const {return base::__before_begin()->__next_->__value_;}
757
Eric Fiselier99f2c002017-04-16 04:02:01 +0000758#ifndef _LIBCPP_CXX03_LANG
Marshall Clow63b560b2017-01-24 23:09:12 +0000759#if _LIBCPP_STD_VER > 14
Eric Fiselier0e411642016-07-21 03:20:17 +0000760 template <class... _Args> reference emplace_front(_Args&&... __args);
Marshall Clow63b560b2017-01-24 23:09:12 +0000761#else
762 template <class... _Args> void emplace_front(_Args&&... __args);
763#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000764 void push_front(value_type&& __v);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000765#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000766 void push_front(const value_type& __v);
767
768 void pop_front();
769
Eric Fiselier99f2c002017-04-16 04:02:01 +0000770#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000771 template <class... _Args>
772 iterator emplace_after(const_iterator __p, _Args&&... __args);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000773
Howard Hinnant3e519522010-05-11 19:42:16 +0000774 iterator insert_after(const_iterator __p, value_type&& __v);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000775 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
776 {return insert_after(__p, __il.begin(), __il.end());}
777#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000778 iterator insert_after(const_iterator __p, const value_type& __v);
779 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
780 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000781 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000782 typename enable_if
783 <
784 __is_input_iterator<_InputIterator>::value,
785 iterator
786 >::type
787 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000788
Howard Hinnant3db88032010-08-21 20:58:44 +0000789 iterator erase_after(const_iterator __p);
790 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000791
Howard Hinnant0af133f2010-09-21 22:55:27 +0000792 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000793 void swap(forward_list& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000794#if _LIBCPP_STD_VER >= 14
795 _NOEXCEPT
796#else
Howard Hinnant91a47502011-06-03 16:20:53 +0000797 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
798 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000799#endif
Howard Hinnant91a47502011-06-03 16:20:53 +0000800 {base::swap(__x);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000801
802 void resize(size_type __n);
803 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000804 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000805 void clear() _NOEXCEPT {base::clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000806
Eric Fiselier99f2c002017-04-16 04:02:01 +0000807#ifndef _LIBCPP_CXX03_LANG
Howard Hinnanteb92df72011-01-27 21:00:35 +0000808 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000809 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000810 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000811 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000812 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000813 void splice_after(const_iterator __p, forward_list&& __x,
814 const_iterator __f, const_iterator __l);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000815#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000816 void splice_after(const_iterator __p, forward_list& __x);
817 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
818 void splice_after(const_iterator __p, forward_list& __x,
819 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000820 void remove(const value_type& __v);
821 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000822 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000823 void unique() {unique(__equal_to<value_type>());}
824 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000825#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant0af133f2010-09-21 22:55:27 +0000826 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000827 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
828 template <class _Compare>
829 _LIBCPP_INLINE_VISIBILITY
830 void merge(forward_list&& __x, _Compare __comp)
Howard Hinnantce48a112011-06-30 21:18:19 +0000831 {merge(__x, _VSTD::move(__comp));}
Eric Fiselier99f2c002017-04-16 04:02:01 +0000832#endif // _LIBCPP_CXX03_LANG
Howard Hinnant0af133f2010-09-21 22:55:27 +0000833 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000834 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
835 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000837 void sort() {sort(__less<value_type>());}
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000838 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000839 void reverse() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000840
841private:
Howard Hinnant3e519522010-05-11 19:42:16 +0000842
Eric Fiselier99f2c002017-04-16 04:02:01 +0000843#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant91a47502011-06-03 16:20:53 +0000844 void __move_assign(forward_list& __x, true_type)
845 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000846 void __move_assign(forward_list& __x, false_type);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000847#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000848
849 template <class _Compare>
850 static
851 __node_pointer
852 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
853
854 template <class _Compare>
855 static
856 __node_pointer
857 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
858};
859
Marshall Clowe0767002018-05-19 16:02:05 +0000860
861#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
862template<class _InputIterator,
863 class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
864 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
865 >
866forward_list(_InputIterator, _InputIterator)
867 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
868
869template<class _InputIterator,
870 class _Alloc,
871 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
872 >
873forward_list(_InputIterator, _InputIterator, _Alloc)
874 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
875#endif
876
Howard Hinnant3e519522010-05-11 19:42:16 +0000877template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000878inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000879forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
880 : base(__a)
881{
882}
883
884template <class _Tp, class _Alloc>
885forward_list<_Tp, _Alloc>::forward_list(size_type __n)
886{
887 if (__n > 0)
888 {
889 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +0000890 typedef __allocator_destructor<__node_allocator> _Dp;
891 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000892 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
893 __p = __p->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +0000894 {
895 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000896 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000897 __h->__next_ = nullptr;
898 __p->__next_ = __h.release();
899 }
900 }
901}
902
Marshall Clowfb829762013-09-08 19:11:51 +0000903#if _LIBCPP_STD_VER > 11
904template <class _Tp, class _Alloc>
Eric Fiselier572e6de2016-12-03 01:21:40 +0000905forward_list<_Tp, _Alloc>::forward_list(size_type __n,
906 const allocator_type& __base_alloc)
907 : base ( __base_alloc )
Marshall Clowfb829762013-09-08 19:11:51 +0000908{
909 if (__n > 0)
910 {
911 __node_allocator& __a = base::__alloc();
912 typedef __allocator_destructor<__node_allocator> _Dp;
913 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000914 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
915 __p = __p->__next_as_begin())
Marshall Clowfb829762013-09-08 19:11:51 +0000916 {
917 __h.reset(__node_traits::allocate(__a, 1));
918 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
919 __h->__next_ = nullptr;
920 __p->__next_ = __h.release();
921 }
922 }
923}
924#endif
925
Howard Hinnant3e519522010-05-11 19:42:16 +0000926template <class _Tp, class _Alloc>
927forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
928{
929 insert_after(cbefore_begin(), __n, __v);
930}
931
932template <class _Tp, class _Alloc>
933forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
934 const allocator_type& __a)
935 : base(__a)
936{
937 insert_after(cbefore_begin(), __n, __v);
938}
939
940template <class _Tp, class _Alloc>
941template <class _InputIterator>
942forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
943 typename enable_if<
944 __is_input_iterator<_InputIterator>::value
945 >::type*)
946{
947 insert_after(cbefore_begin(), __f, __l);
948}
949
950template <class _Tp, class _Alloc>
951template <class _InputIterator>
952forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
953 const allocator_type& __a,
954 typename enable_if<
955 __is_input_iterator<_InputIterator>::value
956 >::type*)
957 : base(__a)
958{
959 insert_after(cbefore_begin(), __f, __l);
960}
961
962template <class _Tp, class _Alloc>
963forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
Eric Fiselier8cef7fd2018-06-05 22:32:52 +0000964 : base(
965 __node_traits::select_on_container_copy_construction(__x.__alloc())) {
966 insert_after(cbefore_begin(), __x.begin(), __x.end());
Howard Hinnant3e519522010-05-11 19:42:16 +0000967}
968
969template <class _Tp, class _Alloc>
970forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
971 const allocator_type& __a)
972 : base(__a)
973{
974 insert_after(cbefore_begin(), __x.begin(), __x.end());
975}
976
Eric Fiselier99f2c002017-04-16 04:02:01 +0000977template <class _Tp, class _Alloc>
978forward_list<_Tp, _Alloc>&
979forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
980{
981 if (this != &__x)
982 {
983 base::__copy_assign_alloc(__x);
984 assign(__x.begin(), __x.end());
985 }
986 return *this;
987}
Howard Hinnant3e519522010-05-11 19:42:16 +0000988
Eric Fiselier99f2c002017-04-16 04:02:01 +0000989#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000990template <class _Tp, class _Alloc>
991forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
992 const allocator_type& __a)
Howard Hinnantce48a112011-06-30 21:18:19 +0000993 : base(_VSTD::move(__x), __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000994{
995 if (base::__alloc() != __x.__alloc())
996 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000997 typedef move_iterator<iterator> _Ip;
998 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +0000999 }
1000}
1001
Howard Hinnant3e519522010-05-11 19:42:16 +00001002template <class _Tp, class _Alloc>
1003forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
1004{
1005 insert_after(cbefore_begin(), __il.begin(), __il.end());
1006}
1007
1008template <class _Tp, class _Alloc>
1009forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
1010 const allocator_type& __a)
1011 : base(__a)
1012{
1013 insert_after(cbefore_begin(), __il.begin(), __il.end());
1014}
1015
Howard Hinnant3e519522010-05-11 19:42:16 +00001016template <class _Tp, class _Alloc>
1017void
1018forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +00001019 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00001020{
1021 clear();
1022 base::__move_assign_alloc(__x);
1023 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
1024 __x.__before_begin()->__next_ = nullptr;
1025}
1026
1027template <class _Tp, class _Alloc>
1028void
1029forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
1030{
1031 if (base::__alloc() == __x.__alloc())
1032 __move_assign(__x, true_type());
1033 else
1034 {
Howard Hinnantc003db12011-11-29 18:15:50 +00001035 typedef move_iterator<iterator> _Ip;
1036 assign(_Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +00001037 }
1038}
1039
1040template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001041inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001042forward_list<_Tp, _Alloc>&
1043forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +00001044 _NOEXCEPT_(
1045 __node_traits::propagate_on_container_move_assignment::value &&
1046 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00001047{
1048 __move_assign(__x, integral_constant<bool,
1049 __node_traits::propagate_on_container_move_assignment::value>());
1050 return *this;
1051}
1052
Howard Hinnant3e519522010-05-11 19:42:16 +00001053template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001054inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001055forward_list<_Tp, _Alloc>&
1056forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
1057{
1058 assign(__il.begin(), __il.end());
1059 return *this;
1060}
1061
Eric Fiselier99f2c002017-04-16 04:02:01 +00001062#endif // _LIBCPP_CXX03_LANG
Howard Hinnant54976f22011-08-12 21:56:02 +00001063
Howard Hinnant3e519522010-05-11 19:42:16 +00001064template <class _Tp, class _Alloc>
1065template <class _InputIterator>
1066typename enable_if
1067<
1068 __is_input_iterator<_InputIterator>::value,
1069 void
1070>::type
1071forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
1072{
1073 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +00001074 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001075 iterator __e = end();
Eric Fiselier910285b2014-10-27 19:28:20 +00001076 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
Howard Hinnant3e519522010-05-11 19:42:16 +00001077 *__j = *__f;
1078 if (__j == __e)
1079 insert_after(__i, __f, __l);
1080 else
1081 erase_after(__i, __e);
1082}
1083
1084template <class _Tp, class _Alloc>
1085void
1086forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
1087{
1088 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +00001089 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001090 iterator __e = end();
1091 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1092 *__j = __v;
1093 if (__j == __e)
1094 insert_after(__i, __n, __v);
1095 else
1096 erase_after(__i, __e);
1097}
1098
Eric Fiselier99f2c002017-04-16 04:02:01 +00001099#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant54976f22011-08-12 21:56:02 +00001100
Howard Hinnant3e519522010-05-11 19:42:16 +00001101template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001102inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001103void
1104forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1105{
1106 assign(__il.begin(), __il.end());
1107}
1108
Howard Hinnant3e519522010-05-11 19:42:16 +00001109template <class _Tp, class _Alloc>
1110template <class... _Args>
Marshall Clow63b560b2017-01-24 23:09:12 +00001111#if _LIBCPP_STD_VER > 14
Eric Fiselier0e411642016-07-21 03:20:17 +00001112typename forward_list<_Tp, _Alloc>::reference
Marshall Clow63b560b2017-01-24 23:09:12 +00001113#else
1114void
1115#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001116forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1117{
1118 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001119 typedef __allocator_destructor<__node_allocator> _Dp;
1120 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001121 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1122 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001123 __h->__next_ = base::__before_begin()->__next_;
1124 base::__before_begin()->__next_ = __h.release();
Marshall Clow63b560b2017-01-24 23:09:12 +00001125#if _LIBCPP_STD_VER > 14
Eric Fiselier0e411642016-07-21 03:20:17 +00001126 return base::__before_begin()->__next_->__value_;
Marshall Clow63b560b2017-01-24 23:09:12 +00001127#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001128}
1129
1130template <class _Tp, class _Alloc>
1131void
1132forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1133{
1134 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001135 typedef __allocator_destructor<__node_allocator> _Dp;
1136 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001137 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001138 __h->__next_ = base::__before_begin()->__next_;
1139 base::__before_begin()->__next_ = __h.release();
1140}
1141
Eric Fiselier99f2c002017-04-16 04:02:01 +00001142#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001143
1144template <class _Tp, class _Alloc>
1145void
1146forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1147{
1148 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001149 typedef __allocator_destructor<__node_allocator> _Dp;
1150 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001151 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001152 __h->__next_ = base::__before_begin()->__next_;
1153 base::__before_begin()->__next_ = __h.release();
1154}
1155
1156template <class _Tp, class _Alloc>
1157void
1158forward_list<_Tp, _Alloc>::pop_front()
1159{
1160 __node_allocator& __a = base::__alloc();
1161 __node_pointer __p = base::__before_begin()->__next_;
1162 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001163 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001164 __node_traits::deallocate(__a, __p, 1);
1165}
1166
Eric Fiselier99f2c002017-04-16 04:02:01 +00001167#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001168
1169template <class _Tp, class _Alloc>
1170template <class... _Args>
1171typename forward_list<_Tp, _Alloc>::iterator
1172forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1173{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001174 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001175 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001176 typedef __allocator_destructor<__node_allocator> _Dp;
1177 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001178 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1179 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001180 __h->__next_ = __r->__next_;
1181 __r->__next_ = __h.release();
1182 return iterator(__r->__next_);
1183}
1184
1185template <class _Tp, class _Alloc>
1186typename forward_list<_Tp, _Alloc>::iterator
1187forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1188{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001189 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001190 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001191 typedef __allocator_destructor<__node_allocator> _Dp;
1192 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001193 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001194 __h->__next_ = __r->__next_;
1195 __r->__next_ = __h.release();
1196 return iterator(__r->__next_);
1197}
1198
Eric Fiselier99f2c002017-04-16 04:02:01 +00001199#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001200
1201template <class _Tp, class _Alloc>
1202typename forward_list<_Tp, _Alloc>::iterator
1203forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1204{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001205 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001206 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001207 typedef __allocator_destructor<__node_allocator> _Dp;
1208 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001209 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001210 __h->__next_ = __r->__next_;
1211 __r->__next_ = __h.release();
1212 return iterator(__r->__next_);
1213}
1214
1215template <class _Tp, class _Alloc>
1216typename forward_list<_Tp, _Alloc>::iterator
1217forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1218 const value_type& __v)
1219{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001220 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001221 if (__n > 0)
1222 {
1223 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001224 typedef __allocator_destructor<__node_allocator> _Dp;
1225 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001226 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001227 __node_pointer __first = __h.release();
1228 __node_pointer __last = __first;
1229#ifndef _LIBCPP_NO_EXCEPTIONS
1230 try
1231 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001232#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001233 for (--__n; __n != 0; --__n, __last = __last->__next_)
1234 {
1235 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001236 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001237 __last->__next_ = __h.release();
1238 }
1239#ifndef _LIBCPP_NO_EXCEPTIONS
1240 }
1241 catch (...)
1242 {
1243 while (__first != nullptr)
1244 {
1245 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001246 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001247 __node_traits::deallocate(__a, __first, 1);
1248 __first = __next;
1249 }
1250 throw;
1251 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001252#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001253 __last->__next_ = __r->__next_;
1254 __r->__next_ = __first;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001255 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnant3e519522010-05-11 19:42:16 +00001256 }
1257 return iterator(__r);
1258}
1259
1260template <class _Tp, class _Alloc>
1261template <class _InputIterator>
1262typename enable_if
1263<
1264 __is_input_iterator<_InputIterator>::value,
1265 typename forward_list<_Tp, _Alloc>::iterator
1266>::type
1267forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1268 _InputIterator __f, _InputIterator __l)
1269{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001270 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001271 if (__f != __l)
1272 {
1273 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001274 typedef __allocator_destructor<__node_allocator> _Dp;
1275 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001276 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001277 __node_pointer __first = __h.release();
1278 __node_pointer __last = __first;
1279#ifndef _LIBCPP_NO_EXCEPTIONS
1280 try
1281 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001282#endif // _LIBCPP_NO_EXCEPTIONS
Eric Fiselier910285b2014-10-27 19:28:20 +00001283 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001284 {
1285 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001286 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001287 __last->__next_ = __h.release();
1288 }
1289#ifndef _LIBCPP_NO_EXCEPTIONS
1290 }
1291 catch (...)
1292 {
1293 while (__first != nullptr)
1294 {
1295 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001296 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001297 __node_traits::deallocate(__a, __first, 1);
1298 __first = __next;
1299 }
1300 throw;
1301 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001302#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001303 __last->__next_ = __r->__next_;
1304 __r->__next_ = __first;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001305 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnant3e519522010-05-11 19:42:16 +00001306 }
1307 return iterator(__r);
1308}
1309
1310template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001311typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001312forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1313{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001314 __begin_node_pointer __p = __f.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001315 __node_pointer __n = __p->__next_;
1316 __p->__next_ = __n->__next_;
1317 __node_allocator& __a = base::__alloc();
Howard Hinnantce48a112011-06-30 21:18:19 +00001318 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001319 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001320 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001321}
1322
1323template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001324typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001325forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1326{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001327 __node_pointer __e = __l.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001328 if (__f != __l)
1329 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001330 __begin_node_pointer __bp = __f.__get_begin();
1331
1332 __node_pointer __n = __bp->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001333 if (__n != __e)
1334 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001335 __bp->__next_ = __e;
Howard Hinnant3e519522010-05-11 19:42:16 +00001336 __node_allocator& __a = base::__alloc();
1337 do
1338 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001339 __node_pointer __tmp = __n->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001340 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001341 __node_traits::deallocate(__a, __n, 1);
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001342 __n = __tmp;
Howard Hinnant3e519522010-05-11 19:42:16 +00001343 } while (__n != __e);
1344 }
1345 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001346 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001347}
1348
1349template <class _Tp, class _Alloc>
1350void
1351forward_list<_Tp, _Alloc>::resize(size_type __n)
1352{
1353 size_type __sz = 0;
1354 iterator __p = before_begin();
1355 iterator __i = begin();
1356 iterator __e = end();
1357 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1358 ;
1359 if (__i != __e)
1360 erase_after(__p, __e);
1361 else
1362 {
1363 __n -= __sz;
1364 if (__n > 0)
1365 {
1366 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001367 typedef __allocator_destructor<__node_allocator> _Dp;
1368 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001369 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1370 __ptr = __ptr->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001371 {
1372 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001373 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001374 __h->__next_ = nullptr;
1375 __ptr->__next_ = __h.release();
1376 }
1377 }
1378 }
1379}
1380
1381template <class _Tp, class _Alloc>
1382void
1383forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1384{
1385 size_type __sz = 0;
1386 iterator __p = before_begin();
1387 iterator __i = begin();
1388 iterator __e = end();
1389 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1390 ;
1391 if (__i != __e)
1392 erase_after(__p, __e);
1393 else
1394 {
1395 __n -= __sz;
1396 if (__n > 0)
1397 {
1398 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001399 typedef __allocator_destructor<__node_allocator> _Dp;
1400 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001401 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1402 __ptr = __ptr->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001403 {
1404 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001405 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001406 __h->__next_ = nullptr;
1407 __ptr->__next_ = __h.release();
1408 }
1409 }
1410 }
1411}
1412
1413template <class _Tp, class _Alloc>
1414void
1415forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001416 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001417{
1418 if (!__x.empty())
1419 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001420 if (__p.__get_begin()->__next_ != nullptr)
Howard Hinnant3e519522010-05-11 19:42:16 +00001421 {
1422 const_iterator __lm1 = __x.before_begin();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001423 while (__lm1.__get_begin()->__next_ != nullptr)
Howard Hinnant3e519522010-05-11 19:42:16 +00001424 ++__lm1;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001425 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001426 }
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001427 __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
Howard Hinnant8a27ba82013-06-24 17:17:28 +00001428 __x.__before_begin()->__next_ = nullptr;
Howard Hinnant3e519522010-05-11 19:42:16 +00001429 }
1430}
1431
1432template <class _Tp, class _Alloc>
1433void
1434forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Eric Fiselierfd838222016-12-23 23:37:52 +00001435 forward_list& /*__other*/,
Howard Hinnant3e519522010-05-11 19:42:16 +00001436 const_iterator __i)
1437{
Howard Hinnantce48a112011-06-30 21:18:19 +00001438 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001439 if (__p != __i && __p != __lm1)
1440 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001441 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
1442 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1443 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001444 }
1445}
1446
1447template <class _Tp, class _Alloc>
1448void
1449forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Eric Fiselierfd838222016-12-23 23:37:52 +00001450 forward_list& /*__other*/,
Howard Hinnant3e519522010-05-11 19:42:16 +00001451 const_iterator __f, const_iterator __l)
1452{
1453 if (__f != __l && __p != __f)
1454 {
1455 const_iterator __lm1 = __f;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001456 while (__lm1.__get_begin()->__next_ != __l.__get_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001457 ++__lm1;
1458 if (__f != __lm1)
1459 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001460 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1461 __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
1462 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001463 }
1464 }
1465}
1466
Eric Fiselier99f2c002017-04-16 04:02:01 +00001467#ifndef _LIBCPP_CXX03_LANG
Howard Hinnanteb92df72011-01-27 21:00:35 +00001468
1469template <class _Tp, class _Alloc>
1470inline _LIBCPP_INLINE_VISIBILITY
1471void
1472forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1473 forward_list&& __x)
1474{
1475 splice_after(__p, __x);
1476}
1477
1478template <class _Tp, class _Alloc>
1479inline _LIBCPP_INLINE_VISIBILITY
1480void
1481forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1482 forward_list&& __x,
1483 const_iterator __i)
1484{
1485 splice_after(__p, __x, __i);
1486}
1487
1488template <class _Tp, class _Alloc>
1489inline _LIBCPP_INLINE_VISIBILITY
1490void
1491forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1492 forward_list&& __x,
1493 const_iterator __f, const_iterator __l)
1494{
1495 splice_after(__p, __x, __f, __l);
1496}
1497
Eric Fiselier99f2c002017-04-16 04:02:01 +00001498#endif // _LIBCPP_CXX03_LANG
Howard Hinnanteb92df72011-01-27 21:00:35 +00001499
Howard Hinnant3e519522010-05-11 19:42:16 +00001500template <class _Tp, class _Alloc>
1501void
1502forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1503{
Marshall Clow99d2df92014-08-08 15:58:00 +00001504 forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
Howard Hinnant3e519522010-05-11 19:42:16 +00001505 iterator __e = end();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001506 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnant3e519522010-05-11 19:42:16 +00001507 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001508 if (__i.__get_begin()->__next_->__value_ == __v)
Howard Hinnant3e519522010-05-11 19:42:16 +00001509 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001510 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001511 for (; __j != __e && *__j == __v; ++__j)
1512 ;
Marshall Clowc8528b52014-10-18 11:03:33 +00001513 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
Howard Hinnant3e519522010-05-11 19:42:16 +00001514 if (__j == __e)
1515 break;
1516 __i = __j;
1517 }
1518 else
1519 ++__i;
1520 }
1521}
1522
1523template <class _Tp, class _Alloc>
1524template <class _Predicate>
1525void
1526forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1527{
1528 iterator __e = end();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001529 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnant3e519522010-05-11 19:42:16 +00001530 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001531 if (__pred(__i.__get_begin()->__next_->__value_))
Howard Hinnant3e519522010-05-11 19:42:16 +00001532 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001533 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001534 for (; __j != __e && __pred(*__j); ++__j)
1535 ;
1536 erase_after(__i, __j);
1537 if (__j == __e)
1538 break;
1539 __i = __j;
1540 }
1541 else
1542 ++__i;
1543 }
1544}
1545
1546template <class _Tp, class _Alloc>
1547template <class _BinaryPredicate>
1548void
1549forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1550{
1551 for (iterator __i = begin(), __e = end(); __i != __e;)
1552 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001553 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001554 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1555 ;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001556 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
Howard Hinnant3e519522010-05-11 19:42:16 +00001557 erase_after(__i, __j);
1558 __i = __j;
1559 }
1560}
1561
1562template <class _Tp, class _Alloc>
1563template <class _Compare>
1564void
Howard Hinnant3e519522010-05-11 19:42:16 +00001565forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001566{
1567 if (this != &__x)
1568 {
1569 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1570 __x.__before_begin()->__next_,
1571 __comp);
1572 __x.__before_begin()->__next_ = nullptr;
1573 }
1574}
1575
1576template <class _Tp, class _Alloc>
1577template <class _Compare>
1578typename forward_list<_Tp, _Alloc>::__node_pointer
1579forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1580 _Compare& __comp)
1581{
1582 if (__f1 == nullptr)
1583 return __f2;
1584 if (__f2 == nullptr)
1585 return __f1;
1586 __node_pointer __r;
1587 if (__comp(__f2->__value_, __f1->__value_))
1588 {
1589 __node_pointer __t = __f2;
1590 while (__t->__next_ != nullptr &&
1591 __comp(__t->__next_->__value_, __f1->__value_))
1592 __t = __t->__next_;
1593 __r = __f2;
1594 __f2 = __t->__next_;
1595 __t->__next_ = __f1;
1596 }
1597 else
1598 __r = __f1;
1599 __node_pointer __p = __f1;
1600 __f1 = __f1->__next_;
1601 while (__f1 != nullptr && __f2 != nullptr)
1602 {
1603 if (__comp(__f2->__value_, __f1->__value_))
1604 {
1605 __node_pointer __t = __f2;
1606 while (__t->__next_ != nullptr &&
1607 __comp(__t->__next_->__value_, __f1->__value_))
1608 __t = __t->__next_;
1609 __p->__next_ = __f2;
1610 __f2 = __t->__next_;
1611 __t->__next_ = __f1;
1612 }
1613 __p = __f1;
1614 __f1 = __f1->__next_;
1615 }
1616 if (__f2 != nullptr)
1617 __p->__next_ = __f2;
1618 return __r;
1619}
1620
1621template <class _Tp, class _Alloc>
1622template <class _Compare>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001623inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001624void
1625forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1626{
1627 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnantce48a112011-06-30 21:18:19 +00001628 _VSTD::distance(begin(), end()), __comp);
Howard Hinnant3e519522010-05-11 19:42:16 +00001629}
1630
1631template <class _Tp, class _Alloc>
1632template <class _Compare>
1633typename forward_list<_Tp, _Alloc>::__node_pointer
1634forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1635 _Compare& __comp)
1636{
1637 switch (__sz)
1638 {
1639 case 0:
1640 case 1:
1641 return __f1;
1642 case 2:
1643 if (__comp(__f1->__next_->__value_, __f1->__value_))
1644 {
1645 __node_pointer __t = __f1->__next_;
1646 __t->__next_ = __f1;
1647 __f1->__next_ = nullptr;
1648 __f1 = __t;
1649 }
1650 return __f1;
1651 }
1652 difference_type __sz1 = __sz / 2;
1653 difference_type __sz2 = __sz - __sz1;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001654 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001655 __node_pointer __f2 = __t->__next_;
1656 __t->__next_ = nullptr;
1657 return __merge(__sort(__f1, __sz1, __comp),
1658 __sort(__f2, __sz2, __comp), __comp);
1659}
1660
1661template <class _Tp, class _Alloc>
1662void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001663forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001664{
1665 __node_pointer __p = base::__before_begin()->__next_;
1666 if (__p != nullptr)
1667 {
1668 __node_pointer __f = __p->__next_;
1669 __p->__next_ = nullptr;
1670 while (__f != nullptr)
1671 {
1672 __node_pointer __t = __f->__next_;
1673 __f->__next_ = __p;
1674 __p = __f;
1675 __f = __t;
1676 }
1677 base::__before_begin()->__next_ = __p;
1678 }
1679}
1680
1681template <class _Tp, class _Alloc>
1682bool operator==(const forward_list<_Tp, _Alloc>& __x,
1683 const forward_list<_Tp, _Alloc>& __y)
1684{
Howard Hinnantc003db12011-11-29 18:15:50 +00001685 typedef forward_list<_Tp, _Alloc> _Cp;
1686 typedef typename _Cp::const_iterator _Ip;
1687 _Ip __ix = __x.begin();
1688 _Ip __ex = __x.end();
1689 _Ip __iy = __y.begin();
1690 _Ip __ey = __y.end();
Howard Hinnant3e519522010-05-11 19:42:16 +00001691 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1692 if (!(*__ix == *__iy))
1693 return false;
1694 return (__ix == __ex) == (__iy == __ey);
1695}
1696
1697template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001698inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001699bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1700 const forward_list<_Tp, _Alloc>& __y)
1701{
1702 return !(__x == __y);
1703}
1704
1705template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001706inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001707bool operator< (const forward_list<_Tp, _Alloc>& __x,
1708 const forward_list<_Tp, _Alloc>& __y)
1709{
Howard Hinnantce48a112011-06-30 21:18:19 +00001710 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnant3e519522010-05-11 19:42:16 +00001711 __y.begin(), __y.end());
1712}
1713
1714template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001715inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001716bool operator> (const forward_list<_Tp, _Alloc>& __x,
1717 const forward_list<_Tp, _Alloc>& __y)
1718{
1719 return __y < __x;
1720}
1721
1722template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001723inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001724bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1725 const forward_list<_Tp, _Alloc>& __y)
1726{
1727 return !(__x < __y);
1728}
1729
1730template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001731inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001732bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1733 const forward_list<_Tp, _Alloc>& __y)
1734{
1735 return !(__y < __x);
1736}
1737
1738template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001739inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001740void
1741swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +00001742 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001743{
1744 __x.swap(__y);
1745}
1746
1747_LIBCPP_END_NAMESPACE_STD
1748
Eric Fiseliera016efb2017-05-31 22:07:49 +00001749_LIBCPP_POP_MACROS
1750
Howard Hinnant3e519522010-05-11 19:42:16 +00001751#endif // _LIBCPP_FORWARD_LIST