blob: f344d2e1fe7b52747b054b6bc21e4be3e3e6efbb [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------- forward_list ---------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-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 Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +000037 forward_list()
38 noexcept(is_nothrow_default_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000039 explicit forward_list(const allocator_type& a);
40 explicit forward_list(size_type n);
Marshall Clowe00f53b2013-09-09 18:19:45 +000041 explicit forward_list(size_type n, const allocator_type& a); // C++14
Howard Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +000050 forward_list(forward_list&& x)
51 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-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 Hinnantb965fed2011-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 Hinnantbc8d3f92010-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 Hinnant8790cab2011-06-02 16:44:28 +000070 allocator_type get_allocator() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071
Howard Hinnant8790cab2011-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 Hinnantbc8d3f92010-05-11 19:42:16 +000076
Howard Hinnant8790cab2011-06-02 16:44:28 +000077 const_iterator cbegin() const noexcept;
78 const_iterator cend() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000079
Howard Hinnant8790cab2011-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 Hinnantbc8d3f92010-05-11 19:42:16 +000083
Howard Hinnant8790cab2011-06-02 16:44:28 +000084 bool empty() const noexcept;
85 size_type max_size() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000086
87 reference front();
88 const_reference front() const;
89
Eric Fiselier3816ef92016-07-21 03:20:17 +000090 template <class... Args> reference emplace_front(Args&&... args);
Howard Hinnantbc8d3f92010-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 Hinnant7a2523b2010-08-21 20:58:44 +0000106 iterator erase_after(const_iterator p);
107 iterator erase_after(const_iterator first, const_iterator last);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000108
Howard Hinnantb965fed2011-06-03 16:20:53 +0000109 void swap(forward_list& x)
Marshall Clow7d914d12015-07-13 20:04:56 +0000110 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000111
112 void resize(size_type n);
113 void resize(size_type n, const value_type& v);
Howard Hinnant8790cab2011-06-02 16:44:28 +0000114 void clear() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000115
Howard Hinnant99b2f762011-01-27 21:00:35 +0000116 void splice_after(const_iterator p, forward_list& x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000117 void splice_after(const_iterator p, forward_list&& x);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000118 void splice_after(const_iterator p, forward_list& x, const_iterator i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000119 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000120 void splice_after(const_iterator p, forward_list& x,
121 const_iterator first, const_iterator last);
Howard Hinnantbc8d3f92010-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 Hinnant99b2f762011-01-27 21:00:35 +0000128 void merge(forward_list& x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129 void merge(forward_list&& x);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000130 template <class Compare> void merge(forward_list& x, Compare comp);
Howard Hinnantbc8d3f92010-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 Hinnant8790cab2011-06-02 16:44:28 +0000134 void reverse() noexcept;
Howard Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +0000162 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
Howard Hinnantc5607272011-06-03 17:30:28 +0000163 noexcept(noexcept(x.swap(y)));
Howard Hinnantbc8d3f92010-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 Hinnant66c6f972011-11-29 16:45:27 +0000177#include <__undef_min_max>
178
Howard Hinnant08e17472011-10-17 20:05:10 +0000179#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000180#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000181#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000182
183_LIBCPP_BEGIN_NAMESPACE_STD
184
Howard Hinnant2b1b2d42011-06-14 19:58:17 +0000185template <class _Tp, class _VoidPtr> struct __forward_list_node;
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000234
235template <class _NodePtr>
236struct __forward_begin_node
237{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000238 typedef _NodePtr pointer;
Eric Fiselierde637db2016-01-27 00:11:54 +0000239 typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000240
241 pointer __next_;
242
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000249};
250
251template <class _Tp, class _VoidPtr>
Peter Collingbournea3dc8f32014-02-05 01:44:17 +0000252struct _LIBCPP_HIDDEN __begin_node_of
253{
Eric Fiselier5cf84e02015-12-30 21:52:00 +0000254 typedef __forward_begin_node<
255 typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
256 > type;
Peter Collingbournea3dc8f32014-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000262{
263 typedef _Tp value_type;
264
265 value_type __value_;
266};
267
Eric Fiselierde637db2016-01-27 00:11:54 +0000268
Marshall Clowceead9c2015-02-18 17:24:08 +0000269template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY forward_list;
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000270template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000271
272template <class _NodePtr>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000273class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274{
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000280
Eric Fiselierde637db2016-01-27 00:11:54 +0000281 __iter_node_pointer __ptr_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000282
Howard Hinnant42a63a72010-09-21 22:55:27 +0000283 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000304
Howard Hinnant0f678bd2013-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000307
308public:
309 typedef forward_iterator_tag iterator_category;
Eric Fiselierde637db2016-01-27 00:11:54 +0000310 typedef typename __traits::__node_value_type value_type;
Howard Hinnant81381a92013-06-24 17:17:28 +0000311 typedef value_type& reference;
Howard Hinnant324bb032010-08-22 00:02:43 +0000312 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000313 difference_type;
Eric Fiselier5cf84e02015-12-30 21:52:00 +0000314 typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000315
Howard Hinnant42a63a72010-09-21 22:55:27 +0000316 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000317 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000318
Howard Hinnant42a63a72010-09-21 22:55:27 +0000319 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-01-27 00:11:54 +0000320 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000321 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-01-27 00:11:54 +0000322 pointer operator->() const {
323 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
324 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000325
Howard Hinnant42a63a72010-09-21 22:55:27 +0000326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000327 __forward_list_iterator& operator++()
328 {
Eric Fiselierc778a6a2016-01-27 00:49:20 +0000329 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 return *this;
331 }
Howard Hinnant42a63a72010-09-21 22:55:27 +0000332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000343 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant42a63a72010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000347 {return !(__x == __y);}
348};
349
350template <class _NodeConstPtr>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000351class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000352{
Eric Fiselierde637db2016-01-27 00:11:54 +0000353 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
354 typedef _NodeConstPtr _NodePtr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000355
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000373
Howard Hinnant42a63a72010-09-21 22:55:27 +0000374 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-01-27 00:11:54 +0000375 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
376 : __ptr_(nullptr) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000377
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000386
387 template<class, class> friend class forward_list;
388
389public:
390 typedef forward_iterator_tag iterator_category;
Eric Fiselierde637db2016-01-27 00:11:54 +0000391 typedef typename __traits::__node_value_type value_type;
Howard Hinnant81381a92013-06-24 17:17:28 +0000392 typedef const value_type& reference;
Eric Fiselierde637db2016-01-27 00:11:54 +0000393 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000394 difference_type;
Eric Fiselierde637db2016-01-27 00:11:54 +0000395 typedef typename __rebind_pointer<__node_pointer, const value_type>::type
396 pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397
Howard Hinnant42a63a72010-09-21 22:55:27 +0000398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000399 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000401 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000402 : __ptr_(__p.__ptr_) {}
403
Howard Hinnant42a63a72010-09-21 22:55:27 +0000404 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-01-27 00:11:54 +0000405 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000406 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-01-27 00:11:54 +0000407 pointer operator->() const {return pointer_traits<pointer>::pointer_to(
408 __get_unsafe_node_pointer()->__value_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409
Howard Hinnant42a63a72010-09-21 22:55:27 +0000410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411 __forward_list_const_iterator& operator++()
412 {
Eric Fiselierc778a6a2016-01-27 00:49:20 +0000413 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414 return *this;
415 }
Howard Hinnant42a63a72010-09-21 22:55:27 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000427 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000428 friend _LIBCPP_INLINE_VISIBILITY
429 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnantbc8d3f92010-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 Collingbournea3dc8f32014-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 Clow66302c62015-04-07 05:21:38 +0000444 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000445 typedef allocator_traits<__node_allocator> __node_traits;
446 typedef typename __node_traits::pointer __node_pointer;
Howard Hinnant81381a92013-06-24 17:17:28 +0000447
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000453
454 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
455
Howard Hinnant42a63a72010-09-21 22:55:27 +0000456 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-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 Hinnant42a63a72010-09-21 22:55:27 +0000459 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierde637db2016-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000462
Howard Hinnant42a63a72010-09-21 22:55:27 +0000463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000464 __node_allocator& __alloc() _NOEXCEPT
465 {return __before_begin_.second();}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000467 const __node_allocator& __alloc() const _NOEXCEPT
468 {return __before_begin_.second();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000469
470 typedef __forward_list_iterator<__node_pointer> iterator;
Howard Hinnant81381a92013-06-24 17:17:28 +0000471 typedef __forward_list_const_iterator<__node_pointer> const_iterator;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000472
Howard Hinnant42a63a72010-09-21 22:55:27 +0000473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000474 __forward_list_base()
Howard Hinnantb965fed2011-06-03 16:20:53 +0000475 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000476 : __before_begin_(__begin_node()) {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478 __forward_list_base(const allocator_type& __a)
479 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
480
Howard Hinnant73d21a42010-09-04 23:28:19 +0000481#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantb965fed2011-06-03 16:20:53 +0000482public:
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000484 __forward_list_base(__forward_list_base&& __x)
485 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000486 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000487 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000488#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000493
Howard Hinnantb965fed2011-06-03 16:20:53 +0000494public:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000495 ~__forward_list_base();
496
Howard Hinnantb965fed2011-06-03 16:20:53 +0000497protected:
Howard Hinnant42a63a72010-09-21 22:55:27 +0000498 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000503 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000504 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000505 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
506 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000507 {__move_assign_alloc(__x, integral_constant<bool,
508 __node_traits::propagate_on_container_move_assignment::value>());}
509
Howard Hinnantb965fed2011-06-03 16:20:53 +0000510public:
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000512 void swap(__forward_list_base& __x)
Marshall Clow7d914d12015-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 Hinnantb965fed2011-06-03 16:20:53 +0000519protected:
Howard Hinnant8790cab2011-06-02 16:44:28 +0000520 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000521
522private:
Howard Hinnant42a63a72010-09-21 22:55:27 +0000523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000524 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000534 void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
535 {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000537 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000538 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000539 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000540};
541
Howard Hinnant73d21a42010-09-04 23:28:19 +0000542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000543
544template <class _Tp, class _Alloc>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000545inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000546__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000547 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000548 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000549{
550 __x.__before_begin()->__next_ = nullptr;
551}
552
553template <class _Tp, class _Alloc>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000554inline
Howard Hinnantbc8d3f92010-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 Hinnant73d21a42010-09-04 23:28:19 +0000566#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-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 Stepanov9341a8a2016-04-22 01:04:55 +0000575inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000576void
577__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Marshall Clow7d914d12015-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000584{
Marshall Clow7d914d12015-07-13 20:04:56 +0000585 __swap_allocator(__alloc(), __x.__alloc(),
586 integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
Howard Hinnant0949eed2011-06-30 21:18:19 +0000587 using _VSTD::swap;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000588 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
589}
590
591template <class _Tp, class _Alloc>
592void
Howard Hinnant8790cab2011-06-02 16:44:28 +0000593__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-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 Hinnant0949eed2011-06-30 21:18:19 +0000599 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000600 __node_traits::deallocate(__a, __p, 1);
601 __p = __next;
602 }
603 __before_begin()->__next_ = nullptr;
604}
605
Marshall Clowceead9c2015-02-18 17:24:08 +0000606template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000607class _LIBCPP_TYPE_VIS_ONLY forward_list
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000608 : private __forward_list_base<_Tp, _Alloc>
609{
610 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnantb965fed2011-06-03 16:20:53 +0000611 typedef typename base::__node_allocator __node_allocator;
Eric Fiselierde637db2016-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 Hinnantb965fed2011-06-03 16:20:53 +0000616
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000617public:
618 typedef _Tp value_type;
619 typedef _Alloc allocator_type;
620
Marshall Clow14ba0ad2015-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 Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +0000634 _LIBCPP_INLINE_VISIBILITY
635 forward_list()
636 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
637 {} // = default;
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000638 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000639 explicit forward_list(const allocator_type& __a);
640 explicit forward_list(size_type __n);
Marshall Clow955f2c82013-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 Hinnantbc8d3f92010-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 Hinnant73d21a42010-09-04 23:28:19 +0000659#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant42a63a72010-09-21 22:55:27 +0000660 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000661 forward_list(forward_list&& __x)
662 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000663 : base(_VSTD::move(__x)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000664 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000665#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnante3e32912011-08-12 21:56:02 +0000666#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnantbc8d3f92010-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 Hinnante3e32912011-08-12 21:56:02 +0000669#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000670
671 // ~forward_list() = default;
672
673 forward_list& operator=(const forward_list& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000674#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000675 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000680#endif
Howard Hinnante3e32912011-08-12 21:56:02 +0000681#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000682 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000683 forward_list& operator=(initializer_list<value_type> __il);
Howard Hinnante3e32912011-08-12 21:56:02 +0000684#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnantbc8d3f92010-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 Hinnante3e32912011-08-12 21:56:02 +0000694#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000695 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000696 void assign(initializer_list<value_type> __il);
Howard Hinnante3e32912011-08-12 21:56:02 +0000697#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000698
Howard Hinnant42a63a72010-09-21 22:55:27 +0000699 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000700 allocator_type get_allocator() const _NOEXCEPT
701 {return allocator_type(base::__alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000702
Howard Hinnant42a63a72010-09-21 22:55:27 +0000703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000704 iterator begin() _NOEXCEPT
705 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000707 const_iterator begin() const _NOEXCEPT
708 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000710 iterator end() _NOEXCEPT
711 {return iterator(nullptr);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000713 const_iterator end() const _NOEXCEPT
714 {return const_iterator(nullptr);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000715
Howard Hinnant42a63a72010-09-21 22:55:27 +0000716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000717 const_iterator cbegin() const _NOEXCEPT
718 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000720 const_iterator cend() const _NOEXCEPT
721 {return const_iterator(nullptr);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000722
Howard Hinnant42a63a72010-09-21 22:55:27 +0000723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000724 iterator before_begin() _NOEXCEPT
725 {return iterator(base::__before_begin());}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000727 const_iterator before_begin() const _NOEXCEPT
728 {return const_iterator(base::__before_begin());}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000730 const_iterator cbefore_begin() const _NOEXCEPT
731 {return const_iterator(base::__before_begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000732
Howard Hinnant42a63a72010-09-21 22:55:27 +0000733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000734 bool empty() const _NOEXCEPT
735 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000736 _LIBCPP_INLINE_VISIBILITY
Eric Fiselieref3060e2016-11-23 01:18:56 +0000737 size_type max_size() const _NOEXCEPT {
738 return std::min<size_type>(
739 __node_traits::max_size(base::__alloc()),
740 numeric_limits<difference_type>::max());
741 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000742
Howard Hinnant42a63a72010-09-21 22:55:27 +0000743 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000744 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000746 const_reference front() const {return base::__before_begin()->__next_->__value_;}
747
Howard Hinnant73d21a42010-09-04 23:28:19 +0000748#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
749#ifndef _LIBCPP_HAS_NO_VARIADICS
Eric Fiselier3816ef92016-07-21 03:20:17 +0000750 template <class... _Args> reference emplace_front(_Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000751#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000752 void push_front(value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000753#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000754 void push_front(const value_type& __v);
755
756 void pop_front();
757
Howard Hinnant73d21a42010-09-04 23:28:19 +0000758#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
759#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000760 template <class... _Args>
761 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000762#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000763 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000764#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000765 iterator insert_after(const_iterator __p, const value_type& __v);
766 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
767 template <class _InputIterator>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000769 typename enable_if
770 <
771 __is_input_iterator<_InputIterator>::value,
772 iterator
773 >::type
774 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnante3e32912011-08-12 21:56:02 +0000775#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000776 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
777 {return insert_after(__p, __il.begin(), __il.end());}
Howard Hinnante3e32912011-08-12 21:56:02 +0000778#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000779
Howard Hinnant7a2523b2010-08-21 20:58:44 +0000780 iterator erase_after(const_iterator __p);
781 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000782
Howard Hinnant42a63a72010-09-21 22:55:27 +0000783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000784 void swap(forward_list& __x)
Marshall Clow7d914d12015-07-13 20:04:56 +0000785#if _LIBCPP_STD_VER >= 14
786 _NOEXCEPT
787#else
Howard Hinnantb965fed2011-06-03 16:20:53 +0000788 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
789 __is_nothrow_swappable<__node_allocator>::value)
Marshall Clow7d914d12015-07-13 20:04:56 +0000790#endif
Howard Hinnantb965fed2011-06-03 16:20:53 +0000791 {base::swap(__x);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000792
793 void resize(size_type __n);
794 void resize(size_type __n, const value_type& __v);
Howard Hinnant42a63a72010-09-21 22:55:27 +0000795 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000796 void clear() _NOEXCEPT {base::clear();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000797
Howard Hinnant73d21a42010-09-04 23:28:19 +0000798#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99b2f762011-01-27 21:00:35 +0000799 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000800 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000802 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000803 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000804 void splice_after(const_iterator __p, forward_list&& __x,
805 const_iterator __f, const_iterator __l);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000806#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000807 void splice_after(const_iterator __p, forward_list& __x);
808 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
809 void splice_after(const_iterator __p, forward_list& __x,
810 const_iterator __f, const_iterator __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000811 void remove(const value_type& __v);
812 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant42a63a72010-09-21 22:55:27 +0000813 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000814 void unique() {unique(__equal_to<value_type>());}
815 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000816#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant42a63a72010-09-21 22:55:27 +0000817 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99b2f762011-01-27 21:00:35 +0000818 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
819 template <class _Compare>
820 _LIBCPP_INLINE_VISIBILITY
821 void merge(forward_list&& __x, _Compare __comp)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000822 {merge(__x, _VSTD::move(__comp));}
Howard Hinnant99b2f762011-01-27 21:00:35 +0000823#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant42a63a72010-09-21 22:55:27 +0000824 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000825 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
826 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant42a63a72010-09-21 22:55:27 +0000827 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000828 void sort() {sort(__less<value_type>());}
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000829 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
Howard Hinnant8790cab2011-06-02 16:44:28 +0000830 void reverse() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000831
832private:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000833
Howard Hinnant73d21a42010-09-04 23:28:19 +0000834#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantb965fed2011-06-03 16:20:53 +0000835 void __move_assign(forward_list& __x, true_type)
836 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000837 void __move_assign(forward_list& __x, false_type);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000838#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000839
840 template <class _Compare>
841 static
842 __node_pointer
843 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
844
845 template <class _Compare>
846 static
847 __node_pointer
848 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
849};
850
851template <class _Tp, class _Alloc>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +0000852inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000853forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
854 : base(__a)
855{
856}
857
858template <class _Tp, class _Alloc>
859forward_list<_Tp, _Alloc>::forward_list(size_type __n)
860{
861 if (__n > 0)
862 {
863 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +0000864 typedef __allocator_destructor<__node_allocator> _Dp;
865 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselierde637db2016-01-27 00:11:54 +0000866 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
867 __p = __p->__next_as_begin())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000868 {
869 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +0000870 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000871 __h->__next_ = nullptr;
872 __p->__next_ = __h.release();
873 }
874 }
875}
876
Marshall Clow955f2c82013-09-08 19:11:51 +0000877#if _LIBCPP_STD_VER > 11
878template <class _Tp, class _Alloc>
879forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a)
880 : base ( __a )
881{
882 if (__n > 0)
883 {
884 __node_allocator& __a = base::__alloc();
885 typedef __allocator_destructor<__node_allocator> _Dp;
886 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselierde637db2016-01-27 00:11:54 +0000887 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
888 __p = __p->__next_as_begin())
Marshall Clow955f2c82013-09-08 19:11:51 +0000889 {
890 __h.reset(__node_traits::allocate(__a, 1));
891 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
892 __h->__next_ = nullptr;
893 __p->__next_ = __h.release();
894 }
895 }
896}
897#endif
898
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000899template <class _Tp, class _Alloc>
900forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
901{
902 insert_after(cbefore_begin(), __n, __v);
903}
904
905template <class _Tp, class _Alloc>
906forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
907 const allocator_type& __a)
908 : base(__a)
909{
910 insert_after(cbefore_begin(), __n, __v);
911}
912
913template <class _Tp, class _Alloc>
914template <class _InputIterator>
915forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
916 typename enable_if<
917 __is_input_iterator<_InputIterator>::value
918 >::type*)
919{
920 insert_after(cbefore_begin(), __f, __l);
921}
922
923template <class _Tp, class _Alloc>
924template <class _InputIterator>
925forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
926 const allocator_type& __a,
927 typename enable_if<
928 __is_input_iterator<_InputIterator>::value
929 >::type*)
930 : base(__a)
931{
932 insert_after(cbefore_begin(), __f, __l);
933}
934
935template <class _Tp, class _Alloc>
936forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
937 : base(allocator_type(
938 __node_traits::select_on_container_copy_construction(__x.__alloc())
939 )
940 )
941{
942 insert_after(cbefore_begin(), __x.begin(), __x.end());
943}
944
945template <class _Tp, class _Alloc>
946forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
947 const allocator_type& __a)
948 : base(__a)
949{
950 insert_after(cbefore_begin(), __x.begin(), __x.end());
951}
952
Howard Hinnant73d21a42010-09-04 23:28:19 +0000953#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000954
955template <class _Tp, class _Alloc>
956forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
957 const allocator_type& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000958 : base(_VSTD::move(__x), __a)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000959{
960 if (base::__alloc() != __x.__alloc())
961 {
Howard Hinnant99968442011-11-29 18:15:50 +0000962 typedef move_iterator<iterator> _Ip;
963 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000964 }
965}
966
Howard Hinnant73d21a42010-09-04 23:28:19 +0000967#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000968
Howard Hinnante3e32912011-08-12 21:56:02 +0000969#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
970
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000971template <class _Tp, class _Alloc>
972forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
973{
974 insert_after(cbefore_begin(), __il.begin(), __il.end());
975}
976
977template <class _Tp, class _Alloc>
978forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
979 const allocator_type& __a)
980 : base(__a)
981{
982 insert_after(cbefore_begin(), __il.begin(), __il.end());
983}
984
Howard Hinnante3e32912011-08-12 21:56:02 +0000985#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
986
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000987template <class _Tp, class _Alloc>
988forward_list<_Tp, _Alloc>&
989forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
990{
991 if (this != &__x)
992 {
993 base::__copy_assign_alloc(__x);
994 assign(__x.begin(), __x.end());
995 }
996 return *this;
997}
998
Howard Hinnant73d21a42010-09-04 23:28:19 +0000999#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001000
1001template <class _Tp, class _Alloc>
1002void
1003forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnantb965fed2011-06-03 16:20:53 +00001004 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001005{
1006 clear();
1007 base::__move_assign_alloc(__x);
1008 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
1009 __x.__before_begin()->__next_ = nullptr;
1010}
1011
1012template <class _Tp, class _Alloc>
1013void
1014forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
1015{
1016 if (base::__alloc() == __x.__alloc())
1017 __move_assign(__x, true_type());
1018 else
1019 {
Howard Hinnant99968442011-11-29 18:15:50 +00001020 typedef move_iterator<iterator> _Ip;
1021 assign(_Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001022 }
1023}
1024
1025template <class _Tp, class _Alloc>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +00001026inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001027forward_list<_Tp, _Alloc>&
1028forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +00001029 _NOEXCEPT_(
1030 __node_traits::propagate_on_container_move_assignment::value &&
1031 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001032{
1033 __move_assign(__x, integral_constant<bool,
1034 __node_traits::propagate_on_container_move_assignment::value>());
1035 return *this;
1036}
1037
Howard Hinnant73d21a42010-09-04 23:28:19 +00001038#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001039
Howard Hinnante3e32912011-08-12 21:56:02 +00001040#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1041
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001042template <class _Tp, class _Alloc>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +00001043inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001044forward_list<_Tp, _Alloc>&
1045forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
1046{
1047 assign(__il.begin(), __il.end());
1048 return *this;
1049}
1050
Howard Hinnante3e32912011-08-12 21:56:02 +00001051#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1052
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001053template <class _Tp, class _Alloc>
1054template <class _InputIterator>
1055typename enable_if
1056<
1057 __is_input_iterator<_InputIterator>::value,
1058 void
1059>::type
1060forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
1061{
1062 iterator __i = before_begin();
Howard Hinnant0949eed2011-06-30 21:18:19 +00001063 iterator __j = _VSTD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001064 iterator __e = end();
Eric Fiselierb9919752014-10-27 19:28:20 +00001065 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001066 *__j = *__f;
1067 if (__j == __e)
1068 insert_after(__i, __f, __l);
1069 else
1070 erase_after(__i, __e);
1071}
1072
1073template <class _Tp, class _Alloc>
1074void
1075forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
1076{
1077 iterator __i = before_begin();
Howard Hinnant0949eed2011-06-30 21:18:19 +00001078 iterator __j = _VSTD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001079 iterator __e = end();
1080 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1081 *__j = __v;
1082 if (__j == __e)
1083 insert_after(__i, __n, __v);
1084 else
1085 erase_after(__i, __e);
1086}
1087
Howard Hinnante3e32912011-08-12 21:56:02 +00001088#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1089
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001090template <class _Tp, class _Alloc>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +00001091inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001092void
1093forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1094{
1095 assign(__il.begin(), __il.end());
1096}
1097
Howard Hinnante3e32912011-08-12 21:56:02 +00001098#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
1099
Howard Hinnant73d21a42010-09-04 23:28:19 +00001100#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1101#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001102
1103template <class _Tp, class _Alloc>
1104template <class... _Args>
Eric Fiselier3816ef92016-07-21 03:20:17 +00001105typename forward_list<_Tp, _Alloc>::reference
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001106forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1107{
1108 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-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 Hinnant0949eed2011-06-30 21:18:19 +00001111 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1112 _VSTD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113 __h->__next_ = base::__before_begin()->__next_;
1114 base::__before_begin()->__next_ = __h.release();
Eric Fiselier3816ef92016-07-21 03:20:17 +00001115 return base::__before_begin()->__next_->__value_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001116}
1117
Howard Hinnant73d21a42010-09-04 23:28:19 +00001118#endif // _LIBCPP_HAS_NO_VARIADICS
1119
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001120template <class _Tp, class _Alloc>
1121void
1122forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1123{
1124 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001125 typedef __allocator_destructor<__node_allocator> _Dp;
1126 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001127 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001128 __h->__next_ = base::__before_begin()->__next_;
1129 base::__before_begin()->__next_ = __h.release();
1130}
1131
Howard Hinnant73d21a42010-09-04 23:28:19 +00001132#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001133
1134template <class _Tp, class _Alloc>
1135void
1136forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1137{
1138 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001139 typedef __allocator_destructor<__node_allocator> _Dp;
1140 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001141 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001142 __h->__next_ = base::__before_begin()->__next_;
1143 base::__before_begin()->__next_ = __h.release();
1144}
1145
1146template <class _Tp, class _Alloc>
1147void
1148forward_list<_Tp, _Alloc>::pop_front()
1149{
1150 __node_allocator& __a = base::__alloc();
1151 __node_pointer __p = base::__before_begin()->__next_;
1152 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001153 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001154 __node_traits::deallocate(__a, __p, 1);
1155}
1156
Howard Hinnant73d21a42010-09-04 23:28:19 +00001157#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1158#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001159
1160template <class _Tp, class _Alloc>
1161template <class... _Args>
1162typename forward_list<_Tp, _Alloc>::iterator
1163forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1164{
Eric Fiselierde637db2016-01-27 00:11:54 +00001165 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001166 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001167 typedef __allocator_destructor<__node_allocator> _Dp;
1168 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001169 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1170 _VSTD::forward<_Args>(__args)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001171 __h->__next_ = __r->__next_;
1172 __r->__next_ = __h.release();
1173 return iterator(__r->__next_);
1174}
1175
Howard Hinnant73d21a42010-09-04 23:28:19 +00001176#endif // _LIBCPP_HAS_NO_VARIADICS
1177
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001178template <class _Tp, class _Alloc>
1179typename forward_list<_Tp, _Alloc>::iterator
1180forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1181{
Eric Fiselierde637db2016-01-27 00:11:54 +00001182 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001183 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001184 typedef __allocator_destructor<__node_allocator> _Dp;
1185 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001186 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001187 __h->__next_ = __r->__next_;
1188 __r->__next_ = __h.release();
1189 return iterator(__r->__next_);
1190}
1191
Howard Hinnant73d21a42010-09-04 23:28:19 +00001192#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001193
1194template <class _Tp, class _Alloc>
1195typename forward_list<_Tp, _Alloc>::iterator
1196forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1197{
Eric Fiselierde637db2016-01-27 00:11:54 +00001198 __begin_node_pointer const __r = __p.__get_begin();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001199 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001200 typedef __allocator_destructor<__node_allocator> _Dp;
1201 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001202 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001203 __h->__next_ = __r->__next_;
1204 __r->__next_ = __h.release();
1205 return iterator(__r->__next_);
1206}
1207
1208template <class _Tp, class _Alloc>
1209typename forward_list<_Tp, _Alloc>::iterator
1210forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1211 const value_type& __v)
1212{
Eric Fiselierde637db2016-01-27 00:11:54 +00001213 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001214 if (__n > 0)
1215 {
1216 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001217 typedef __allocator_destructor<__node_allocator> _Dp;
1218 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001219 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001220 __node_pointer __first = __h.release();
1221 __node_pointer __last = __first;
1222#ifndef _LIBCPP_NO_EXCEPTIONS
1223 try
1224 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001225#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001226 for (--__n; __n != 0; --__n, __last = __last->__next_)
1227 {
1228 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001229 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001230 __last->__next_ = __h.release();
1231 }
1232#ifndef _LIBCPP_NO_EXCEPTIONS
1233 }
1234 catch (...)
1235 {
1236 while (__first != nullptr)
1237 {
1238 __node_pointer __next = __first->__next_;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001239 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001240 __node_traits::deallocate(__a, __first, 1);
1241 __first = __next;
1242 }
1243 throw;
1244 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001245#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001246 __last->__next_ = __r->__next_;
1247 __r->__next_ = __first;
Eric Fiselierde637db2016-01-27 00:11:54 +00001248 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001249 }
1250 return iterator(__r);
1251}
1252
1253template <class _Tp, class _Alloc>
1254template <class _InputIterator>
1255typename enable_if
1256<
1257 __is_input_iterator<_InputIterator>::value,
1258 typename forward_list<_Tp, _Alloc>::iterator
1259>::type
1260forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1261 _InputIterator __f, _InputIterator __l)
1262{
Eric Fiselierde637db2016-01-27 00:11:54 +00001263 __begin_node_pointer __r = __p.__get_begin();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001264 if (__f != __l)
1265 {
1266 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001267 typedef __allocator_destructor<__node_allocator> _Dp;
1268 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001269 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001270 __node_pointer __first = __h.release();
1271 __node_pointer __last = __first;
1272#ifndef _LIBCPP_NO_EXCEPTIONS
1273 try
1274 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001275#endif // _LIBCPP_NO_EXCEPTIONS
Eric Fiselierb9919752014-10-27 19:28:20 +00001276 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001277 {
1278 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001279 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001280 __last->__next_ = __h.release();
1281 }
1282#ifndef _LIBCPP_NO_EXCEPTIONS
1283 }
1284 catch (...)
1285 {
1286 while (__first != nullptr)
1287 {
1288 __node_pointer __next = __first->__next_;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001289 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001290 __node_traits::deallocate(__a, __first, 1);
1291 __first = __next;
1292 }
1293 throw;
1294 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001295#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001296 __last->__next_ = __r->__next_;
1297 __r->__next_ = __first;
Eric Fiselierde637db2016-01-27 00:11:54 +00001298 __r = static_cast<__begin_node_pointer>(__last);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001299 }
1300 return iterator(__r);
1301}
1302
1303template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001304typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001305forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1306{
Eric Fiselierde637db2016-01-27 00:11:54 +00001307 __begin_node_pointer __p = __f.__get_begin();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001308 __node_pointer __n = __p->__next_;
1309 __p->__next_ = __n->__next_;
1310 __node_allocator& __a = base::__alloc();
Howard Hinnant0949eed2011-06-30 21:18:19 +00001311 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001312 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001313 return iterator(__p->__next_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001314}
1315
1316template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001317typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001318forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1319{
Eric Fiselierde637db2016-01-27 00:11:54 +00001320 __node_pointer __e = __l.__get_unsafe_node_pointer();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001321 if (__f != __l)
1322 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001323 __begin_node_pointer __bp = __f.__get_begin();
1324
1325 __node_pointer __n = __bp->__next_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001326 if (__n != __e)
1327 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001328 __bp->__next_ = __e;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001329 __node_allocator& __a = base::__alloc();
1330 do
1331 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001332 __node_pointer __tmp = __n->__next_;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001333 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001334 __node_traits::deallocate(__a, __n, 1);
Eric Fiselierde637db2016-01-27 00:11:54 +00001335 __n = __tmp;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001336 } while (__n != __e);
1337 }
1338 }
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001339 return iterator(__e);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001340}
1341
1342template <class _Tp, class _Alloc>
1343void
1344forward_list<_Tp, _Alloc>::resize(size_type __n)
1345{
1346 size_type __sz = 0;
1347 iterator __p = before_begin();
1348 iterator __i = begin();
1349 iterator __e = end();
1350 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1351 ;
1352 if (__i != __e)
1353 erase_after(__p, __e);
1354 else
1355 {
1356 __n -= __sz;
1357 if (__n > 0)
1358 {
1359 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001360 typedef __allocator_destructor<__node_allocator> _Dp;
1361 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselierde637db2016-01-27 00:11:54 +00001362 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1363 __ptr = __ptr->__next_as_begin())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001364 {
1365 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001366 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001367 __h->__next_ = nullptr;
1368 __ptr->__next_ = __h.release();
1369 }
1370 }
1371 }
1372}
1373
1374template <class _Tp, class _Alloc>
1375void
1376forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1377{
1378 size_type __sz = 0;
1379 iterator __p = before_begin();
1380 iterator __i = begin();
1381 iterator __e = end();
1382 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1383 ;
1384 if (__i != __e)
1385 erase_after(__p, __e);
1386 else
1387 {
1388 __n -= __sz;
1389 if (__n > 0)
1390 {
1391 __node_allocator& __a = base::__alloc();
Howard Hinnant99968442011-11-29 18:15:50 +00001392 typedef __allocator_destructor<__node_allocator> _Dp;
1393 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Eric Fiselierde637db2016-01-27 00:11:54 +00001394 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1395 __ptr = __ptr->__next_as_begin())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001396 {
1397 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant0949eed2011-06-30 21:18:19 +00001398 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001399 __h->__next_ = nullptr;
1400 __ptr->__next_ = __h.release();
1401 }
1402 }
1403 }
1404}
1405
1406template <class _Tp, class _Alloc>
1407void
1408forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001409 forward_list& __x)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001410{
1411 if (!__x.empty())
1412 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001413 if (__p.__get_begin()->__next_ != nullptr)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001414 {
1415 const_iterator __lm1 = __x.before_begin();
Eric Fiselierde637db2016-01-27 00:11:54 +00001416 while (__lm1.__get_begin()->__next_ != nullptr)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001417 ++__lm1;
Eric Fiselierde637db2016-01-27 00:11:54 +00001418 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001419 }
Eric Fiselierde637db2016-01-27 00:11:54 +00001420 __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
Howard Hinnant81381a92013-06-24 17:17:28 +00001421 __x.__before_begin()->__next_ = nullptr;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001422 }
1423}
1424
1425template <class _Tp, class _Alloc>
1426void
1427forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001428 forward_list& __x,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001429 const_iterator __i)
1430{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001431 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001432 if (__p != __i && __p != __lm1)
1433 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001434 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
1435 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1436 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001437 }
1438}
1439
1440template <class _Tp, class _Alloc>
1441void
1442forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001443 forward_list& __x,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001444 const_iterator __f, const_iterator __l)
1445{
1446 if (__f != __l && __p != __f)
1447 {
1448 const_iterator __lm1 = __f;
Eric Fiselierde637db2016-01-27 00:11:54 +00001449 while (__lm1.__get_begin()->__next_ != __l.__get_begin())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001450 ++__lm1;
1451 if (__f != __lm1)
1452 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001453 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1454 __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
1455 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001456 }
1457 }
1458}
1459
Howard Hinnant99b2f762011-01-27 21:00:35 +00001460#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
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{
1468 splice_after(__p, __x);
1469}
1470
1471template <class _Tp, class _Alloc>
1472inline _LIBCPP_INLINE_VISIBILITY
1473void
1474forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1475 forward_list&& __x,
1476 const_iterator __i)
1477{
1478 splice_after(__p, __x, __i);
1479}
1480
1481template <class _Tp, class _Alloc>
1482inline _LIBCPP_INLINE_VISIBILITY
1483void
1484forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1485 forward_list&& __x,
1486 const_iterator __f, const_iterator __l)
1487{
1488 splice_after(__p, __x, __f, __l);
1489}
1490
1491#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1492
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001493template <class _Tp, class _Alloc>
1494void
1495forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1496{
Marshall Clow095c3dd2014-08-08 15:58:00 +00001497 forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001498 iterator __e = end();
Eric Fiselierde637db2016-01-27 00:11:54 +00001499 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001500 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001501 if (__i.__get_begin()->__next_->__value_ == __v)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001502 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001503 iterator __j = _VSTD::next(__i, 2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001504 for (; __j != __e && *__j == __v; ++__j)
1505 ;
Marshall Clow38d90052014-10-18 11:03:33 +00001506 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001507 if (__j == __e)
1508 break;
1509 __i = __j;
1510 }
1511 else
1512 ++__i;
1513 }
1514}
1515
1516template <class _Tp, class _Alloc>
1517template <class _Predicate>
1518void
1519forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1520{
1521 iterator __e = end();
Eric Fiselierde637db2016-01-27 00:11:54 +00001522 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001523 {
Eric Fiselierde637db2016-01-27 00:11:54 +00001524 if (__pred(__i.__get_begin()->__next_->__value_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001525 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001526 iterator __j = _VSTD::next(__i, 2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001527 for (; __j != __e && __pred(*__j); ++__j)
1528 ;
1529 erase_after(__i, __j);
1530 if (__j == __e)
1531 break;
1532 __i = __j;
1533 }
1534 else
1535 ++__i;
1536 }
1537}
1538
1539template <class _Tp, class _Alloc>
1540template <class _BinaryPredicate>
1541void
1542forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1543{
1544 for (iterator __i = begin(), __e = end(); __i != __e;)
1545 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001546 iterator __j = _VSTD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001547 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1548 ;
Eric Fiselierde637db2016-01-27 00:11:54 +00001549 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001550 erase_after(__i, __j);
1551 __i = __j;
1552 }
1553}
1554
1555template <class _Tp, class _Alloc>
1556template <class _Compare>
1557void
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001558forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001559{
1560 if (this != &__x)
1561 {
1562 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1563 __x.__before_begin()->__next_,
1564 __comp);
1565 __x.__before_begin()->__next_ = nullptr;
1566 }
1567}
1568
1569template <class _Tp, class _Alloc>
1570template <class _Compare>
1571typename forward_list<_Tp, _Alloc>::__node_pointer
1572forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1573 _Compare& __comp)
1574{
1575 if (__f1 == nullptr)
1576 return __f2;
1577 if (__f2 == nullptr)
1578 return __f1;
1579 __node_pointer __r;
1580 if (__comp(__f2->__value_, __f1->__value_))
1581 {
1582 __node_pointer __t = __f2;
1583 while (__t->__next_ != nullptr &&
1584 __comp(__t->__next_->__value_, __f1->__value_))
1585 __t = __t->__next_;
1586 __r = __f2;
1587 __f2 = __t->__next_;
1588 __t->__next_ = __f1;
1589 }
1590 else
1591 __r = __f1;
1592 __node_pointer __p = __f1;
1593 __f1 = __f1->__next_;
1594 while (__f1 != nullptr && __f2 != nullptr)
1595 {
1596 if (__comp(__f2->__value_, __f1->__value_))
1597 {
1598 __node_pointer __t = __f2;
1599 while (__t->__next_ != nullptr &&
1600 __comp(__t->__next_->__value_, __f1->__value_))
1601 __t = __t->__next_;
1602 __p->__next_ = __f2;
1603 __f2 = __t->__next_;
1604 __t->__next_ = __f1;
1605 }
1606 __p = __f1;
1607 __f1 = __f1->__next_;
1608 }
1609 if (__f2 != nullptr)
1610 __p->__next_ = __f2;
1611 return __r;
1612}
1613
1614template <class _Tp, class _Alloc>
1615template <class _Compare>
Evgeniy Stepanov9341a8a2016-04-22 01:04:55 +00001616inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001617void
1618forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1619{
1620 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnant0949eed2011-06-30 21:18:19 +00001621 _VSTD::distance(begin(), end()), __comp);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001622}
1623
1624template <class _Tp, class _Alloc>
1625template <class _Compare>
1626typename forward_list<_Tp, _Alloc>::__node_pointer
1627forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1628 _Compare& __comp)
1629{
1630 switch (__sz)
1631 {
1632 case 0:
1633 case 1:
1634 return __f1;
1635 case 2:
1636 if (__comp(__f1->__next_->__value_, __f1->__value_))
1637 {
1638 __node_pointer __t = __f1->__next_;
1639 __t->__next_ = __f1;
1640 __f1->__next_ = nullptr;
1641 __f1 = __t;
1642 }
1643 return __f1;
1644 }
1645 difference_type __sz1 = __sz / 2;
1646 difference_type __sz2 = __sz - __sz1;
Eric Fiselierde637db2016-01-27 00:11:54 +00001647 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001648 __node_pointer __f2 = __t->__next_;
1649 __t->__next_ = nullptr;
1650 return __merge(__sort(__f1, __sz1, __comp),
1651 __sort(__f2, __sz2, __comp), __comp);
1652}
1653
1654template <class _Tp, class _Alloc>
1655void
Howard Hinnant8790cab2011-06-02 16:44:28 +00001656forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001657{
1658 __node_pointer __p = base::__before_begin()->__next_;
1659 if (__p != nullptr)
1660 {
1661 __node_pointer __f = __p->__next_;
1662 __p->__next_ = nullptr;
1663 while (__f != nullptr)
1664 {
1665 __node_pointer __t = __f->__next_;
1666 __f->__next_ = __p;
1667 __p = __f;
1668 __f = __t;
1669 }
1670 base::__before_begin()->__next_ = __p;
1671 }
1672}
1673
1674template <class _Tp, class _Alloc>
1675bool operator==(const forward_list<_Tp, _Alloc>& __x,
1676 const forward_list<_Tp, _Alloc>& __y)
1677{
Howard Hinnant99968442011-11-29 18:15:50 +00001678 typedef forward_list<_Tp, _Alloc> _Cp;
1679 typedef typename _Cp::const_iterator _Ip;
1680 _Ip __ix = __x.begin();
1681 _Ip __ex = __x.end();
1682 _Ip __iy = __y.begin();
1683 _Ip __ey = __y.end();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001684 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1685 if (!(*__ix == *__iy))
1686 return false;
1687 return (__ix == __ex) == (__iy == __ey);
1688}
1689
1690template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001691inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001692bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1693 const forward_list<_Tp, _Alloc>& __y)
1694{
1695 return !(__x == __y);
1696}
1697
1698template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001699inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001700bool operator< (const forward_list<_Tp, _Alloc>& __x,
1701 const forward_list<_Tp, _Alloc>& __y)
1702{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001703 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001704 __y.begin(), __y.end());
1705}
1706
1707template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001708inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001709bool operator> (const forward_list<_Tp, _Alloc>& __x,
1710 const forward_list<_Tp, _Alloc>& __y)
1711{
1712 return __y < __x;
1713}
1714
1715template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001716inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001717bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1718 const forward_list<_Tp, _Alloc>& __y)
1719{
1720 return !(__x < __y);
1721}
1722
1723template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001724inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001725bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1726 const forward_list<_Tp, _Alloc>& __y)
1727{
1728 return !(__y < __x);
1729}
1730
1731template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001732inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001733void
1734swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnantb965fed2011-06-03 16:20:53 +00001735 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001736{
1737 __x.swap(__y);
1738}
1739
1740_LIBCPP_END_NAMESPACE_STD
1741
1742#endif // _LIBCPP_FORWARD_LIST