blob: 8bfa9a084338d512870c613dd1e4eddaf2177dc3 [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
137template <class T, class Allocator>
138 bool operator==(const forward_list<T, Allocator>& x,
139 const forward_list<T, Allocator>& y);
140
141template <class T, class Allocator>
142 bool operator< (const forward_list<T, Allocator>& x,
143 const forward_list<T, Allocator>& y);
144
145template <class T, class Allocator>
146 bool operator!=(const forward_list<T, Allocator>& x,
147 const forward_list<T, Allocator>& y);
148
149template <class T, class Allocator>
150 bool operator> (const forward_list<T, Allocator>& x,
151 const forward_list<T, Allocator>& y);
152
153template <class T, class Allocator>
154 bool operator>=(const forward_list<T, Allocator>& x,
155 const forward_list<T, Allocator>& y);
156
157template <class T, class Allocator>
158 bool operator<=(const forward_list<T, Allocator>& x,
159 const forward_list<T, Allocator>& y);
160
161template <class T, class Allocator>
Howard Hinnant91a47502011-06-03 16:20:53 +0000162 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
Howard Hinnant45900102011-06-03 17:30:28 +0000163 noexcept(noexcept(x.swap(y)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000164
165} // std
166
167*/
168
169#include <__config>
Howard Hinnant3e519522010-05-11 19:42:16 +0000170#include <initializer_list>
171#include <memory>
172#include <limits>
173#include <iterator>
174#include <algorithm>
175
Howard Hinnant073458b2011-10-17 20:05:10 +0000176#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +0000177#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000178#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000179
Eric Fiseliera016efb2017-05-31 22:07:49 +0000180_LIBCPP_PUSH_MACROS
181#include <__undef_macros>
182
183
Howard Hinnant3e519522010-05-11 19:42:16 +0000184_LIBCPP_BEGIN_NAMESPACE_STD
185
Howard Hinnantce534202011-06-14 19:58:17 +0000186template <class _Tp, class _VoidPtr> struct __forward_list_node;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000187template <class _NodePtr> struct __forward_begin_node;
188
189
190template <class>
191struct __forward_list_node_value_type;
192
193template <class _Tp, class _VoidPtr>
194struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
195 typedef _Tp type;
196};
197
198template <class _NodePtr>
199struct __forward_node_traits {
200
201 typedef typename remove_cv<
202 typename pointer_traits<_NodePtr>::element_type>::type __node;
203 typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
204 typedef _NodePtr __node_pointer;
205 typedef __forward_begin_node<_NodePtr> __begin_node;
206 typedef typename __rebind_pointer<_NodePtr, __begin_node>::type
207 __begin_node_pointer;
208 typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer;
209
210#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
211 typedef __begin_node_pointer __iter_node_pointer;
212#else
213 typedef typename conditional<
214 is_pointer<__void_pointer>::value,
215 __begin_node_pointer,
216 __node_pointer
217 >::type __iter_node_pointer;
218#endif
219
220 typedef typename conditional<
221 is_same<__iter_node_pointer, __node_pointer>::value,
222 __begin_node_pointer,
223 __node_pointer
224 >::type __non_iter_node_pointer;
225
226 _LIBCPP_INLINE_VISIBILITY
227 static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) {
228 return __p;
229 }
230 _LIBCPP_INLINE_VISIBILITY
231 static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
232 return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
233 }
234};
Howard Hinnant3e519522010-05-11 19:42:16 +0000235
236template <class _NodePtr>
237struct __forward_begin_node
238{
Howard Hinnant3e519522010-05-11 19:42:16 +0000239 typedef _NodePtr pointer;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000240 typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000241
242 pointer __next_;
243
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000244 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
245
246 _LIBCPP_INLINE_VISIBILITY
247 __begin_node_pointer __next_as_begin() const {
248 return static_cast<__begin_node_pointer>(__next_);
249 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000250};
251
252template <class _Tp, class _VoidPtr>
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000253struct _LIBCPP_HIDDEN __begin_node_of
254{
Eric Fiselier934b0922015-12-30 21:52:00 +0000255 typedef __forward_begin_node<
256 typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
257 > type;
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000258};
259
260template <class _Tp, class _VoidPtr>
261struct __forward_list_node
262 : public __begin_node_of<_Tp, _VoidPtr>::type
Howard Hinnant3e519522010-05-11 19:42:16 +0000263{
264 typedef _Tp value_type;
265
266 value_type __value_;
267};
268
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000269
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000270template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list;
271template<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000272
273template <class _NodePtr>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000274class _LIBCPP_TEMPLATE_VIS __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000275{
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000276 typedef __forward_node_traits<_NodePtr> __traits;
277 typedef typename __traits::__node_pointer __node_pointer;
278 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
279 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
280 typedef typename __traits::__void_pointer __void_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000281
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000282 __iter_node_pointer __ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +0000283
Howard Hinnant0af133f2010-09-21 22:55:27 +0000284 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000285 __begin_node_pointer __get_begin() const {
286 return static_cast<__begin_node_pointer>(
287 static_cast<__void_pointer>(__ptr_));
288 }
289 _LIBCPP_INLINE_VISIBILITY
290 __node_pointer __get_unsafe_node_pointer() const {
291 return static_cast<__node_pointer>(
292 static_cast<__void_pointer>(__ptr_));
293 }
294
295 _LIBCPP_INLINE_VISIBILITY
296 explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
297
298 _LIBCPP_INLINE_VISIBILITY
299 explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
300 : __ptr_(__traits::__as_iter_node(__p)) {}
301
302 _LIBCPP_INLINE_VISIBILITY
303 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
304 : __ptr_(__traits::__as_iter_node(__p)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000305
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000306 template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list;
307 template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000308
309public:
310 typedef forward_iterator_tag iterator_category;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000311 typedef typename __traits::__node_value_type value_type;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000312 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000313 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000314 difference_type;
Eric Fiselier934b0922015-12-30 21:52:00 +0000315 typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000316
Howard Hinnant0af133f2010-09-21 22:55:27 +0000317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000318 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000319
Howard Hinnant0af133f2010-09-21 22:55:27 +0000320 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000321 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000322 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000323 pointer operator->() const {
324 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
325 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000326
Howard Hinnant0af133f2010-09-21 22:55:27 +0000327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000328 __forward_list_iterator& operator++()
329 {
Eric Fiselier4de5f982016-01-27 00:49:20 +0000330 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000331 return *this;
332 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000334 __forward_list_iterator operator++(int)
335 {
336 __forward_list_iterator __t(*this);
337 ++(*this);
338 return __t;
339 }
340
Howard Hinnant0af133f2010-09-21 22:55:27 +0000341 friend _LIBCPP_INLINE_VISIBILITY
342 bool operator==(const __forward_list_iterator& __x,
343 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000344 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000345 friend _LIBCPP_INLINE_VISIBILITY
346 bool operator!=(const __forward_list_iterator& __x,
347 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000348 {return !(__x == __y);}
349};
350
351template <class _NodeConstPtr>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000352class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000353{
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000354 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
355 typedef _NodeConstPtr _NodePtr;
Howard Hinnant3e519522010-05-11 19:42:16 +0000356
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000357 typedef __forward_node_traits<_NodePtr> __traits;
358 typedef typename __traits::__node __node;
359 typedef typename __traits::__node_pointer __node_pointer;
360 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
361 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
362 typedef typename __traits::__void_pointer __void_pointer;
363
364 __iter_node_pointer __ptr_;
365
366 __begin_node_pointer __get_begin() const {
367 return static_cast<__begin_node_pointer>(
368 static_cast<__void_pointer>(__ptr_));
369 }
370 __node_pointer __get_unsafe_node_pointer() const {
371 return static_cast<__node_pointer>(
372 static_cast<__void_pointer>(__ptr_));
373 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000374
Howard Hinnant0af133f2010-09-21 22:55:27 +0000375 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000376 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
377 : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000378
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000379 _LIBCPP_INLINE_VISIBILITY
380 explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
381 : __ptr_(__traits::__as_iter_node(__p)) {}
382
383 _LIBCPP_INLINE_VISIBILITY
384 explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
385 : __ptr_(__traits::__as_iter_node(__p)) {}
386
Howard Hinnant3e519522010-05-11 19:42:16 +0000387
388 template<class, class> friend class forward_list;
389
390public:
391 typedef forward_iterator_tag iterator_category;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000392 typedef typename __traits::__node_value_type value_type;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000393 typedef const value_type& reference;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000394 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000395 difference_type;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000396 typedef typename __rebind_pointer<__node_pointer, const value_type>::type
397 pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000398
Howard Hinnant0af133f2010-09-21 22:55:27 +0000399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000400 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000402 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000403 : __ptr_(__p.__ptr_) {}
404
Howard Hinnant0af133f2010-09-21 22:55:27 +0000405 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000406 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000407 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000408 pointer operator->() const {return pointer_traits<pointer>::pointer_to(
409 __get_unsafe_node_pointer()->__value_);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000410
Howard Hinnant0af133f2010-09-21 22:55:27 +0000411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000412 __forward_list_const_iterator& operator++()
413 {
Eric Fiselier4de5f982016-01-27 00:49:20 +0000414 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000415 return *this;
416 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000418 __forward_list_const_iterator operator++(int)
419 {
420 __forward_list_const_iterator __t(*this);
421 ++(*this);
422 return __t;
423 }
424
Howard Hinnant0af133f2010-09-21 22:55:27 +0000425 friend _LIBCPP_INLINE_VISIBILITY
426 bool operator==(const __forward_list_const_iterator& __x,
427 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000428 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000429 friend _LIBCPP_INLINE_VISIBILITY
430 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000431 const __forward_list_const_iterator& __y)
432 {return !(__x == __y);}
433};
434
435template <class _Tp, class _Alloc>
436class __forward_list_base
437{
438protected:
439 typedef _Tp value_type;
440 typedef _Alloc allocator_type;
441
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000442 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
443 typedef __forward_list_node<value_type, void_pointer> __node;
444 typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
Marshall Clow1f508012015-04-07 05:21:38 +0000445 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000446 typedef allocator_traits<__node_allocator> __node_traits;
447 typedef typename __node_traits::pointer __node_pointer;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000448
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000449 typedef typename __rebind_alloc_helper<
450 allocator_traits<allocator_type>, __begin_node
451 >::type __begin_node_allocator;
452 typedef typename allocator_traits<__begin_node_allocator>::pointer
453 __begin_node_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000454
455 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
456
Howard Hinnant0af133f2010-09-21 22:55:27 +0000457 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000458 __begin_node_pointer __before_begin() _NOEXCEPT
459 {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000460 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000461 __begin_node_pointer __before_begin() const _NOEXCEPT
462 {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));}
Howard Hinnant3e519522010-05-11 19:42:16 +0000463
Howard Hinnant0af133f2010-09-21 22:55:27 +0000464 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000465 __node_allocator& __alloc() _NOEXCEPT
466 {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000468 const __node_allocator& __alloc() const _NOEXCEPT
469 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000470
471 typedef __forward_list_iterator<__node_pointer> iterator;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000472 typedef __forward_list_const_iterator<__node_pointer> const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000473
Howard Hinnant0af133f2010-09-21 22:55:27 +0000474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000475 __forward_list_base()
Howard Hinnant91a47502011-06-03 16:20:53 +0000476 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000477 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000479 __forward_list_base(const allocator_type& __a)
480 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
481
Eric Fiselier99f2c002017-04-16 04:02:01 +0000482#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant91a47502011-06-03 16:20:53 +0000483public:
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000485 __forward_list_base(__forward_list_base&& __x)
486 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000488 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000489#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000490
491private:
492 __forward_list_base(const __forward_list_base&);
493 __forward_list_base& operator=(const __forward_list_base&);
Howard Hinnant3e519522010-05-11 19:42:16 +0000494
Howard Hinnant91a47502011-06-03 16:20:53 +0000495public:
Howard Hinnant3e519522010-05-11 19:42:16 +0000496 ~__forward_list_base();
497
Howard Hinnant91a47502011-06-03 16:20:53 +0000498protected:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000499 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000500 void __copy_assign_alloc(const __forward_list_base& __x)
501 {__copy_assign_alloc(__x, integral_constant<bool,
502 __node_traits::propagate_on_container_copy_assignment::value>());}
503
Howard Hinnant0af133f2010-09-21 22:55:27 +0000504 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000505 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000506 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
507 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000508 {__move_assign_alloc(__x, integral_constant<bool,
509 __node_traits::propagate_on_container_move_assignment::value>());}
510
Howard Hinnant91a47502011-06-03 16:20:53 +0000511public:
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000512 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000513 void swap(__forward_list_base& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000514#if _LIBCPP_STD_VER >= 14
515 _NOEXCEPT;
516#else
517 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
518 __is_nothrow_swappable<__node_allocator>::value);
519#endif
Howard Hinnant91a47502011-06-03 16:20:53 +0000520protected:
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000521 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000522
523private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000525 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000527 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
528 {
529 if (__alloc() != __x.__alloc())
530 clear();
531 __alloc() = __x.__alloc();
532 }
533
Howard Hinnant0af133f2010-09-21 22:55:27 +0000534 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierfd838222016-12-23 23:37:52 +0000535 void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT
Howard Hinnant91a47502011-06-03 16:20:53 +0000536 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000537 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000538 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000539 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000540 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000541};
542
Eric Fiselier99f2c002017-04-16 04:02:01 +0000543#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000544
545template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000546inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000547__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000548 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000549 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnant3e519522010-05-11 19:42:16 +0000550{
551 __x.__before_begin()->__next_ = nullptr;
552}
553
554template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000555inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000556__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
557 const allocator_type& __a)
558 : __before_begin_(__begin_node(), __node_allocator(__a))
559{
560 if (__alloc() == __x.__alloc())
561 {
562 __before_begin()->__next_ = __x.__before_begin()->__next_;
563 __x.__before_begin()->__next_ = nullptr;
564 }
565}
566
Eric Fiselier99f2c002017-04-16 04:02:01 +0000567#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000568
569template <class _Tp, class _Alloc>
570__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
571{
572 clear();
573}
574
575template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000576inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000577void
578__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000579#if _LIBCPP_STD_VER >= 14
580 _NOEXCEPT
581#else
582 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
583 __is_nothrow_swappable<__node_allocator>::value)
584#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000585{
Marshall Clowe3fbe142015-07-13 20:04:56 +0000586 __swap_allocator(__alloc(), __x.__alloc(),
587 integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
Howard Hinnantce48a112011-06-30 21:18:19 +0000588 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000589 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
590}
591
592template <class _Tp, class _Alloc>
593void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000594__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000595{
596 __node_allocator& __a = __alloc();
597 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
598 {
599 __node_pointer __next = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000600 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000601 __node_traits::deallocate(__a, __p, 1);
602 __p = __next;
603 }
604 __before_begin()->__next_ = nullptr;
605}
606
Marshall Clowb5d34aa2015-02-18 17:24:08 +0000607template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000608class _LIBCPP_TEMPLATE_VIS forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000609 : private __forward_list_base<_Tp, _Alloc>
610{
611 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnant91a47502011-06-03 16:20:53 +0000612 typedef typename base::__node_allocator __node_allocator;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000613 typedef typename base::__node __node;
614 typedef typename base::__node_traits __node_traits;
615 typedef typename base::__node_pointer __node_pointer;
616 typedef typename base::__begin_node_pointer __begin_node_pointer;
Howard Hinnant91a47502011-06-03 16:20:53 +0000617
Howard Hinnant3e519522010-05-11 19:42:16 +0000618public:
619 typedef _Tp value_type;
620 typedef _Alloc allocator_type;
621
Marshall Clow94f89ae2015-11-26 01:24:04 +0000622 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
623 "Allocator::value_type must be same type as value_type");
624
Howard Hinnant3e519522010-05-11 19:42:16 +0000625 typedef value_type& reference;
626 typedef const value_type& const_reference;
627 typedef typename allocator_traits<allocator_type>::pointer pointer;
628 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
629 typedef typename allocator_traits<allocator_type>::size_type size_type;
630 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
631
632 typedef typename base::iterator iterator;
633 typedef typename base::const_iterator const_iterator;
634
Howard Hinnant91a47502011-06-03 16:20:53 +0000635 _LIBCPP_INLINE_VISIBILITY
636 forward_list()
637 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
638 {} // = default;
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000639 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000640 explicit forward_list(const allocator_type& __a);
641 explicit forward_list(size_type __n);
Marshall Clowfb829762013-09-08 19:11:51 +0000642#if _LIBCPP_STD_VER > 11
643 explicit forward_list(size_type __n, const allocator_type& __a);
644#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000645 forward_list(size_type __n, const value_type& __v);
646 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
647 template <class _InputIterator>
648 forward_list(_InputIterator __f, _InputIterator __l,
649 typename enable_if<
650 __is_input_iterator<_InputIterator>::value
651 >::type* = nullptr);
652 template <class _InputIterator>
653 forward_list(_InputIterator __f, _InputIterator __l,
654 const allocator_type& __a,
655 typename enable_if<
656 __is_input_iterator<_InputIterator>::value
657 >::type* = nullptr);
658 forward_list(const forward_list& __x);
659 forward_list(const forward_list& __x, const allocator_type& __a);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000660
661 forward_list& operator=(const forward_list& __x);
662
663#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant0af133f2010-09-21 22:55:27 +0000664 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000665 forward_list(forward_list&& __x)
666 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000667 : base(_VSTD::move(__x)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000668 forward_list(forward_list&& __x, const allocator_type& __a);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000669
Howard Hinnant3e519522010-05-11 19:42:16 +0000670 forward_list(initializer_list<value_type> __il);
671 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
672
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000673 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000674 forward_list& operator=(forward_list&& __x)
675 _NOEXCEPT_(
676 __node_traits::propagate_on_container_move_assignment::value &&
677 is_nothrow_move_assignable<allocator_type>::value);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000678
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000680 forward_list& operator=(initializer_list<value_type> __il);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000681
682 _LIBCPP_INLINE_VISIBILITY
683 void assign(initializer_list<value_type> __il);
684#endif // _LIBCPP_CXX03_LANG
685
686 // ~forward_list() = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000687
688 template <class _InputIterator>
689 typename enable_if
690 <
691 __is_input_iterator<_InputIterator>::value,
692 void
693 >::type
694 assign(_InputIterator __f, _InputIterator __l);
695 void assign(size_type __n, const value_type& __v);
Howard Hinnant3e519522010-05-11 19:42:16 +0000696
Howard Hinnant0af133f2010-09-21 22:55:27 +0000697 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000698 allocator_type get_allocator() const _NOEXCEPT
699 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000700
Howard Hinnant0af133f2010-09-21 22:55:27 +0000701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000702 iterator begin() _NOEXCEPT
703 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000705 const_iterator begin() const _NOEXCEPT
706 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000707 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000708 iterator end() _NOEXCEPT
709 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000711 const_iterator end() const _NOEXCEPT
712 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000713
Howard Hinnant0af133f2010-09-21 22:55:27 +0000714 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000715 const_iterator cbegin() const _NOEXCEPT
716 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000717 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000718 const_iterator cend() const _NOEXCEPT
719 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000720
Howard Hinnant0af133f2010-09-21 22:55:27 +0000721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000722 iterator before_begin() _NOEXCEPT
723 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000725 const_iterator before_begin() const _NOEXCEPT
726 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000727 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000728 const_iterator cbefore_begin() const _NOEXCEPT
729 {return const_iterator(base::__before_begin());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000730
Howard Hinnant0af133f2010-09-21 22:55:27 +0000731 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000732 bool empty() const _NOEXCEPT
733 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000734 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier55b31b4e2016-11-23 01:18:56 +0000735 size_type max_size() const _NOEXCEPT {
736 return std::min<size_type>(
737 __node_traits::max_size(base::__alloc()),
738 numeric_limits<difference_type>::max());
739 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000740
Howard Hinnant0af133f2010-09-21 22:55:27 +0000741 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000742 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000743 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000744 const_reference front() const {return base::__before_begin()->__next_->__value_;}
745
Eric Fiselier99f2c002017-04-16 04:02:01 +0000746#ifndef _LIBCPP_CXX03_LANG
Marshall Clow63b560b2017-01-24 23:09:12 +0000747#if _LIBCPP_STD_VER > 14
Eric Fiselier0e411642016-07-21 03:20:17 +0000748 template <class... _Args> reference emplace_front(_Args&&... __args);
Marshall Clow63b560b2017-01-24 23:09:12 +0000749#else
750 template <class... _Args> void emplace_front(_Args&&... __args);
751#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000752 void push_front(value_type&& __v);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000753#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000754 void push_front(const value_type& __v);
755
756 void pop_front();
757
Eric Fiselier99f2c002017-04-16 04:02:01 +0000758#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000759 template <class... _Args>
760 iterator emplace_after(const_iterator __p, _Args&&... __args);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000761
Howard Hinnant3e519522010-05-11 19:42:16 +0000762 iterator insert_after(const_iterator __p, value_type&& __v);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000763 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
764 {return insert_after(__p, __il.begin(), __il.end());}
765#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000766 iterator insert_after(const_iterator __p, const value_type& __v);
767 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
768 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000769 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000770 typename enable_if
771 <
772 __is_input_iterator<_InputIterator>::value,
773 iterator
774 >::type
775 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000776
Howard Hinnant3db88032010-08-21 20:58:44 +0000777 iterator erase_after(const_iterator __p);
778 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000779
Howard Hinnant0af133f2010-09-21 22:55:27 +0000780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000781 void swap(forward_list& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000782#if _LIBCPP_STD_VER >= 14
783 _NOEXCEPT
784#else
Howard Hinnant91a47502011-06-03 16:20:53 +0000785 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
786 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000787#endif
Howard Hinnant91a47502011-06-03 16:20:53 +0000788 {base::swap(__x);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000789
790 void resize(size_type __n);
791 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000792 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000793 void clear() _NOEXCEPT {base::clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000794
Eric Fiselier99f2c002017-04-16 04:02:01 +0000795#ifndef _LIBCPP_CXX03_LANG
Howard Hinnanteb92df72011-01-27 21:00:35 +0000796 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000797 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000798 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000799 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000800 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000801 void splice_after(const_iterator __p, forward_list&& __x,
802 const_iterator __f, const_iterator __l);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000803#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000804 void splice_after(const_iterator __p, forward_list& __x);
805 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
806 void splice_after(const_iterator __p, forward_list& __x,
807 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000808 void remove(const value_type& __v);
809 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000810 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000811 void unique() {unique(__equal_to<value_type>());}
812 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000813#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant0af133f2010-09-21 22:55:27 +0000814 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000815 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
816 template <class _Compare>
817 _LIBCPP_INLINE_VISIBILITY
818 void merge(forward_list&& __x, _Compare __comp)
Howard Hinnantce48a112011-06-30 21:18:19 +0000819 {merge(__x, _VSTD::move(__comp));}
Eric Fiselier99f2c002017-04-16 04:02:01 +0000820#endif // _LIBCPP_CXX03_LANG
Howard Hinnant0af133f2010-09-21 22:55:27 +0000821 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000822 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
823 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000824 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000825 void sort() {sort(__less<value_type>());}
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000826 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000827 void reverse() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000828
829private:
Howard Hinnant3e519522010-05-11 19:42:16 +0000830
Eric Fiselier99f2c002017-04-16 04:02:01 +0000831#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant91a47502011-06-03 16:20:53 +0000832 void __move_assign(forward_list& __x, true_type)
833 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000834 void __move_assign(forward_list& __x, false_type);
Eric Fiselier99f2c002017-04-16 04:02:01 +0000835#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000836
837 template <class _Compare>
838 static
839 __node_pointer
840 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
841
842 template <class _Compare>
843 static
844 __node_pointer
845 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
846};
847
848template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000849inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000850forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
851 : base(__a)
852{
853}
854
855template <class _Tp, class _Alloc>
856forward_list<_Tp, _Alloc>::forward_list(size_type __n)
857{
858 if (__n > 0)
859 {
860 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +0000861 typedef __allocator_destructor<__node_allocator> _Dp;
862 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000863 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
864 __p = __p->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +0000865 {
866 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000867 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000868 __h->__next_ = nullptr;
869 __p->__next_ = __h.release();
870 }
871 }
872}
873
Marshall Clowfb829762013-09-08 19:11:51 +0000874#if _LIBCPP_STD_VER > 11
875template <class _Tp, class _Alloc>
Eric Fiselier572e6de2016-12-03 01:21:40 +0000876forward_list<_Tp, _Alloc>::forward_list(size_type __n,
877 const allocator_type& __base_alloc)
878 : base ( __base_alloc )
Marshall Clowfb829762013-09-08 19:11:51 +0000879{
880 if (__n > 0)
881 {
882 __node_allocator& __a = base::__alloc();
883 typedef __allocator_destructor<__node_allocator> _Dp;
884 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000885 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
886 __p = __p->__next_as_begin())
Marshall Clowfb829762013-09-08 19:11:51 +0000887 {
888 __h.reset(__node_traits::allocate(__a, 1));
889 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
890 __h->__next_ = nullptr;
891 __p->__next_ = __h.release();
892 }
893 }
894}
895#endif
896
Howard Hinnant3e519522010-05-11 19:42:16 +0000897template <class _Tp, class _Alloc>
898forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
899{
900 insert_after(cbefore_begin(), __n, __v);
901}
902
903template <class _Tp, class _Alloc>
904forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
905 const allocator_type& __a)
906 : base(__a)
907{
908 insert_after(cbefore_begin(), __n, __v);
909}
910
911template <class _Tp, class _Alloc>
912template <class _InputIterator>
913forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
914 typename enable_if<
915 __is_input_iterator<_InputIterator>::value
916 >::type*)
917{
918 insert_after(cbefore_begin(), __f, __l);
919}
920
921template <class _Tp, class _Alloc>
922template <class _InputIterator>
923forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
924 const allocator_type& __a,
925 typename enable_if<
926 __is_input_iterator<_InputIterator>::value
927 >::type*)
928 : base(__a)
929{
930 insert_after(cbefore_begin(), __f, __l);
931}
932
933template <class _Tp, class _Alloc>
934forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
935 : base(allocator_type(
936 __node_traits::select_on_container_copy_construction(__x.__alloc())
937 )
938 )
939{
940 insert_after(cbefore_begin(), __x.begin(), __x.end());
941}
942
943template <class _Tp, class _Alloc>
944forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
945 const allocator_type& __a)
946 : base(__a)
947{
948 insert_after(cbefore_begin(), __x.begin(), __x.end());
949}
950
Eric Fiselier99f2c002017-04-16 04:02:01 +0000951template <class _Tp, class _Alloc>
952forward_list<_Tp, _Alloc>&
953forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
954{
955 if (this != &__x)
956 {
957 base::__copy_assign_alloc(__x);
958 assign(__x.begin(), __x.end());
959 }
960 return *this;
961}
Howard Hinnant3e519522010-05-11 19:42:16 +0000962
Eric Fiselier99f2c002017-04-16 04:02:01 +0000963#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +0000964template <class _Tp, class _Alloc>
965forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
966 const allocator_type& __a)
Howard Hinnantce48a112011-06-30 21:18:19 +0000967 : base(_VSTD::move(__x), __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000968{
969 if (base::__alloc() != __x.__alloc())
970 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000971 typedef move_iterator<iterator> _Ip;
972 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +0000973 }
974}
975
Howard Hinnant3e519522010-05-11 19:42:16 +0000976template <class _Tp, class _Alloc>
977forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
978{
979 insert_after(cbefore_begin(), __il.begin(), __il.end());
980}
981
982template <class _Tp, class _Alloc>
983forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
984 const allocator_type& __a)
985 : base(__a)
986{
987 insert_after(cbefore_begin(), __il.begin(), __il.end());
988}
989
Howard Hinnant3e519522010-05-11 19:42:16 +0000990template <class _Tp, class _Alloc>
991void
992forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000993 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000994{
995 clear();
996 base::__move_assign_alloc(__x);
997 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
998 __x.__before_begin()->__next_ = nullptr;
999}
1000
1001template <class _Tp, class _Alloc>
1002void
1003forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
1004{
1005 if (base::__alloc() == __x.__alloc())
1006 __move_assign(__x, true_type());
1007 else
1008 {
Howard Hinnantc003db12011-11-29 18:15:50 +00001009 typedef move_iterator<iterator> _Ip;
1010 assign(_Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +00001011 }
1012}
1013
1014template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001015inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001016forward_list<_Tp, _Alloc>&
1017forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +00001018 _NOEXCEPT_(
1019 __node_traits::propagate_on_container_move_assignment::value &&
1020 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00001021{
1022 __move_assign(__x, integral_constant<bool,
1023 __node_traits::propagate_on_container_move_assignment::value>());
1024 return *this;
1025}
1026
Howard Hinnant3e519522010-05-11 19:42:16 +00001027template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001028inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001029forward_list<_Tp, _Alloc>&
1030forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
1031{
1032 assign(__il.begin(), __il.end());
1033 return *this;
1034}
1035
Eric Fiselier99f2c002017-04-16 04:02:01 +00001036#endif // _LIBCPP_CXX03_LANG
Howard Hinnant54976f22011-08-12 21:56:02 +00001037
Howard Hinnant3e519522010-05-11 19:42:16 +00001038template <class _Tp, class _Alloc>
1039template <class _InputIterator>
1040typename enable_if
1041<
1042 __is_input_iterator<_InputIterator>::value,
1043 void
1044>::type
1045forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
1046{
1047 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +00001048 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001049 iterator __e = end();
Eric Fiselier910285b2014-10-27 19:28:20 +00001050 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
Howard Hinnant3e519522010-05-11 19:42:16 +00001051 *__j = *__f;
1052 if (__j == __e)
1053 insert_after(__i, __f, __l);
1054 else
1055 erase_after(__i, __e);
1056}
1057
1058template <class _Tp, class _Alloc>
1059void
1060forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
1061{
1062 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +00001063 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001064 iterator __e = end();
1065 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1066 *__j = __v;
1067 if (__j == __e)
1068 insert_after(__i, __n, __v);
1069 else
1070 erase_after(__i, __e);
1071}
1072
Eric Fiselier99f2c002017-04-16 04:02:01 +00001073#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant54976f22011-08-12 21:56:02 +00001074
Howard Hinnant3e519522010-05-11 19:42:16 +00001075template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001076inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001077void
1078forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1079{
1080 assign(__il.begin(), __il.end());
1081}
1082
Howard Hinnant3e519522010-05-11 19:42:16 +00001083template <class _Tp, class _Alloc>
1084template <class... _Args>
Marshall Clow63b560b2017-01-24 23:09:12 +00001085#if _LIBCPP_STD_VER > 14
Eric Fiselier0e411642016-07-21 03:20:17 +00001086typename forward_list<_Tp, _Alloc>::reference
Marshall Clow63b560b2017-01-24 23:09:12 +00001087#else
1088void
1089#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001090forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1091{
1092 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001093 typedef __allocator_destructor<__node_allocator> _Dp;
1094 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001095 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1096 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001097 __h->__next_ = base::__before_begin()->__next_;
1098 base::__before_begin()->__next_ = __h.release();
Marshall Clow63b560b2017-01-24 23:09:12 +00001099#if _LIBCPP_STD_VER > 14
Eric Fiselier0e411642016-07-21 03:20:17 +00001100 return base::__before_begin()->__next_->__value_;
Marshall Clow63b560b2017-01-24 23:09:12 +00001101#endif
Howard Hinnant3e519522010-05-11 19:42:16 +00001102}
1103
1104template <class _Tp, class _Alloc>
1105void
1106forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1107{
1108 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001109 typedef __allocator_destructor<__node_allocator> _Dp;
1110 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001111 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001112 __h->__next_ = base::__before_begin()->__next_;
1113 base::__before_begin()->__next_ = __h.release();
1114}
1115
Eric Fiselier99f2c002017-04-16 04:02:01 +00001116#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001117
1118template <class _Tp, class _Alloc>
1119void
1120forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1121{
1122 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001123 typedef __allocator_destructor<__node_allocator> _Dp;
1124 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001125 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001126 __h->__next_ = base::__before_begin()->__next_;
1127 base::__before_begin()->__next_ = __h.release();
1128}
1129
1130template <class _Tp, class _Alloc>
1131void
1132forward_list<_Tp, _Alloc>::pop_front()
1133{
1134 __node_allocator& __a = base::__alloc();
1135 __node_pointer __p = base::__before_begin()->__next_;
1136 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001137 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001138 __node_traits::deallocate(__a, __p, 1);
1139}
1140
Eric Fiselier99f2c002017-04-16 04:02:01 +00001141#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001142
1143template <class _Tp, class _Alloc>
1144template <class... _Args>
1145typename forward_list<_Tp, _Alloc>::iterator
1146forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1147{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001148 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001149 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001150 typedef __allocator_destructor<__node_allocator> _Dp;
1151 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001152 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1153 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001154 __h->__next_ = __r->__next_;
1155 __r->__next_ = __h.release();
1156 return iterator(__r->__next_);
1157}
1158
1159template <class _Tp, class _Alloc>
1160typename forward_list<_Tp, _Alloc>::iterator
1161forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1162{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001163 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001164 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001165 typedef __allocator_destructor<__node_allocator> _Dp;
1166 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001167 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001168 __h->__next_ = __r->__next_;
1169 __r->__next_ = __h.release();
1170 return iterator(__r->__next_);
1171}
1172
Eric Fiselier99f2c002017-04-16 04:02:01 +00001173#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3e519522010-05-11 19:42:16 +00001174
1175template <class _Tp, class _Alloc>
1176typename forward_list<_Tp, _Alloc>::iterator
1177forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1178{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001179 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001180 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001181 typedef __allocator_destructor<__node_allocator> _Dp;
1182 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001183 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001184 __h->__next_ = __r->__next_;
1185 __r->__next_ = __h.release();
1186 return iterator(__r->__next_);
1187}
1188
1189template <class _Tp, class _Alloc>
1190typename forward_list<_Tp, _Alloc>::iterator
1191forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1192 const value_type& __v)
1193{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001194 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001195 if (__n > 0)
1196 {
1197 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001198 typedef __allocator_destructor<__node_allocator> _Dp;
1199 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001200 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001201 __node_pointer __first = __h.release();
1202 __node_pointer __last = __first;
1203#ifndef _LIBCPP_NO_EXCEPTIONS
1204 try
1205 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001206#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001207 for (--__n; __n != 0; --__n, __last = __last->__next_)
1208 {
1209 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001210 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001211 __last->__next_ = __h.release();
1212 }
1213#ifndef _LIBCPP_NO_EXCEPTIONS
1214 }
1215 catch (...)
1216 {
1217 while (__first != nullptr)
1218 {
1219 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001220 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001221 __node_traits::deallocate(__a, __first, 1);
1222 __first = __next;
1223 }
1224 throw;
1225 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001226#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001227 __last->__next_ = __r->__next_;
1228 __r->__next_ = __first;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001229 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnant3e519522010-05-11 19:42:16 +00001230 }
1231 return iterator(__r);
1232}
1233
1234template <class _Tp, class _Alloc>
1235template <class _InputIterator>
1236typename enable_if
1237<
1238 __is_input_iterator<_InputIterator>::value,
1239 typename forward_list<_Tp, _Alloc>::iterator
1240>::type
1241forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1242 _InputIterator __f, _InputIterator __l)
1243{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001244 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001245 if (__f != __l)
1246 {
1247 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001248 typedef __allocator_destructor<__node_allocator> _Dp;
1249 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001250 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001251 __node_pointer __first = __h.release();
1252 __node_pointer __last = __first;
1253#ifndef _LIBCPP_NO_EXCEPTIONS
1254 try
1255 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001256#endif // _LIBCPP_NO_EXCEPTIONS
Eric Fiselier910285b2014-10-27 19:28:20 +00001257 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001258 {
1259 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001260 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001261 __last->__next_ = __h.release();
1262 }
1263#ifndef _LIBCPP_NO_EXCEPTIONS
1264 }
1265 catch (...)
1266 {
1267 while (__first != nullptr)
1268 {
1269 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001270 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001271 __node_traits::deallocate(__a, __first, 1);
1272 __first = __next;
1273 }
1274 throw;
1275 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001276#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001277 __last->__next_ = __r->__next_;
1278 __r->__next_ = __first;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001279 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnant3e519522010-05-11 19:42:16 +00001280 }
1281 return iterator(__r);
1282}
1283
1284template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001285typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001286forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1287{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001288 __begin_node_pointer __p = __f.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001289 __node_pointer __n = __p->__next_;
1290 __p->__next_ = __n->__next_;
1291 __node_allocator& __a = base::__alloc();
Howard Hinnantce48a112011-06-30 21:18:19 +00001292 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001293 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001294 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001295}
1296
1297template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001298typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001299forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1300{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001301 __node_pointer __e = __l.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001302 if (__f != __l)
1303 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001304 __begin_node_pointer __bp = __f.__get_begin();
1305
1306 __node_pointer __n = __bp->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001307 if (__n != __e)
1308 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001309 __bp->__next_ = __e;
Howard Hinnant3e519522010-05-11 19:42:16 +00001310 __node_allocator& __a = base::__alloc();
1311 do
1312 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001313 __node_pointer __tmp = __n->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001314 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001315 __node_traits::deallocate(__a, __n, 1);
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001316 __n = __tmp;
Howard Hinnant3e519522010-05-11 19:42:16 +00001317 } while (__n != __e);
1318 }
1319 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001320 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001321}
1322
1323template <class _Tp, class _Alloc>
1324void
1325forward_list<_Tp, _Alloc>::resize(size_type __n)
1326{
1327 size_type __sz = 0;
1328 iterator __p = before_begin();
1329 iterator __i = begin();
1330 iterator __e = end();
1331 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1332 ;
1333 if (__i != __e)
1334 erase_after(__p, __e);
1335 else
1336 {
1337 __n -= __sz;
1338 if (__n > 0)
1339 {
1340 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001341 typedef __allocator_destructor<__node_allocator> _Dp;
1342 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001343 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1344 __ptr = __ptr->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001345 {
1346 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001347 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001348 __h->__next_ = nullptr;
1349 __ptr->__next_ = __h.release();
1350 }
1351 }
1352 }
1353}
1354
1355template <class _Tp, class _Alloc>
1356void
1357forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1358{
1359 size_type __sz = 0;
1360 iterator __p = before_begin();
1361 iterator __i = begin();
1362 iterator __e = end();
1363 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1364 ;
1365 if (__i != __e)
1366 erase_after(__p, __e);
1367 else
1368 {
1369 __n -= __sz;
1370 if (__n > 0)
1371 {
1372 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001373 typedef __allocator_destructor<__node_allocator> _Dp;
1374 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001375 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1376 __ptr = __ptr->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001377 {
1378 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001379 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001380 __h->__next_ = nullptr;
1381 __ptr->__next_ = __h.release();
1382 }
1383 }
1384 }
1385}
1386
1387template <class _Tp, class _Alloc>
1388void
1389forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001390 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001391{
1392 if (!__x.empty())
1393 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001394 if (__p.__get_begin()->__next_ != nullptr)
Howard Hinnant3e519522010-05-11 19:42:16 +00001395 {
1396 const_iterator __lm1 = __x.before_begin();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001397 while (__lm1.__get_begin()->__next_ != nullptr)
Howard Hinnant3e519522010-05-11 19:42:16 +00001398 ++__lm1;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001399 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001400 }
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001401 __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
Howard Hinnant8a27ba82013-06-24 17:17:28 +00001402 __x.__before_begin()->__next_ = nullptr;
Howard Hinnant3e519522010-05-11 19:42:16 +00001403 }
1404}
1405
1406template <class _Tp, class _Alloc>
1407void
1408forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Eric Fiselierfd838222016-12-23 23:37:52 +00001409 forward_list& /*__other*/,
Howard Hinnant3e519522010-05-11 19:42:16 +00001410 const_iterator __i)
1411{
Howard Hinnantce48a112011-06-30 21:18:19 +00001412 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001413 if (__p != __i && __p != __lm1)
1414 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001415 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
1416 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1417 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001418 }
1419}
1420
1421template <class _Tp, class _Alloc>
1422void
1423forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Eric Fiselierfd838222016-12-23 23:37:52 +00001424 forward_list& /*__other*/,
Howard Hinnant3e519522010-05-11 19:42:16 +00001425 const_iterator __f, const_iterator __l)
1426{
1427 if (__f != __l && __p != __f)
1428 {
1429 const_iterator __lm1 = __f;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001430 while (__lm1.__get_begin()->__next_ != __l.__get_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001431 ++__lm1;
1432 if (__f != __lm1)
1433 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001434 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1435 __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
1436 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001437 }
1438 }
1439}
1440
Eric Fiselier99f2c002017-04-16 04:02:01 +00001441#ifndef _LIBCPP_CXX03_LANG
Howard Hinnanteb92df72011-01-27 21:00:35 +00001442
1443template <class _Tp, class _Alloc>
1444inline _LIBCPP_INLINE_VISIBILITY
1445void
1446forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1447 forward_list&& __x)
1448{
1449 splice_after(__p, __x);
1450}
1451
1452template <class _Tp, class _Alloc>
1453inline _LIBCPP_INLINE_VISIBILITY
1454void
1455forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1456 forward_list&& __x,
1457 const_iterator __i)
1458{
1459 splice_after(__p, __x, __i);
1460}
1461
1462template <class _Tp, class _Alloc>
1463inline _LIBCPP_INLINE_VISIBILITY
1464void
1465forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1466 forward_list&& __x,
1467 const_iterator __f, const_iterator __l)
1468{
1469 splice_after(__p, __x, __f, __l);
1470}
1471
Eric Fiselier99f2c002017-04-16 04:02:01 +00001472#endif // _LIBCPP_CXX03_LANG
Howard Hinnanteb92df72011-01-27 21:00:35 +00001473
Howard Hinnant3e519522010-05-11 19:42:16 +00001474template <class _Tp, class _Alloc>
1475void
1476forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1477{
Marshall Clow99d2df92014-08-08 15:58:00 +00001478 forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
Howard Hinnant3e519522010-05-11 19:42:16 +00001479 iterator __e = end();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001480 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnant3e519522010-05-11 19:42:16 +00001481 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001482 if (__i.__get_begin()->__next_->__value_ == __v)
Howard Hinnant3e519522010-05-11 19:42:16 +00001483 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001484 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001485 for (; __j != __e && *__j == __v; ++__j)
1486 ;
Marshall Clowc8528b52014-10-18 11:03:33 +00001487 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
Howard Hinnant3e519522010-05-11 19:42:16 +00001488 if (__j == __e)
1489 break;
1490 __i = __j;
1491 }
1492 else
1493 ++__i;
1494 }
1495}
1496
1497template <class _Tp, class _Alloc>
1498template <class _Predicate>
1499void
1500forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1501{
1502 iterator __e = end();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001503 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnant3e519522010-05-11 19:42:16 +00001504 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001505 if (__pred(__i.__get_begin()->__next_->__value_))
Howard Hinnant3e519522010-05-11 19:42:16 +00001506 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001507 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001508 for (; __j != __e && __pred(*__j); ++__j)
1509 ;
1510 erase_after(__i, __j);
1511 if (__j == __e)
1512 break;
1513 __i = __j;
1514 }
1515 else
1516 ++__i;
1517 }
1518}
1519
1520template <class _Tp, class _Alloc>
1521template <class _BinaryPredicate>
1522void
1523forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1524{
1525 for (iterator __i = begin(), __e = end(); __i != __e;)
1526 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001527 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001528 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1529 ;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001530 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
Howard Hinnant3e519522010-05-11 19:42:16 +00001531 erase_after(__i, __j);
1532 __i = __j;
1533 }
1534}
1535
1536template <class _Tp, class _Alloc>
1537template <class _Compare>
1538void
Howard Hinnant3e519522010-05-11 19:42:16 +00001539forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001540{
1541 if (this != &__x)
1542 {
1543 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1544 __x.__before_begin()->__next_,
1545 __comp);
1546 __x.__before_begin()->__next_ = nullptr;
1547 }
1548}
1549
1550template <class _Tp, class _Alloc>
1551template <class _Compare>
1552typename forward_list<_Tp, _Alloc>::__node_pointer
1553forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1554 _Compare& __comp)
1555{
1556 if (__f1 == nullptr)
1557 return __f2;
1558 if (__f2 == nullptr)
1559 return __f1;
1560 __node_pointer __r;
1561 if (__comp(__f2->__value_, __f1->__value_))
1562 {
1563 __node_pointer __t = __f2;
1564 while (__t->__next_ != nullptr &&
1565 __comp(__t->__next_->__value_, __f1->__value_))
1566 __t = __t->__next_;
1567 __r = __f2;
1568 __f2 = __t->__next_;
1569 __t->__next_ = __f1;
1570 }
1571 else
1572 __r = __f1;
1573 __node_pointer __p = __f1;
1574 __f1 = __f1->__next_;
1575 while (__f1 != nullptr && __f2 != nullptr)
1576 {
1577 if (__comp(__f2->__value_, __f1->__value_))
1578 {
1579 __node_pointer __t = __f2;
1580 while (__t->__next_ != nullptr &&
1581 __comp(__t->__next_->__value_, __f1->__value_))
1582 __t = __t->__next_;
1583 __p->__next_ = __f2;
1584 __f2 = __t->__next_;
1585 __t->__next_ = __f1;
1586 }
1587 __p = __f1;
1588 __f1 = __f1->__next_;
1589 }
1590 if (__f2 != nullptr)
1591 __p->__next_ = __f2;
1592 return __r;
1593}
1594
1595template <class _Tp, class _Alloc>
1596template <class _Compare>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001597inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001598void
1599forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1600{
1601 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnantce48a112011-06-30 21:18:19 +00001602 _VSTD::distance(begin(), end()), __comp);
Howard Hinnant3e519522010-05-11 19:42:16 +00001603}
1604
1605template <class _Tp, class _Alloc>
1606template <class _Compare>
1607typename forward_list<_Tp, _Alloc>::__node_pointer
1608forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1609 _Compare& __comp)
1610{
1611 switch (__sz)
1612 {
1613 case 0:
1614 case 1:
1615 return __f1;
1616 case 2:
1617 if (__comp(__f1->__next_->__value_, __f1->__value_))
1618 {
1619 __node_pointer __t = __f1->__next_;
1620 __t->__next_ = __f1;
1621 __f1->__next_ = nullptr;
1622 __f1 = __t;
1623 }
1624 return __f1;
1625 }
1626 difference_type __sz1 = __sz / 2;
1627 difference_type __sz2 = __sz - __sz1;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001628 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001629 __node_pointer __f2 = __t->__next_;
1630 __t->__next_ = nullptr;
1631 return __merge(__sort(__f1, __sz1, __comp),
1632 __sort(__f2, __sz2, __comp), __comp);
1633}
1634
1635template <class _Tp, class _Alloc>
1636void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001637forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001638{
1639 __node_pointer __p = base::__before_begin()->__next_;
1640 if (__p != nullptr)
1641 {
1642 __node_pointer __f = __p->__next_;
1643 __p->__next_ = nullptr;
1644 while (__f != nullptr)
1645 {
1646 __node_pointer __t = __f->__next_;
1647 __f->__next_ = __p;
1648 __p = __f;
1649 __f = __t;
1650 }
1651 base::__before_begin()->__next_ = __p;
1652 }
1653}
1654
1655template <class _Tp, class _Alloc>
1656bool operator==(const forward_list<_Tp, _Alloc>& __x,
1657 const forward_list<_Tp, _Alloc>& __y)
1658{
Howard Hinnantc003db12011-11-29 18:15:50 +00001659 typedef forward_list<_Tp, _Alloc> _Cp;
1660 typedef typename _Cp::const_iterator _Ip;
1661 _Ip __ix = __x.begin();
1662 _Ip __ex = __x.end();
1663 _Ip __iy = __y.begin();
1664 _Ip __ey = __y.end();
Howard Hinnant3e519522010-05-11 19:42:16 +00001665 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1666 if (!(*__ix == *__iy))
1667 return false;
1668 return (__ix == __ex) == (__iy == __ey);
1669}
1670
1671template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001672inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001673bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1674 const forward_list<_Tp, _Alloc>& __y)
1675{
1676 return !(__x == __y);
1677}
1678
1679template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001680inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001681bool operator< (const forward_list<_Tp, _Alloc>& __x,
1682 const forward_list<_Tp, _Alloc>& __y)
1683{
Howard Hinnantce48a112011-06-30 21:18:19 +00001684 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnant3e519522010-05-11 19:42:16 +00001685 __y.begin(), __y.end());
1686}
1687
1688template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001689inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001690bool operator> (const forward_list<_Tp, _Alloc>& __x,
1691 const forward_list<_Tp, _Alloc>& __y)
1692{
1693 return __y < __x;
1694}
1695
1696template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001697inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001698bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1699 const forward_list<_Tp, _Alloc>& __y)
1700{
1701 return !(__x < __y);
1702}
1703
1704template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001705inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001706bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1707 const forward_list<_Tp, _Alloc>& __y)
1708{
1709 return !(__y < __x);
1710}
1711
1712template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001713inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001714void
1715swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +00001716 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001717{
1718 __x.swap(__y);
1719}
1720
1721_LIBCPP_END_NAMESPACE_STD
1722
Eric Fiseliera016efb2017-05-31 22:07:49 +00001723_LIBCPP_POP_MACROS
1724
Howard Hinnant3e519522010-05-11 19:42:16 +00001725#endif // _LIBCPP_FORWARD_LIST