blob: 41b4b468d455cb0865add98d718c0e1446ba18fb [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
Eric Fiselier0e411642016-07-21 03:20:17 +000090 template <class... Args> reference emplace_front(Args&&... args);
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>
170
171#include <initializer_list>
172#include <memory>
173#include <limits>
174#include <iterator>
175#include <algorithm>
176
Howard Hinnantab4f4382011-11-29 16:45:27 +0000177#include <__undef_min_max>
178
Howard Hinnant073458b2011-10-17 20:05:10 +0000179#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +0000180#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000181#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000182
183_LIBCPP_BEGIN_NAMESPACE_STD
184
Howard Hinnantce534202011-06-14 19:58:17 +0000185template <class _Tp, class _VoidPtr> struct __forward_list_node;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000186template <class _NodePtr> struct __forward_begin_node;
187
188
189template <class>
190struct __forward_list_node_value_type;
191
192template <class _Tp, class _VoidPtr>
193struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
194 typedef _Tp type;
195};
196
197template <class _NodePtr>
198struct __forward_node_traits {
199
200 typedef typename remove_cv<
201 typename pointer_traits<_NodePtr>::element_type>::type __node;
202 typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
203 typedef _NodePtr __node_pointer;
204 typedef __forward_begin_node<_NodePtr> __begin_node;
205 typedef typename __rebind_pointer<_NodePtr, __begin_node>::type
206 __begin_node_pointer;
207 typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer;
208
209#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
210 typedef __begin_node_pointer __iter_node_pointer;
211#else
212 typedef typename conditional<
213 is_pointer<__void_pointer>::value,
214 __begin_node_pointer,
215 __node_pointer
216 >::type __iter_node_pointer;
217#endif
218
219 typedef typename conditional<
220 is_same<__iter_node_pointer, __node_pointer>::value,
221 __begin_node_pointer,
222 __node_pointer
223 >::type __non_iter_node_pointer;
224
225 _LIBCPP_INLINE_VISIBILITY
226 static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) {
227 return __p;
228 }
229 _LIBCPP_INLINE_VISIBILITY
230 static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
231 return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
232 }
233};
Howard Hinnant3e519522010-05-11 19:42:16 +0000234
235template <class _NodePtr>
236struct __forward_begin_node
237{
Howard Hinnant3e519522010-05-11 19:42:16 +0000238 typedef _NodePtr pointer;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000239 typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000240
241 pointer __next_;
242
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000243 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
244
245 _LIBCPP_INLINE_VISIBILITY
246 __begin_node_pointer __next_as_begin() const {
247 return static_cast<__begin_node_pointer>(__next_);
248 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000249};
250
251template <class _Tp, class _VoidPtr>
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000252struct _LIBCPP_HIDDEN __begin_node_of
253{
Eric Fiselier934b0922015-12-30 21:52:00 +0000254 typedef __forward_begin_node<
255 typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
256 > type;
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000257};
258
259template <class _Tp, class _VoidPtr>
260struct __forward_list_node
261 : public __begin_node_of<_Tp, _VoidPtr>::type
Howard Hinnant3e519522010-05-11 19:42:16 +0000262{
263 typedef _Tp value_type;
264
265 value_type __value_;
266};
267
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000268
Marshall Clowb5d34aa2015-02-18 17:24:08 +0000269template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY forward_list;
Howard Hinnantf0544c22013-08-12 18:38:34 +0000270template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000271
272template <class _NodePtr>
Howard Hinnantf0544c22013-08-12 18:38:34 +0000273class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000274{
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000275 typedef __forward_node_traits<_NodePtr> __traits;
276 typedef typename __traits::__node_pointer __node_pointer;
277 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
278 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
279 typedef typename __traits::__void_pointer __void_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000280
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000281 __iter_node_pointer __ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +0000282
Howard Hinnant0af133f2010-09-21 22:55:27 +0000283 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000284 __begin_node_pointer __get_begin() const {
285 return static_cast<__begin_node_pointer>(
286 static_cast<__void_pointer>(__ptr_));
287 }
288 _LIBCPP_INLINE_VISIBILITY
289 __node_pointer __get_unsafe_node_pointer() const {
290 return static_cast<__node_pointer>(
291 static_cast<__void_pointer>(__ptr_));
292 }
293
294 _LIBCPP_INLINE_VISIBILITY
295 explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
296
297 _LIBCPP_INLINE_VISIBILITY
298 explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
299 : __ptr_(__traits::__as_iter_node(__p)) {}
300
301 _LIBCPP_INLINE_VISIBILITY
302 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
303 : __ptr_(__traits::__as_iter_node(__p)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000304
Howard Hinnantf0544c22013-08-12 18:38:34 +0000305 template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list;
306 template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000307
308public:
309 typedef forward_iterator_tag iterator_category;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000310 typedef typename __traits::__node_value_type value_type;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000311 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000312 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000313 difference_type;
Eric Fiselier934b0922015-12-30 21:52:00 +0000314 typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000315
Howard Hinnant0af133f2010-09-21 22:55:27 +0000316 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000317 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000318
Howard Hinnant0af133f2010-09-21 22:55:27 +0000319 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000320 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000321 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000322 pointer operator->() const {
323 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
324 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000325
Howard Hinnant0af133f2010-09-21 22:55:27 +0000326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000327 __forward_list_iterator& operator++()
328 {
Eric Fiselier4de5f982016-01-27 00:49:20 +0000329 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000330 return *this;
331 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000333 __forward_list_iterator operator++(int)
334 {
335 __forward_list_iterator __t(*this);
336 ++(*this);
337 return __t;
338 }
339
Howard Hinnant0af133f2010-09-21 22:55:27 +0000340 friend _LIBCPP_INLINE_VISIBILITY
341 bool operator==(const __forward_list_iterator& __x,
342 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000343 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000344 friend _LIBCPP_INLINE_VISIBILITY
345 bool operator!=(const __forward_list_iterator& __x,
346 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000347 {return !(__x == __y);}
348};
349
350template <class _NodeConstPtr>
Howard Hinnantf0544c22013-08-12 18:38:34 +0000351class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000352{
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000353 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
354 typedef _NodeConstPtr _NodePtr;
Howard Hinnant3e519522010-05-11 19:42:16 +0000355
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000356 typedef __forward_node_traits<_NodePtr> __traits;
357 typedef typename __traits::__node __node;
358 typedef typename __traits::__node_pointer __node_pointer;
359 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
360 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
361 typedef typename __traits::__void_pointer __void_pointer;
362
363 __iter_node_pointer __ptr_;
364
365 __begin_node_pointer __get_begin() const {
366 return static_cast<__begin_node_pointer>(
367 static_cast<__void_pointer>(__ptr_));
368 }
369 __node_pointer __get_unsafe_node_pointer() const {
370 return static_cast<__node_pointer>(
371 static_cast<__void_pointer>(__ptr_));
372 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000373
Howard Hinnant0af133f2010-09-21 22:55:27 +0000374 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000375 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
376 : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000377
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000378 _LIBCPP_INLINE_VISIBILITY
379 explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
380 : __ptr_(__traits::__as_iter_node(__p)) {}
381
382 _LIBCPP_INLINE_VISIBILITY
383 explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
384 : __ptr_(__traits::__as_iter_node(__p)) {}
385
Howard Hinnant3e519522010-05-11 19:42:16 +0000386
387 template<class, class> friend class forward_list;
388
389public:
390 typedef forward_iterator_tag iterator_category;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000391 typedef typename __traits::__node_value_type value_type;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000392 typedef const value_type& reference;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000393 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000394 difference_type;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000395 typedef typename __rebind_pointer<__node_pointer, const value_type>::type
396 pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000397
Howard Hinnant0af133f2010-09-21 22:55:27 +0000398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000399 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000401 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000402 : __ptr_(__p.__ptr_) {}
403
Howard Hinnant0af133f2010-09-21 22:55:27 +0000404 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000405 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000406 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000407 pointer operator->() const {return pointer_traits<pointer>::pointer_to(
408 __get_unsafe_node_pointer()->__value_);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000409
Howard Hinnant0af133f2010-09-21 22:55:27 +0000410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000411 __forward_list_const_iterator& operator++()
412 {
Eric Fiselier4de5f982016-01-27 00:49:20 +0000413 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000414 return *this;
415 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000417 __forward_list_const_iterator operator++(int)
418 {
419 __forward_list_const_iterator __t(*this);
420 ++(*this);
421 return __t;
422 }
423
Howard Hinnant0af133f2010-09-21 22:55:27 +0000424 friend _LIBCPP_INLINE_VISIBILITY
425 bool operator==(const __forward_list_const_iterator& __x,
426 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000427 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000428 friend _LIBCPP_INLINE_VISIBILITY
429 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000430 const __forward_list_const_iterator& __y)
431 {return !(__x == __y);}
432};
433
434template <class _Tp, class _Alloc>
435class __forward_list_base
436{
437protected:
438 typedef _Tp value_type;
439 typedef _Alloc allocator_type;
440
Peter Collingbourne09df4a62014-02-05 01:44:17 +0000441 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
442 typedef __forward_list_node<value_type, void_pointer> __node;
443 typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
Marshall Clow1f508012015-04-07 05:21:38 +0000444 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000445 typedef allocator_traits<__node_allocator> __node_traits;
446 typedef typename __node_traits::pointer __node_pointer;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000447
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000448 typedef typename __rebind_alloc_helper<
449 allocator_traits<allocator_type>, __begin_node
450 >::type __begin_node_allocator;
451 typedef typename allocator_traits<__begin_node_allocator>::pointer
452 __begin_node_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000453
454 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
455
Howard Hinnant0af133f2010-09-21 22:55:27 +0000456 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000457 __begin_node_pointer __before_begin() _NOEXCEPT
458 {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000459 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000460 __begin_node_pointer __before_begin() const _NOEXCEPT
461 {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));}
Howard Hinnant3e519522010-05-11 19:42:16 +0000462
Howard Hinnant0af133f2010-09-21 22:55:27 +0000463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000464 __node_allocator& __alloc() _NOEXCEPT
465 {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000467 const __node_allocator& __alloc() const _NOEXCEPT
468 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000469
470 typedef __forward_list_iterator<__node_pointer> iterator;
Howard Hinnant8a27ba82013-06-24 17:17:28 +0000471 typedef __forward_list_const_iterator<__node_pointer> const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000472
Howard Hinnant0af133f2010-09-21 22:55:27 +0000473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000474 __forward_list_base()
Howard Hinnant91a47502011-06-03 16:20:53 +0000475 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000476 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000478 __forward_list_base(const allocator_type& __a)
479 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
480
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000481#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000482public:
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000484 __forward_list_base(__forward_list_base&& __x)
485 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000486 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000487 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000488#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000489
490private:
491 __forward_list_base(const __forward_list_base&);
492 __forward_list_base& operator=(const __forward_list_base&);
Howard Hinnant3e519522010-05-11 19:42:16 +0000493
Howard Hinnant91a47502011-06-03 16:20:53 +0000494public:
Howard Hinnant3e519522010-05-11 19:42:16 +0000495 ~__forward_list_base();
496
Howard Hinnant91a47502011-06-03 16:20:53 +0000497protected:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000498 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000499 void __copy_assign_alloc(const __forward_list_base& __x)
500 {__copy_assign_alloc(__x, integral_constant<bool,
501 __node_traits::propagate_on_container_copy_assignment::value>());}
502
Howard Hinnant0af133f2010-09-21 22:55:27 +0000503 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000504 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000505 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
506 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000507 {__move_assign_alloc(__x, integral_constant<bool,
508 __node_traits::propagate_on_container_move_assignment::value>());}
509
Howard Hinnant91a47502011-06-03 16:20:53 +0000510public:
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000512 void swap(__forward_list_base& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000513#if _LIBCPP_STD_VER >= 14
514 _NOEXCEPT;
515#else
516 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
517 __is_nothrow_swappable<__node_allocator>::value);
518#endif
Howard Hinnant91a47502011-06-03 16:20:53 +0000519protected:
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000520 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000521
522private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000524 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000526 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
527 {
528 if (__alloc() != __x.__alloc())
529 clear();
530 __alloc() = __x.__alloc();
531 }
532
Howard Hinnant0af133f2010-09-21 22:55:27 +0000533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000534 void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
535 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000537 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000538 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000539 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000540};
541
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000543
544template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000545inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000546__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000547 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000548 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnant3e519522010-05-11 19:42:16 +0000549{
550 __x.__before_begin()->__next_ = nullptr;
551}
552
553template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000554inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000555__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
556 const allocator_type& __a)
557 : __before_begin_(__begin_node(), __node_allocator(__a))
558{
559 if (__alloc() == __x.__alloc())
560 {
561 __before_begin()->__next_ = __x.__before_begin()->__next_;
562 __x.__before_begin()->__next_ = nullptr;
563 }
564}
565
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000566#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000567
568template <class _Tp, class _Alloc>
569__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
570{
571 clear();
572}
573
574template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000575inline
Howard Hinnant3e519522010-05-11 19:42:16 +0000576void
577__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Marshall Clowe3fbe142015-07-13 20:04:56 +0000578#if _LIBCPP_STD_VER >= 14
579 _NOEXCEPT
580#else
581 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
582 __is_nothrow_swappable<__node_allocator>::value)
583#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000584{
Marshall Clowe3fbe142015-07-13 20:04:56 +0000585 __swap_allocator(__alloc(), __x.__alloc(),
586 integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
Howard Hinnantce48a112011-06-30 21:18:19 +0000587 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000588 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
589}
590
591template <class _Tp, class _Alloc>
592void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000593__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000594{
595 __node_allocator& __a = __alloc();
596 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
597 {
598 __node_pointer __next = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000599 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000600 __node_traits::deallocate(__a, __p, 1);
601 __p = __next;
602 }
603 __before_begin()->__next_ = nullptr;
604}
605
Marshall Clowb5d34aa2015-02-18 17:24:08 +0000606template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
Howard Hinnantf0544c22013-08-12 18:38:34 +0000607class _LIBCPP_TYPE_VIS_ONLY forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000608 : private __forward_list_base<_Tp, _Alloc>
609{
610 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnant91a47502011-06-03 16:20:53 +0000611 typedef typename base::__node_allocator __node_allocator;
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000612 typedef typename base::__node __node;
613 typedef typename base::__node_traits __node_traits;
614 typedef typename base::__node_pointer __node_pointer;
615 typedef typename base::__begin_node_pointer __begin_node_pointer;
Howard Hinnant91a47502011-06-03 16:20:53 +0000616
Howard Hinnant3e519522010-05-11 19:42:16 +0000617public:
618 typedef _Tp value_type;
619 typedef _Alloc allocator_type;
620
Marshall Clow94f89ae2015-11-26 01:24:04 +0000621 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
622 "Allocator::value_type must be same type as value_type");
623
Howard Hinnant3e519522010-05-11 19:42:16 +0000624 typedef value_type& reference;
625 typedef const value_type& const_reference;
626 typedef typename allocator_traits<allocator_type>::pointer pointer;
627 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
628 typedef typename allocator_traits<allocator_type>::size_type size_type;
629 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
630
631 typedef typename base::iterator iterator;
632 typedef typename base::const_iterator const_iterator;
633
Howard Hinnant91a47502011-06-03 16:20:53 +0000634 _LIBCPP_INLINE_VISIBILITY
635 forward_list()
636 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
637 {} // = default;
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000638 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000639 explicit forward_list(const allocator_type& __a);
640 explicit forward_list(size_type __n);
Marshall Clowfb829762013-09-08 19:11:51 +0000641#if _LIBCPP_STD_VER > 11
642 explicit forward_list(size_type __n, const allocator_type& __a);
643#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000644 forward_list(size_type __n, const value_type& __v);
645 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
646 template <class _InputIterator>
647 forward_list(_InputIterator __f, _InputIterator __l,
648 typename enable_if<
649 __is_input_iterator<_InputIterator>::value
650 >::type* = nullptr);
651 template <class _InputIterator>
652 forward_list(_InputIterator __f, _InputIterator __l,
653 const allocator_type& __a,
654 typename enable_if<
655 __is_input_iterator<_InputIterator>::value
656 >::type* = nullptr);
657 forward_list(const forward_list& __x);
658 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000659#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000660 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000661 forward_list(forward_list&& __x)
662 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000663 : base(_VSTD::move(__x)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000664 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000665#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54976f22011-08-12 21:56:02 +0000666#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000667 forward_list(initializer_list<value_type> __il);
668 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
Howard Hinnant54976f22011-08-12 21:56:02 +0000669#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000670
671 // ~forward_list() = default;
672
673 forward_list& operator=(const forward_list& __x);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000674#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000675 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000676 forward_list& operator=(forward_list&& __x)
677 _NOEXCEPT_(
678 __node_traits::propagate_on_container_move_assignment::value &&
679 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000680#endif
Howard Hinnant54976f22011-08-12 21:56:02 +0000681#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000682 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000683 forward_list& operator=(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000684#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000685
686 template <class _InputIterator>
687 typename enable_if
688 <
689 __is_input_iterator<_InputIterator>::value,
690 void
691 >::type
692 assign(_InputIterator __f, _InputIterator __l);
693 void assign(size_type __n, const value_type& __v);
Howard Hinnant54976f22011-08-12 21:56:02 +0000694#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +0000695 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000696 void assign(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000697#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000698
Howard Hinnant0af133f2010-09-21 22:55:27 +0000699 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000700 allocator_type get_allocator() const _NOEXCEPT
701 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000702
Howard Hinnant0af133f2010-09-21 22:55:27 +0000703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000704 iterator begin() _NOEXCEPT
705 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000707 const_iterator begin() const _NOEXCEPT
708 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000710 iterator end() _NOEXCEPT
711 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000713 const_iterator end() const _NOEXCEPT
714 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000715
Howard Hinnant0af133f2010-09-21 22:55:27 +0000716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000717 const_iterator cbegin() 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 const_iterator cend() const _NOEXCEPT
721 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000722
Howard Hinnant0af133f2010-09-21 22:55:27 +0000723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000724 iterator before_begin() _NOEXCEPT
725 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000727 const_iterator before_begin() const _NOEXCEPT
728 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000730 const_iterator cbefore_begin() const _NOEXCEPT
731 {return const_iterator(base::__before_begin());}
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 bool empty() const _NOEXCEPT
735 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000737 size_type max_size() const _NOEXCEPT
738 {return numeric_limits<size_type>::max();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000739
Howard Hinnant0af133f2010-09-21 22:55:27 +0000740 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000741 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000743 const_reference front() const {return base::__before_begin()->__next_->__value_;}
744
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000745#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
746#ifndef _LIBCPP_HAS_NO_VARIADICS
Eric Fiselier0e411642016-07-21 03:20:17 +0000747 template <class... _Args> reference emplace_front(_Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000748#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000749 void push_front(value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000750#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000751 void push_front(const value_type& __v);
752
753 void pop_front();
754
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000755#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
756#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000757 template <class... _Args>
758 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000759#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000760 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000761#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000762 iterator insert_after(const_iterator __p, const value_type& __v);
763 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
764 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000766 typename enable_if
767 <
768 __is_input_iterator<_InputIterator>::value,
769 iterator
770 >::type
771 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnant54976f22011-08-12 21:56:02 +0000772#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000773 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
774 {return insert_after(__p, __il.begin(), __il.end());}
Howard Hinnant54976f22011-08-12 21:56:02 +0000775#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
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
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000795#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
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);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000803#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
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);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000813#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
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));}
Howard Hinnanteb92df72011-01-27 21:00:35 +0000820#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
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
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000831#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
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);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000835#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
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>
876forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a)
877 : base ( __a )
878{
879 if (__n > 0)
880 {
881 __node_allocator& __a = base::__alloc();
882 typedef __allocator_destructor<__node_allocator> _Dp;
883 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +0000884 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
885 __p = __p->__next_as_begin())
Marshall Clowfb829762013-09-08 19:11:51 +0000886 {
887 __h.reset(__node_traits::allocate(__a, 1));
888 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
889 __h->__next_ = nullptr;
890 __p->__next_ = __h.release();
891 }
892 }
893}
894#endif
895
Howard Hinnant3e519522010-05-11 19:42:16 +0000896template <class _Tp, class _Alloc>
897forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
898{
899 insert_after(cbefore_begin(), __n, __v);
900}
901
902template <class _Tp, class _Alloc>
903forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
904 const allocator_type& __a)
905 : base(__a)
906{
907 insert_after(cbefore_begin(), __n, __v);
908}
909
910template <class _Tp, class _Alloc>
911template <class _InputIterator>
912forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
913 typename enable_if<
914 __is_input_iterator<_InputIterator>::value
915 >::type*)
916{
917 insert_after(cbefore_begin(), __f, __l);
918}
919
920template <class _Tp, class _Alloc>
921template <class _InputIterator>
922forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
923 const allocator_type& __a,
924 typename enable_if<
925 __is_input_iterator<_InputIterator>::value
926 >::type*)
927 : base(__a)
928{
929 insert_after(cbefore_begin(), __f, __l);
930}
931
932template <class _Tp, class _Alloc>
933forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
934 : base(allocator_type(
935 __node_traits::select_on_container_copy_construction(__x.__alloc())
936 )
937 )
938{
939 insert_after(cbefore_begin(), __x.begin(), __x.end());
940}
941
942template <class _Tp, class _Alloc>
943forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
944 const allocator_type& __a)
945 : base(__a)
946{
947 insert_after(cbefore_begin(), __x.begin(), __x.end());
948}
949
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000950#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000951
952template <class _Tp, class _Alloc>
953forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
954 const allocator_type& __a)
Howard Hinnantce48a112011-06-30 21:18:19 +0000955 : base(_VSTD::move(__x), __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000956{
957 if (base::__alloc() != __x.__alloc())
958 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000959 typedef move_iterator<iterator> _Ip;
960 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +0000961 }
962}
963
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000964#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000965
Howard Hinnant54976f22011-08-12 21:56:02 +0000966#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
967
Howard Hinnant3e519522010-05-11 19:42:16 +0000968template <class _Tp, class _Alloc>
969forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
970{
971 insert_after(cbefore_begin(), __il.begin(), __il.end());
972}
973
974template <class _Tp, class _Alloc>
975forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
976 const allocator_type& __a)
977 : base(__a)
978{
979 insert_after(cbefore_begin(), __il.begin(), __il.end());
980}
981
Howard Hinnant54976f22011-08-12 21:56:02 +0000982#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
983
Howard Hinnant3e519522010-05-11 19:42:16 +0000984template <class _Tp, class _Alloc>
985forward_list<_Tp, _Alloc>&
986forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
987{
988 if (this != &__x)
989 {
990 base::__copy_assign_alloc(__x);
991 assign(__x.begin(), __x.end());
992 }
993 return *this;
994}
995
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000996#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000997
998template <class _Tp, class _Alloc>
999void
1000forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +00001001 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00001002{
1003 clear();
1004 base::__move_assign_alloc(__x);
1005 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
1006 __x.__before_begin()->__next_ = nullptr;
1007}
1008
1009template <class _Tp, class _Alloc>
1010void
1011forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
1012{
1013 if (base::__alloc() == __x.__alloc())
1014 __move_assign(__x, true_type());
1015 else
1016 {
Howard Hinnantc003db12011-11-29 18:15:50 +00001017 typedef move_iterator<iterator> _Ip;
1018 assign(_Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +00001019 }
1020}
1021
1022template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001023inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001024forward_list<_Tp, _Alloc>&
1025forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +00001026 _NOEXCEPT_(
1027 __node_traits::propagate_on_container_move_assignment::value &&
1028 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +00001029{
1030 __move_assign(__x, integral_constant<bool,
1031 __node_traits::propagate_on_container_move_assignment::value>());
1032 return *this;
1033}
1034
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001035#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001036
Howard Hinnant54976f22011-08-12 21:56:02 +00001037#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1038
Howard Hinnant3e519522010-05-11 19:42:16 +00001039template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001040inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001041forward_list<_Tp, _Alloc>&
1042forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
1043{
1044 assign(__il.begin(), __il.end());
1045 return *this;
1046}
1047
Howard Hinnant54976f22011-08-12 21:56:02 +00001048#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1049
Howard Hinnant3e519522010-05-11 19:42:16 +00001050template <class _Tp, class _Alloc>
1051template <class _InputIterator>
1052typename enable_if
1053<
1054 __is_input_iterator<_InputIterator>::value,
1055 void
1056>::type
1057forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
1058{
1059 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +00001060 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001061 iterator __e = end();
Eric Fiselier910285b2014-10-27 19:28:20 +00001062 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
Howard Hinnant3e519522010-05-11 19:42:16 +00001063 *__j = *__f;
1064 if (__j == __e)
1065 insert_after(__i, __f, __l);
1066 else
1067 erase_after(__i, __e);
1068}
1069
1070template <class _Tp, class _Alloc>
1071void
1072forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
1073{
1074 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +00001075 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001076 iterator __e = end();
1077 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1078 *__j = __v;
1079 if (__j == __e)
1080 insert_after(__i, __n, __v);
1081 else
1082 erase_after(__i, __e);
1083}
1084
Howard Hinnant54976f22011-08-12 21:56:02 +00001085#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1086
Howard Hinnant3e519522010-05-11 19:42:16 +00001087template <class _Tp, class _Alloc>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001088inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001089void
1090forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1091{
1092 assign(__il.begin(), __il.end());
1093}
1094
Howard Hinnant54976f22011-08-12 21:56:02 +00001095#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1096
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001097#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1098#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +00001099
1100template <class _Tp, class _Alloc>
1101template <class... _Args>
Eric Fiselier0e411642016-07-21 03:20:17 +00001102typename forward_list<_Tp, _Alloc>::reference
Howard Hinnant3e519522010-05-11 19:42:16 +00001103forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1104{
1105 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001106 typedef __allocator_destructor<__node_allocator> _Dp;
1107 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001108 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1109 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001110 __h->__next_ = base::__before_begin()->__next_;
1111 base::__before_begin()->__next_ = __h.release();
Eric Fiselier0e411642016-07-21 03:20:17 +00001112 return base::__before_begin()->__next_->__value_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001113}
1114
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001115#endif // _LIBCPP_HAS_NO_VARIADICS
1116
Howard Hinnant3e519522010-05-11 19:42:16 +00001117template <class _Tp, class _Alloc>
1118void
1119forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1120{
1121 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001122 typedef __allocator_destructor<__node_allocator> _Dp;
1123 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001124 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001125 __h->__next_ = base::__before_begin()->__next_;
1126 base::__before_begin()->__next_ = __h.release();
1127}
1128
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001129#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001130
1131template <class _Tp, class _Alloc>
1132void
1133forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1134{
1135 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001136 typedef __allocator_destructor<__node_allocator> _Dp;
1137 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001138 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001139 __h->__next_ = base::__before_begin()->__next_;
1140 base::__before_begin()->__next_ = __h.release();
1141}
1142
1143template <class _Tp, class _Alloc>
1144void
1145forward_list<_Tp, _Alloc>::pop_front()
1146{
1147 __node_allocator& __a = base::__alloc();
1148 __node_pointer __p = base::__before_begin()->__next_;
1149 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001150 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001151 __node_traits::deallocate(__a, __p, 1);
1152}
1153
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001154#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1155#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +00001156
1157template <class _Tp, class _Alloc>
1158template <class... _Args>
1159typename forward_list<_Tp, _Alloc>::iterator
1160forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1161{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001162 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001163 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001164 typedef __allocator_destructor<__node_allocator> _Dp;
1165 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001166 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1167 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001168 __h->__next_ = __r->__next_;
1169 __r->__next_ = __h.release();
1170 return iterator(__r->__next_);
1171}
1172
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001173#endif // _LIBCPP_HAS_NO_VARIADICS
1174
Howard Hinnant3e519522010-05-11 19:42:16 +00001175template <class _Tp, class _Alloc>
1176typename forward_list<_Tp, _Alloc>::iterator
1177forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, 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_), _VSTD::move(__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
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001189#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001190
1191template <class _Tp, class _Alloc>
1192typename forward_list<_Tp, _Alloc>::iterator
1193forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1194{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001195 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001196 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001197 typedef __allocator_destructor<__node_allocator> _Dp;
1198 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001199 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001200 __h->__next_ = __r->__next_;
1201 __r->__next_ = __h.release();
1202 return iterator(__r->__next_);
1203}
1204
1205template <class _Tp, class _Alloc>
1206typename forward_list<_Tp, _Alloc>::iterator
1207forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1208 const value_type& __v)
1209{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001210 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001211 if (__n > 0)
1212 {
1213 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001214 typedef __allocator_destructor<__node_allocator> _Dp;
1215 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001216 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001217 __node_pointer __first = __h.release();
1218 __node_pointer __last = __first;
1219#ifndef _LIBCPP_NO_EXCEPTIONS
1220 try
1221 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001222#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001223 for (--__n; __n != 0; --__n, __last = __last->__next_)
1224 {
1225 __h.reset(__node_traits::allocate(__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 __last->__next_ = __h.release();
1228 }
1229#ifndef _LIBCPP_NO_EXCEPTIONS
1230 }
1231 catch (...)
1232 {
1233 while (__first != nullptr)
1234 {
1235 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001236 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001237 __node_traits::deallocate(__a, __first, 1);
1238 __first = __next;
1239 }
1240 throw;
1241 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001242#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001243 __last->__next_ = __r->__next_;
1244 __r->__next_ = __first;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001245 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnant3e519522010-05-11 19:42:16 +00001246 }
1247 return iterator(__r);
1248}
1249
1250template <class _Tp, class _Alloc>
1251template <class _InputIterator>
1252typename enable_if
1253<
1254 __is_input_iterator<_InputIterator>::value,
1255 typename forward_list<_Tp, _Alloc>::iterator
1256>::type
1257forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1258 _InputIterator __f, _InputIterator __l)
1259{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001260 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001261 if (__f != __l)
1262 {
1263 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001264 typedef __allocator_destructor<__node_allocator> _Dp;
1265 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001266 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001267 __node_pointer __first = __h.release();
1268 __node_pointer __last = __first;
1269#ifndef _LIBCPP_NO_EXCEPTIONS
1270 try
1271 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001272#endif // _LIBCPP_NO_EXCEPTIONS
Eric Fiselier910285b2014-10-27 19:28:20 +00001273 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001274 {
1275 __h.reset(__node_traits::allocate(__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 __last->__next_ = __h.release();
1278 }
1279#ifndef _LIBCPP_NO_EXCEPTIONS
1280 }
1281 catch (...)
1282 {
1283 while (__first != nullptr)
1284 {
1285 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001286 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001287 __node_traits::deallocate(__a, __first, 1);
1288 __first = __next;
1289 }
1290 throw;
1291 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001292#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001293 __last->__next_ = __r->__next_;
1294 __r->__next_ = __first;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001295 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnant3e519522010-05-11 19:42:16 +00001296 }
1297 return iterator(__r);
1298}
1299
1300template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001301typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001302forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1303{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001304 __begin_node_pointer __p = __f.__get_begin();
Howard Hinnant3e519522010-05-11 19:42:16 +00001305 __node_pointer __n = __p->__next_;
1306 __p->__next_ = __n->__next_;
1307 __node_allocator& __a = base::__alloc();
Howard Hinnantce48a112011-06-30 21:18:19 +00001308 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001309 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001310 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001311}
1312
1313template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001314typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001315forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1316{
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001317 __node_pointer __e = __l.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001318 if (__f != __l)
1319 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001320 __begin_node_pointer __bp = __f.__get_begin();
1321
1322 __node_pointer __n = __bp->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001323 if (__n != __e)
1324 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001325 __bp->__next_ = __e;
Howard Hinnant3e519522010-05-11 19:42:16 +00001326 __node_allocator& __a = base::__alloc();
1327 do
1328 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001329 __node_pointer __tmp = __n->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001330 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001331 __node_traits::deallocate(__a, __n, 1);
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001332 __n = __tmp;
Howard Hinnant3e519522010-05-11 19:42:16 +00001333 } while (__n != __e);
1334 }
1335 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001336 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001337}
1338
1339template <class _Tp, class _Alloc>
1340void
1341forward_list<_Tp, _Alloc>::resize(size_type __n)
1342{
1343 size_type __sz = 0;
1344 iterator __p = before_begin();
1345 iterator __i = begin();
1346 iterator __e = end();
1347 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1348 ;
1349 if (__i != __e)
1350 erase_after(__p, __e);
1351 else
1352 {
1353 __n -= __sz;
1354 if (__n > 0)
1355 {
1356 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001357 typedef __allocator_destructor<__node_allocator> _Dp;
1358 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001359 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1360 __ptr = __ptr->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001361 {
1362 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001363 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001364 __h->__next_ = nullptr;
1365 __ptr->__next_ = __h.release();
1366 }
1367 }
1368 }
1369}
1370
1371template <class _Tp, class _Alloc>
1372void
1373forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1374{
1375 size_type __sz = 0;
1376 iterator __p = before_begin();
1377 iterator __i = begin();
1378 iterator __e = end();
1379 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1380 ;
1381 if (__i != __e)
1382 erase_after(__p, __e);
1383 else
1384 {
1385 __n -= __sz;
1386 if (__n > 0)
1387 {
1388 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001389 typedef __allocator_destructor<__node_allocator> _Dp;
1390 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001391 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1392 __ptr = __ptr->__next_as_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001393 {
1394 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001395 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001396 __h->__next_ = nullptr;
1397 __ptr->__next_ = __h.release();
1398 }
1399 }
1400 }
1401}
1402
1403template <class _Tp, class _Alloc>
1404void
1405forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001406 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001407{
1408 if (!__x.empty())
1409 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001410 if (__p.__get_begin()->__next_ != nullptr)
Howard Hinnant3e519522010-05-11 19:42:16 +00001411 {
1412 const_iterator __lm1 = __x.before_begin();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001413 while (__lm1.__get_begin()->__next_ != nullptr)
Howard Hinnant3e519522010-05-11 19:42:16 +00001414 ++__lm1;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001415 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001416 }
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001417 __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
Howard Hinnant8a27ba82013-06-24 17:17:28 +00001418 __x.__before_begin()->__next_ = nullptr;
Howard Hinnant3e519522010-05-11 19:42:16 +00001419 }
1420}
1421
1422template <class _Tp, class _Alloc>
1423void
1424forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001425 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001426 const_iterator __i)
1427{
Howard Hinnantce48a112011-06-30 21:18:19 +00001428 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001429 if (__p != __i && __p != __lm1)
1430 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001431 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
1432 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1433 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001434 }
1435}
1436
1437template <class _Tp, class _Alloc>
1438void
1439forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001440 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001441 const_iterator __f, const_iterator __l)
1442{
1443 if (__f != __l && __p != __f)
1444 {
1445 const_iterator __lm1 = __f;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001446 while (__lm1.__get_begin()->__next_ != __l.__get_begin())
Howard Hinnant3e519522010-05-11 19:42:16 +00001447 ++__lm1;
1448 if (__f != __lm1)
1449 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001450 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1451 __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
1452 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001453 }
1454 }
1455}
1456
Howard Hinnanteb92df72011-01-27 21:00:35 +00001457#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1458
1459template <class _Tp, class _Alloc>
1460inline _LIBCPP_INLINE_VISIBILITY
1461void
1462forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1463 forward_list&& __x)
1464{
1465 splice_after(__p, __x);
1466}
1467
1468template <class _Tp, class _Alloc>
1469inline _LIBCPP_INLINE_VISIBILITY
1470void
1471forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1472 forward_list&& __x,
1473 const_iterator __i)
1474{
1475 splice_after(__p, __x, __i);
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 __f, const_iterator __l)
1484{
1485 splice_after(__p, __x, __f, __l);
1486}
1487
1488#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1489
Howard Hinnant3e519522010-05-11 19:42:16 +00001490template <class _Tp, class _Alloc>
1491void
1492forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1493{
Marshall Clow99d2df92014-08-08 15:58:00 +00001494 forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
Howard Hinnant3e519522010-05-11 19:42:16 +00001495 iterator __e = end();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001496 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnant3e519522010-05-11 19:42:16 +00001497 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001498 if (__i.__get_begin()->__next_->__value_ == __v)
Howard Hinnant3e519522010-05-11 19:42:16 +00001499 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001500 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001501 for (; __j != __e && *__j == __v; ++__j)
1502 ;
Marshall Clowc8528b52014-10-18 11:03:33 +00001503 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
Howard Hinnant3e519522010-05-11 19:42:16 +00001504 if (__j == __e)
1505 break;
1506 __i = __j;
1507 }
1508 else
1509 ++__i;
1510 }
1511}
1512
1513template <class _Tp, class _Alloc>
1514template <class _Predicate>
1515void
1516forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1517{
1518 iterator __e = end();
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001519 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnant3e519522010-05-11 19:42:16 +00001520 {
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001521 if (__pred(__i.__get_begin()->__next_->__value_))
Howard Hinnant3e519522010-05-11 19:42:16 +00001522 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001523 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001524 for (; __j != __e && __pred(*__j); ++__j)
1525 ;
1526 erase_after(__i, __j);
1527 if (__j == __e)
1528 break;
1529 __i = __j;
1530 }
1531 else
1532 ++__i;
1533 }
1534}
1535
1536template <class _Tp, class _Alloc>
1537template <class _BinaryPredicate>
1538void
1539forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1540{
1541 for (iterator __i = begin(), __e = end(); __i != __e;)
1542 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001543 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001544 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1545 ;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001546 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
Howard Hinnant3e519522010-05-11 19:42:16 +00001547 erase_after(__i, __j);
1548 __i = __j;
1549 }
1550}
1551
1552template <class _Tp, class _Alloc>
1553template <class _Compare>
1554void
Howard Hinnant3e519522010-05-11 19:42:16 +00001555forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001556{
1557 if (this != &__x)
1558 {
1559 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1560 __x.__before_begin()->__next_,
1561 __comp);
1562 __x.__before_begin()->__next_ = nullptr;
1563 }
1564}
1565
1566template <class _Tp, class _Alloc>
1567template <class _Compare>
1568typename forward_list<_Tp, _Alloc>::__node_pointer
1569forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1570 _Compare& __comp)
1571{
1572 if (__f1 == nullptr)
1573 return __f2;
1574 if (__f2 == nullptr)
1575 return __f1;
1576 __node_pointer __r;
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 __r = __f2;
1584 __f2 = __t->__next_;
1585 __t->__next_ = __f1;
1586 }
1587 else
1588 __r = __f1;
1589 __node_pointer __p = __f1;
1590 __f1 = __f1->__next_;
1591 while (__f1 != nullptr && __f2 != nullptr)
1592 {
1593 if (__comp(__f2->__value_, __f1->__value_))
1594 {
1595 __node_pointer __t = __f2;
1596 while (__t->__next_ != nullptr &&
1597 __comp(__t->__next_->__value_, __f1->__value_))
1598 __t = __t->__next_;
1599 __p->__next_ = __f2;
1600 __f2 = __t->__next_;
1601 __t->__next_ = __f1;
1602 }
1603 __p = __f1;
1604 __f1 = __f1->__next_;
1605 }
1606 if (__f2 != nullptr)
1607 __p->__next_ = __f2;
1608 return __r;
1609}
1610
1611template <class _Tp, class _Alloc>
1612template <class _Compare>
Evgeniy Stepanovcd31b432016-04-22 01:04:55 +00001613inline
Howard Hinnant3e519522010-05-11 19:42:16 +00001614void
1615forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1616{
1617 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnantce48a112011-06-30 21:18:19 +00001618 _VSTD::distance(begin(), end()), __comp);
Howard Hinnant3e519522010-05-11 19:42:16 +00001619}
1620
1621template <class _Tp, class _Alloc>
1622template <class _Compare>
1623typename forward_list<_Tp, _Alloc>::__node_pointer
1624forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1625 _Compare& __comp)
1626{
1627 switch (__sz)
1628 {
1629 case 0:
1630 case 1:
1631 return __f1;
1632 case 2:
1633 if (__comp(__f1->__next_->__value_, __f1->__value_))
1634 {
1635 __node_pointer __t = __f1->__next_;
1636 __t->__next_ = __f1;
1637 __f1->__next_ = nullptr;
1638 __f1 = __t;
1639 }
1640 return __f1;
1641 }
1642 difference_type __sz1 = __sz / 2;
1643 difference_type __sz2 = __sz - __sz1;
Eric Fiselier07b9cd32016-01-27 00:11:54 +00001644 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
Howard Hinnant3e519522010-05-11 19:42:16 +00001645 __node_pointer __f2 = __t->__next_;
1646 __t->__next_ = nullptr;
1647 return __merge(__sort(__f1, __sz1, __comp),
1648 __sort(__f2, __sz2, __comp), __comp);
1649}
1650
1651template <class _Tp, class _Alloc>
1652void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001653forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001654{
1655 __node_pointer __p = base::__before_begin()->__next_;
1656 if (__p != nullptr)
1657 {
1658 __node_pointer __f = __p->__next_;
1659 __p->__next_ = nullptr;
1660 while (__f != nullptr)
1661 {
1662 __node_pointer __t = __f->__next_;
1663 __f->__next_ = __p;
1664 __p = __f;
1665 __f = __t;
1666 }
1667 base::__before_begin()->__next_ = __p;
1668 }
1669}
1670
1671template <class _Tp, class _Alloc>
1672bool operator==(const forward_list<_Tp, _Alloc>& __x,
1673 const forward_list<_Tp, _Alloc>& __y)
1674{
Howard Hinnantc003db12011-11-29 18:15:50 +00001675 typedef forward_list<_Tp, _Alloc> _Cp;
1676 typedef typename _Cp::const_iterator _Ip;
1677 _Ip __ix = __x.begin();
1678 _Ip __ex = __x.end();
1679 _Ip __iy = __y.begin();
1680 _Ip __ey = __y.end();
Howard Hinnant3e519522010-05-11 19:42:16 +00001681 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1682 if (!(*__ix == *__iy))
1683 return false;
1684 return (__ix == __ex) == (__iy == __ey);
1685}
1686
1687template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001688inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001689bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1690 const forward_list<_Tp, _Alloc>& __y)
1691{
1692 return !(__x == __y);
1693}
1694
1695template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001696inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001697bool operator< (const forward_list<_Tp, _Alloc>& __x,
1698 const forward_list<_Tp, _Alloc>& __y)
1699{
Howard Hinnantce48a112011-06-30 21:18:19 +00001700 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnant3e519522010-05-11 19:42:16 +00001701 __y.begin(), __y.end());
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 +00001714bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1715 const forward_list<_Tp, _Alloc>& __y)
1716{
1717 return !(__x < __y);
1718}
1719
1720template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001721inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001722bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1723 const forward_list<_Tp, _Alloc>& __y)
1724{
1725 return !(__y < __x);
1726}
1727
1728template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001729inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001730void
1731swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +00001732 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001733{
1734 __x.swap(__y);
1735}
1736
1737_LIBCPP_END_NAMESPACE_STD
1738
1739#endif // _LIBCPP_FORWARD_LIST