blob: 6066475166d37a917cc9c90a04b2f647c401c06f [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
37 forward_list();
38 explicit forward_list(const allocator_type& a);
39 explicit forward_list(size_type n);
40 forward_list(size_type n, const value_type& v);
41 forward_list(size_type n, const value_type& v, const allocator_type& a);
42 template <class InputIterator>
43 forward_list(InputIterator first, InputIterator last);
44 template <class InputIterator>
45 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
46 forward_list(const forward_list& x);
47 forward_list(const forward_list& x, const allocator_type& a);
48 forward_list(forward_list&& x);
49 forward_list(forward_list&& x, const allocator_type& a);
50 forward_list(initializer_list<value_type> il);
51 forward_list(initializer_list<value_type> il, const allocator_type& a);
52
53 ~forward_list();
54
55 forward_list& operator=(const forward_list& x);
56 forward_list& operator=(forward_list&& x);
57 forward_list& operator=(initializer_list<value_type> il);
58
59 template <class InputIterator>
60 void assign(InputIterator first, InputIterator last);
61 void assign(size_type n, const value_type& v);
62 void assign(initializer_list<value_type> il);
63
64 allocator_type get_allocator() const;
65
66 iterator begin();
67 const_iterator begin() const;
68 iterator end();
69 const_iterator end() const;
70
71 const_iterator cbegin() const;
72 const_iterator cend() const;
73
74 iterator before_begin();
75 const_iterator before_begin() const;
76 const_iterator cbefore_begin() const;
77
78 bool empty() const;
79 size_type max_size() const;
80
81 reference front();
82 const_reference front() const;
83
84 template <class... Args> void emplace_front(Args&&... args);
85 void push_front(const value_type& v);
86 void push_front(value_type&& v);
87
88 void pop_front();
89
90 template <class... Args>
91 iterator emplace_after(const_iterator p, Args&&... args);
92 iterator insert_after(const_iterator p, const value_type& v);
93 iterator insert_after(const_iterator p, value_type&& v);
94 iterator insert_after(const_iterator p, size_type n, const value_type& v);
95 template <class InputIterator>
96 iterator insert_after(const_iterator p,
97 InputIterator first, InputIterator last);
98 iterator insert_after(const_iterator p, initializer_list<value_type> il);
99
Howard Hinnant3db88032010-08-21 20:58:44 +0000100 iterator erase_after(const_iterator p);
101 iterator erase_after(const_iterator first, const_iterator last);
Howard Hinnant3e519522010-05-11 19:42:16 +0000102
103 void swap(forward_list& x);
104
105 void resize(size_type n);
106 void resize(size_type n, const value_type& v);
107 void clear();
108
Howard Hinnanteb92df72011-01-27 21:00:35 +0000109 void splice_after(const_iterator p, forward_list& x);
Howard Hinnant3e519522010-05-11 19:42:16 +0000110 void splice_after(const_iterator p, forward_list&& x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000111 void splice_after(const_iterator p, forward_list& x, const_iterator i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000112 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000113 void splice_after(const_iterator p, forward_list& x,
114 const_iterator first, const_iterator last);
Howard Hinnant3e519522010-05-11 19:42:16 +0000115 void splice_after(const_iterator p, forward_list&& x,
116 const_iterator first, const_iterator last);
117 void remove(const value_type& v);
118 template <class Predicate> void remove_if(Predicate pred);
119 void unique();
120 template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000121 void merge(forward_list& x);
Howard Hinnant3e519522010-05-11 19:42:16 +0000122 void merge(forward_list&& x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000123 template <class Compare> void merge(forward_list& x, Compare comp);
Howard Hinnant3e519522010-05-11 19:42:16 +0000124 template <class Compare> void merge(forward_list&& x, Compare comp);
125 void sort();
126 template <class Compare> void sort(Compare comp);
127 void reverse();
128};
129
130template <class T, class Allocator>
131 bool operator==(const forward_list<T, Allocator>& x,
132 const forward_list<T, Allocator>& y);
133
134template <class T, class Allocator>
135 bool operator< (const forward_list<T, Allocator>& x,
136 const forward_list<T, Allocator>& y);
137
138template <class T, class Allocator>
139 bool operator!=(const forward_list<T, Allocator>& x,
140 const forward_list<T, Allocator>& y);
141
142template <class T, class Allocator>
143 bool operator> (const forward_list<T, Allocator>& x,
144 const forward_list<T, Allocator>& y);
145
146template <class T, class Allocator>
147 bool operator>=(const forward_list<T, Allocator>& x,
148 const forward_list<T, Allocator>& y);
149
150template <class T, class Allocator>
151 bool operator<=(const forward_list<T, Allocator>& x,
152 const forward_list<T, Allocator>& y);
153
154template <class T, class Allocator>
155 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y);
156
157} // std
158
159*/
160
161#include <__config>
162
163#include <initializer_list>
164#include <memory>
165#include <limits>
166#include <iterator>
167#include <algorithm>
168
169#pragma GCC system_header
170
171_LIBCPP_BEGIN_NAMESPACE_STD
172
173template <class, class> struct __forward_list_node;
174
175template <class _NodePtr>
176struct __forward_begin_node
177{
178 typedef __forward_begin_node __self;
179 typedef _NodePtr pointer;
180
181 pointer __next_;
182
Howard Hinnant0af133f2010-09-21 22:55:27 +0000183 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000184};
185
186template <class _Tp, class _VoidPtr>
187struct __forward_list_node
188 : public __forward_begin_node
189 <
190 typename pointer_traits<_VoidPtr>::template
191#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
192 rebind<__forward_list_node<_Tp, _VoidPtr> >
193#else
194 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
195#endif
196 >
197{
198 typedef _Tp value_type;
199
200 value_type __value_;
201};
202
203template<class, class> class forward_list;
204template<class> class __forward_list_const_iterator;
205
206template <class _NodePtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000207class _LIBCPP_VISIBLE __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000208{
209 typedef _NodePtr __node_pointer;
210
211 __node_pointer __ptr_;
212
Howard Hinnant0af133f2010-09-21 22:55:27 +0000213 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000214 explicit __forward_list_iterator(__node_pointer __p) : __ptr_(__p) {}
215
216 template<class, class> friend class forward_list;
217 template<class> friend class __forward_list_const_iterator;
218
219public:
220 typedef forward_iterator_tag iterator_category;
221 typedef typename pointer_traits<__node_pointer>::element_type::value_type
222 value_type;
223 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000224 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000225 difference_type;
226 typedef typename pointer_traits<__node_pointer>::template
227#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
228 rebind<value_type>
229#else
230 rebind<value_type>::other
231#endif
232 pointer;
233
Howard Hinnant0af133f2010-09-21 22:55:27 +0000234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000235 __forward_list_iterator() : __ptr_(nullptr) {}
236
Howard Hinnant0af133f2010-09-21 22:55:27 +0000237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000238 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000240 pointer operator->() const {return &__ptr_->__value_;}
241
Howard Hinnant0af133f2010-09-21 22:55:27 +0000242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000243 __forward_list_iterator& operator++()
244 {
245 __ptr_ = __ptr_->__next_;
246 return *this;
247 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000249 __forward_list_iterator operator++(int)
250 {
251 __forward_list_iterator __t(*this);
252 ++(*this);
253 return __t;
254 }
255
Howard Hinnant0af133f2010-09-21 22:55:27 +0000256 friend _LIBCPP_INLINE_VISIBILITY
257 bool operator==(const __forward_list_iterator& __x,
258 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000259 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000260 friend _LIBCPP_INLINE_VISIBILITY
261 bool operator!=(const __forward_list_iterator& __x,
262 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000263 {return !(__x == __y);}
264};
265
266template <class _NodeConstPtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000267class _LIBCPP_VISIBLE __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000268{
269 typedef _NodeConstPtr __node_const_pointer;
270
271 __node_const_pointer __ptr_;
272
Howard Hinnant0af133f2010-09-21 22:55:27 +0000273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000274 explicit __forward_list_const_iterator(__node_const_pointer __p)
275 : __ptr_(__p) {}
276
277 typedef typename remove_const
278 <
279 typename pointer_traits<__node_const_pointer>::element_type
280 >::type __node;
281 typedef typename pointer_traits<__node_const_pointer>::template
282#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
283 rebind<__node>
284#else
285 rebind<__node>::other
286#endif
287 __node_pointer;
288
289 template<class, class> friend class forward_list;
290
291public:
292 typedef forward_iterator_tag iterator_category;
293 typedef typename __node::value_type value_type;
294 typedef const value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000295 typedef typename pointer_traits<__node_const_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000296 difference_type;
297 typedef typename pointer_traits<__node_const_pointer>::template
298#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
299 rebind<const value_type>
300#else
301 rebind<const value_type>::other
302#endif
303 pointer;
304
Howard Hinnant0af133f2010-09-21 22:55:27 +0000305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000306 __forward_list_const_iterator() : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000308 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p)
309 : __ptr_(__p.__ptr_) {}
310
Howard Hinnant0af133f2010-09-21 22:55:27 +0000311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000312 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000314 pointer operator->() const {return &__ptr_->__value_;}
315
Howard Hinnant0af133f2010-09-21 22:55:27 +0000316 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000317 __forward_list_const_iterator& operator++()
318 {
319 __ptr_ = __ptr_->__next_;
320 return *this;
321 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000322 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000323 __forward_list_const_iterator operator++(int)
324 {
325 __forward_list_const_iterator __t(*this);
326 ++(*this);
327 return __t;
328 }
329
Howard Hinnant0af133f2010-09-21 22:55:27 +0000330 friend _LIBCPP_INLINE_VISIBILITY
331 bool operator==(const __forward_list_const_iterator& __x,
332 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000333 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000334 friend _LIBCPP_INLINE_VISIBILITY
335 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000336 const __forward_list_const_iterator& __y)
337 {return !(__x == __y);}
338};
339
340template <class _Tp, class _Alloc>
341class __forward_list_base
342{
343protected:
344 typedef _Tp value_type;
345 typedef _Alloc allocator_type;
346
347 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
348 typedef __forward_list_node<value_type, void_pointer> __node;
349 typedef typename __node::__self __begin_node;
350 typedef typename allocator_traits<allocator_type>::template
351#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
352 rebind_alloc<__node>
353#else
354 rebind_alloc<__node>::other
355#endif
356 __node_allocator;
357 typedef allocator_traits<__node_allocator> __node_traits;
358 typedef typename __node_traits::pointer __node_pointer;
359 typedef typename __node_traits::const_pointer __node_const_pointer;
360
361 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
362
Howard Hinnant0af133f2010-09-21 22:55:27 +0000363 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000364 __node_pointer __before_begin()
365 {return pointer_traits<__node_pointer>::pointer_to(
366 static_cast<__node&>(__before_begin_.first()));}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000367 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000368 __node_const_pointer __before_begin() const
369 {return pointer_traits<__node_const_pointer>::pointer_to(
370 static_cast<const __node&>(__before_begin_.first()));}
371
Howard Hinnant0af133f2010-09-21 22:55:27 +0000372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000373 __node_allocator& __alloc() {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000375 const __node_allocator& __alloc() const {return __before_begin_.second();}
376
377 typedef __forward_list_iterator<__node_pointer> iterator;
378 typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
379
Howard Hinnant0af133f2010-09-21 22:55:27 +0000380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000381 __forward_list_base()
382 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000384 __forward_list_base(const allocator_type& __a)
385 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
386
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000388 __forward_list_base(__forward_list_base&& __x);
389 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000390#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000391
392private:
393 __forward_list_base(const __forward_list_base&);
394 __forward_list_base& operator=(const __forward_list_base&);
395protected:
396
397 ~__forward_list_base();
398
Howard Hinnant0af133f2010-09-21 22:55:27 +0000399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000400 void __copy_assign_alloc(const __forward_list_base& __x)
401 {__copy_assign_alloc(__x, integral_constant<bool,
402 __node_traits::propagate_on_container_copy_assignment::value>());}
403
Howard Hinnant0af133f2010-09-21 22:55:27 +0000404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000405 void __move_assign_alloc(__forward_list_base& __x)
406 {__move_assign_alloc(__x, integral_constant<bool,
407 __node_traits::propagate_on_container_move_assignment::value>());}
408
409 void swap(__forward_list_base& __x);
410 void clear();
411
412private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000414 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000416 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
417 {
418 if (__alloc() != __x.__alloc())
419 clear();
420 __alloc() = __x.__alloc();
421 }
422
Howard Hinnant0af133f2010-09-21 22:55:27 +0000423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000424 void __move_assign_alloc(__forward_list_base& __x, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000425 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000426 void __move_assign_alloc(__forward_list_base& __x, true_type)
427 {__alloc() = _STD::move(__x.__alloc());}
428
Howard Hinnant0af133f2010-09-21 22:55:27 +0000429 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000430 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
431 {__swap_alloc(__x, __y, integral_constant<bool,
432 __node_traits::propagate_on_container_swap::value>());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000434 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
435 false_type)
436 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000437 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000438 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
439 true_type)
440 {
441 using _STD::swap;
442 swap(__x, __y);
443 }
444};
445
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000446#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000447
448template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000449inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000450__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
451 : __before_begin_(_STD::move(__x.__before_begin_))
452{
453 __x.__before_begin()->__next_ = nullptr;
454}
455
456template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000457inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000458__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
459 const allocator_type& __a)
460 : __before_begin_(__begin_node(), __node_allocator(__a))
461{
462 if (__alloc() == __x.__alloc())
463 {
464 __before_begin()->__next_ = __x.__before_begin()->__next_;
465 __x.__before_begin()->__next_ = nullptr;
466 }
467}
468
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000469#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000470
471template <class _Tp, class _Alloc>
472__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
473{
474 clear();
475}
476
477template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000478inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000479void
480__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
481{
482 __swap_alloc(__alloc(), __x.__alloc());
483 using _STD::swap;
484 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
485}
486
487template <class _Tp, class _Alloc>
488void
489__forward_list_base<_Tp, _Alloc>::clear()
490{
491 __node_allocator& __a = __alloc();
492 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
493 {
494 __node_pointer __next = __p->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +0000495 __node_traits::destroy(__a, _STD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000496 __node_traits::deallocate(__a, __p, 1);
497 __p = __next;
498 }
499 __before_begin()->__next_ = nullptr;
500}
501
502template <class _Tp, class _Alloc = allocator<_Tp> >
Howard Hinnant0af133f2010-09-21 22:55:27 +0000503class _LIBCPP_VISIBLE forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000504 : private __forward_list_base<_Tp, _Alloc>
505{
506 typedef __forward_list_base<_Tp, _Alloc> base;
507public:
508 typedef _Tp value_type;
509 typedef _Alloc allocator_type;
510
511 typedef value_type& reference;
512 typedef const value_type& const_reference;
513 typedef typename allocator_traits<allocator_type>::pointer pointer;
514 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
515 typedef typename allocator_traits<allocator_type>::size_type size_type;
516 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
517
518 typedef typename base::iterator iterator;
519 typedef typename base::const_iterator const_iterator;
520
Howard Hinnant0af133f2010-09-21 22:55:27 +0000521 _LIBCPP_INLINE_VISIBILITY forward_list() {} // = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000522 explicit forward_list(const allocator_type& __a);
523 explicit forward_list(size_type __n);
524 forward_list(size_type __n, const value_type& __v);
525 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
526 template <class _InputIterator>
527 forward_list(_InputIterator __f, _InputIterator __l,
528 typename enable_if<
529 __is_input_iterator<_InputIterator>::value
530 >::type* = nullptr);
531 template <class _InputIterator>
532 forward_list(_InputIterator __f, _InputIterator __l,
533 const allocator_type& __a,
534 typename enable_if<
535 __is_input_iterator<_InputIterator>::value
536 >::type* = nullptr);
537 forward_list(const forward_list& __x);
538 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000539#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000541 forward_list(forward_list&& __x) : base(_STD::move(__x)) {}
542 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000543#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000544 forward_list(initializer_list<value_type> __il);
545 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
546
547 // ~forward_list() = default;
548
549 forward_list& operator=(const forward_list& __x);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000550#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000551 forward_list& operator=(forward_list&& __x);
552#endif
553 forward_list& operator=(initializer_list<value_type> __il);
554
555 template <class _InputIterator>
556 typename enable_if
557 <
558 __is_input_iterator<_InputIterator>::value,
559 void
560 >::type
561 assign(_InputIterator __f, _InputIterator __l);
562 void assign(size_type __n, const value_type& __v);
563 void assign(initializer_list<value_type> __il);
564
Howard Hinnant0af133f2010-09-21 22:55:27 +0000565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000566 allocator_type get_allocator() const {return allocator_type(base::__alloc());}
567
Howard Hinnant0af133f2010-09-21 22:55:27 +0000568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000569 iterator begin() {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000571 const_iterator begin() const {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000572 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000573 iterator end() {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000575 const_iterator end() const {return const_iterator(nullptr);}
576
Howard Hinnant0af133f2010-09-21 22:55:27 +0000577 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000578 const_iterator cbegin() const {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000580 const_iterator cend() const {return const_iterator(nullptr);}
581
Howard Hinnant0af133f2010-09-21 22:55:27 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000583 iterator before_begin() {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000585 const_iterator before_begin() const {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000587 const_iterator cbefore_begin() const {return const_iterator(base::__before_begin());}
588
Howard Hinnant0af133f2010-09-21 22:55:27 +0000589 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000590 bool empty() const {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000591 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000592 size_type max_size() const {return numeric_limits<size_type>::max();}
593
Howard Hinnant0af133f2010-09-21 22:55:27 +0000594 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000595 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000596 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000597 const_reference front() const {return base::__before_begin()->__next_->__value_;}
598
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000599#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
600#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000601 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000602#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000603 void push_front(value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000604#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000605 void push_front(const value_type& __v);
606
607 void pop_front();
608
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000609#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
610#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000611 template <class... _Args>
612 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000613#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000614 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000615#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000616 iterator insert_after(const_iterator __p, const value_type& __v);
617 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
618 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000620 typename enable_if
621 <
622 __is_input_iterator<_InputIterator>::value,
623 iterator
624 >::type
625 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
626 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
627 {return insert_after(__p, __il.begin(), __il.end());}
628
Howard Hinnant3db88032010-08-21 20:58:44 +0000629 iterator erase_after(const_iterator __p);
630 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000631
Howard Hinnant0af133f2010-09-21 22:55:27 +0000632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000633 void swap(forward_list& __x) {base::swap(__x);}
634
635 void resize(size_type __n);
636 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000637 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000638 void clear() {base::clear();}
639
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000640#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanteb92df72011-01-27 21:00:35 +0000641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000642 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000643 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000644 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000646 void splice_after(const_iterator __p, forward_list&& __x,
647 const_iterator __f, const_iterator __l);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000648#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000649 void splice_after(const_iterator __p, forward_list& __x);
650 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
651 void splice_after(const_iterator __p, forward_list& __x,
652 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000653 void remove(const value_type& __v);
654 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000655 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000656 void unique() {unique(__equal_to<value_type>());}
657 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000658#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000659 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000660 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
661 template <class _Compare>
662 _LIBCPP_INLINE_VISIBILITY
663 void merge(forward_list&& __x, _Compare __comp)
664 {merge(__x, _STD::move(__comp));}
665#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000666 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000667 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
668 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000669 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000670 void sort() {sort(__less<value_type>());}
671 template <class _Compare> void sort(_Compare __comp);
672 void reverse();
673
674private:
675 typedef typename base::__node_allocator __node_allocator;
676 typedef typename base::__node __node;
677 typedef typename base::__node_traits __node_traits;
678 typedef typename base::__node_pointer __node_pointer;
679
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000680#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000681 void __move_assign(forward_list& __x, true_type);
682 void __move_assign(forward_list& __x, false_type);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000683#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000684
685 template <class _Compare>
686 static
687 __node_pointer
688 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
689
690 template <class _Compare>
691 static
692 __node_pointer
693 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
694};
695
696template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000697inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000698forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
699 : base(__a)
700{
701}
702
703template <class _Tp, class _Alloc>
704forward_list<_Tp, _Alloc>::forward_list(size_type __n)
705{
706 if (__n > 0)
707 {
708 __node_allocator& __a = base::__alloc();
709 typedef __allocator_destructor<__node_allocator> _D;
710 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
711 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
712 __p = __p->__next_)
713 {
714 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000715 __node_traits::construct(__a, _STD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000716 __h->__next_ = nullptr;
717 __p->__next_ = __h.release();
718 }
719 }
720}
721
722template <class _Tp, class _Alloc>
723forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
724{
725 insert_after(cbefore_begin(), __n, __v);
726}
727
728template <class _Tp, class _Alloc>
729forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
730 const allocator_type& __a)
731 : base(__a)
732{
733 insert_after(cbefore_begin(), __n, __v);
734}
735
736template <class _Tp, class _Alloc>
737template <class _InputIterator>
738forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
739 typename enable_if<
740 __is_input_iterator<_InputIterator>::value
741 >::type*)
742{
743 insert_after(cbefore_begin(), __f, __l);
744}
745
746template <class _Tp, class _Alloc>
747template <class _InputIterator>
748forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
749 const allocator_type& __a,
750 typename enable_if<
751 __is_input_iterator<_InputIterator>::value
752 >::type*)
753 : base(__a)
754{
755 insert_after(cbefore_begin(), __f, __l);
756}
757
758template <class _Tp, class _Alloc>
759forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
760 : base(allocator_type(
761 __node_traits::select_on_container_copy_construction(__x.__alloc())
762 )
763 )
764{
765 insert_after(cbefore_begin(), __x.begin(), __x.end());
766}
767
768template <class _Tp, class _Alloc>
769forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
770 const allocator_type& __a)
771 : base(__a)
772{
773 insert_after(cbefore_begin(), __x.begin(), __x.end());
774}
775
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000776#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000777
778template <class _Tp, class _Alloc>
779forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
780 const allocator_type& __a)
781 : base(_STD::move(__x), __a)
782{
783 if (base::__alloc() != __x.__alloc())
784 {
785 typedef move_iterator<iterator> _I;
786 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
787 }
788}
789
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000790#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000791
792template <class _Tp, class _Alloc>
793forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
794{
795 insert_after(cbefore_begin(), __il.begin(), __il.end());
796}
797
798template <class _Tp, class _Alloc>
799forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
800 const allocator_type& __a)
801 : base(__a)
802{
803 insert_after(cbefore_begin(), __il.begin(), __il.end());
804}
805
806template <class _Tp, class _Alloc>
807forward_list<_Tp, _Alloc>&
808forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
809{
810 if (this != &__x)
811 {
812 base::__copy_assign_alloc(__x);
813 assign(__x.begin(), __x.end());
814 }
815 return *this;
816}
817
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000818#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000819
820template <class _Tp, class _Alloc>
821void
822forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
823{
824 clear();
825 base::__move_assign_alloc(__x);
826 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
827 __x.__before_begin()->__next_ = nullptr;
828}
829
830template <class _Tp, class _Alloc>
831void
832forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
833{
834 if (base::__alloc() == __x.__alloc())
835 __move_assign(__x, true_type());
836 else
837 {
838 typedef move_iterator<iterator> _I;
839 assign(_I(__x.begin()), _I(__x.end()));
840 }
841}
842
843template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000844inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000845forward_list<_Tp, _Alloc>&
846forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
847{
848 __move_assign(__x, integral_constant<bool,
849 __node_traits::propagate_on_container_move_assignment::value>());
850 return *this;
851}
852
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000853#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000854
855template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000856inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000857forward_list<_Tp, _Alloc>&
858forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
859{
860 assign(__il.begin(), __il.end());
861 return *this;
862}
863
864template <class _Tp, class _Alloc>
865template <class _InputIterator>
866typename enable_if
867<
868 __is_input_iterator<_InputIterator>::value,
869 void
870>::type
871forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
872{
873 iterator __i = before_begin();
874 iterator __j = next(__i);
875 iterator __e = end();
876 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
877 *__j = *__f;
878 if (__j == __e)
879 insert_after(__i, __f, __l);
880 else
881 erase_after(__i, __e);
882}
883
884template <class _Tp, class _Alloc>
885void
886forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
887{
888 iterator __i = before_begin();
889 iterator __j = next(__i);
890 iterator __e = end();
891 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
892 *__j = __v;
893 if (__j == __e)
894 insert_after(__i, __n, __v);
895 else
896 erase_after(__i, __e);
897}
898
899template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000900inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000901void
902forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
903{
904 assign(__il.begin(), __il.end());
905}
906
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000907#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
908#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000909
910template <class _Tp, class _Alloc>
911template <class... _Args>
912void
913forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
914{
915 __node_allocator& __a = base::__alloc();
916 typedef __allocator_destructor<__node_allocator> _D;
917 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000918 __node_traits::construct(__a, _STD::addressof(__h->__value_),
Howard Hinnant3e519522010-05-11 19:42:16 +0000919 _STD::forward<_Args>(__args)...);
920 __h->__next_ = base::__before_begin()->__next_;
921 base::__before_begin()->__next_ = __h.release();
922}
923
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000924#endif // _LIBCPP_HAS_NO_VARIADICS
925
Howard Hinnant3e519522010-05-11 19:42:16 +0000926template <class _Tp, class _Alloc>
927void
928forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
929{
930 __node_allocator& __a = base::__alloc();
931 typedef __allocator_destructor<__node_allocator> _D;
932 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000933 __node_traits::construct(__a, _STD::addressof(__h->__value_), _STD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +0000934 __h->__next_ = base::__before_begin()->__next_;
935 base::__before_begin()->__next_ = __h.release();
936}
937
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000938#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000939
940template <class _Tp, class _Alloc>
941void
942forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
943{
944 __node_allocator& __a = base::__alloc();
945 typedef __allocator_destructor<__node_allocator> _D;
946 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000947 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +0000948 __h->__next_ = base::__before_begin()->__next_;
949 base::__before_begin()->__next_ = __h.release();
950}
951
952template <class _Tp, class _Alloc>
953void
954forward_list<_Tp, _Alloc>::pop_front()
955{
956 __node_allocator& __a = base::__alloc();
957 __node_pointer __p = base::__before_begin()->__next_;
958 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +0000959 __node_traits::destroy(__a, _STD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000960 __node_traits::deallocate(__a, __p, 1);
961}
962
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000963#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
964#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000965
966template <class _Tp, class _Alloc>
967template <class... _Args>
968typename forward_list<_Tp, _Alloc>::iterator
969forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
970{
971 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
972 __node_allocator& __a = base::__alloc();
973 typedef __allocator_destructor<__node_allocator> _D;
974 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000975 __node_traits::construct(__a, _STD::addressof(__h->__value_),
Howard Hinnant3e519522010-05-11 19:42:16 +0000976 _STD::forward<_Args>(__args)...);
977 __h->__next_ = __r->__next_;
978 __r->__next_ = __h.release();
979 return iterator(__r->__next_);
980}
981
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000982#endif // _LIBCPP_HAS_NO_VARIADICS
983
Howard Hinnant3e519522010-05-11 19:42:16 +0000984template <class _Tp, class _Alloc>
985typename forward_list<_Tp, _Alloc>::iterator
986forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
987{
988 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
989 __node_allocator& __a = base::__alloc();
990 typedef __allocator_destructor<__node_allocator> _D;
991 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000992 __node_traits::construct(__a, _STD::addressof(__h->__value_), _STD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +0000993 __h->__next_ = __r->__next_;
994 __r->__next_ = __h.release();
995 return iterator(__r->__next_);
996}
997
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000998#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000999
1000template <class _Tp, class _Alloc>
1001typename forward_list<_Tp, _Alloc>::iterator
1002forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1003{
1004 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1005 __node_allocator& __a = base::__alloc();
1006 typedef __allocator_destructor<__node_allocator> _D;
1007 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001008 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001009 __h->__next_ = __r->__next_;
1010 __r->__next_ = __h.release();
1011 return iterator(__r->__next_);
1012}
1013
1014template <class _Tp, class _Alloc>
1015typename forward_list<_Tp, _Alloc>::iterator
1016forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1017 const value_type& __v)
1018{
Howard Hinnante57dc142010-08-19 17:40:04 +00001019 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001020 if (__n > 0)
1021 {
1022 __node_allocator& __a = base::__alloc();
1023 typedef __allocator_destructor<__node_allocator> _D;
1024 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001025 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001026 __node_pointer __first = __h.release();
1027 __node_pointer __last = __first;
1028#ifndef _LIBCPP_NO_EXCEPTIONS
1029 try
1030 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001031#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001032 for (--__n; __n != 0; --__n, __last = __last->__next_)
1033 {
1034 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001035 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001036 __last->__next_ = __h.release();
1037 }
1038#ifndef _LIBCPP_NO_EXCEPTIONS
1039 }
1040 catch (...)
1041 {
1042 while (__first != nullptr)
1043 {
1044 __node_pointer __next = __first->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +00001045 __node_traits::destroy(__a, _STD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001046 __node_traits::deallocate(__a, __first, 1);
1047 __first = __next;
1048 }
1049 throw;
1050 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001051#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001052 __last->__next_ = __r->__next_;
1053 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001054 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001055 }
1056 return iterator(__r);
1057}
1058
1059template <class _Tp, class _Alloc>
1060template <class _InputIterator>
1061typename enable_if
1062<
1063 __is_input_iterator<_InputIterator>::value,
1064 typename forward_list<_Tp, _Alloc>::iterator
1065>::type
1066forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1067 _InputIterator __f, _InputIterator __l)
1068{
Howard Hinnante57dc142010-08-19 17:40:04 +00001069 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001070 if (__f != __l)
1071 {
1072 __node_allocator& __a = base::__alloc();
1073 typedef __allocator_destructor<__node_allocator> _D;
1074 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001075 __node_traits::construct(__a, _STD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001076 __node_pointer __first = __h.release();
1077 __node_pointer __last = __first;
1078#ifndef _LIBCPP_NO_EXCEPTIONS
1079 try
1080 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001081#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001082 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1083 {
1084 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001085 __node_traits::construct(__a, _STD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001086 __last->__next_ = __h.release();
1087 }
1088#ifndef _LIBCPP_NO_EXCEPTIONS
1089 }
1090 catch (...)
1091 {
1092 while (__first != nullptr)
1093 {
1094 __node_pointer __next = __first->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +00001095 __node_traits::destroy(__a, _STD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001096 __node_traits::deallocate(__a, __first, 1);
1097 __first = __next;
1098 }
1099 throw;
1100 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001101#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001102 __last->__next_ = __r->__next_;
1103 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001104 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001105 }
1106 return iterator(__r);
1107}
1108
1109template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001110typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001111forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1112{
1113 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1114 __node_pointer __n = __p->__next_;
1115 __p->__next_ = __n->__next_;
1116 __node_allocator& __a = base::__alloc();
Howard Hinnant72c5e142011-02-02 17:36:20 +00001117 __node_traits::destroy(__a, _STD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001118 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001119 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001120}
1121
1122template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001123typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001124forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1125{
Howard Hinnant3db88032010-08-21 20:58:44 +00001126 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001127 if (__f != __l)
1128 {
1129 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1130 __node_pointer __n = __p->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001131 if (__n != __e)
1132 {
1133 __p->__next_ = __e;
1134 __node_allocator& __a = base::__alloc();
1135 do
1136 {
1137 __p = __n->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +00001138 __node_traits::destroy(__a, _STD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001139 __node_traits::deallocate(__a, __n, 1);
1140 __n = __p;
1141 } while (__n != __e);
1142 }
1143 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001144 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001145}
1146
1147template <class _Tp, class _Alloc>
1148void
1149forward_list<_Tp, _Alloc>::resize(size_type __n)
1150{
1151 size_type __sz = 0;
1152 iterator __p = before_begin();
1153 iterator __i = begin();
1154 iterator __e = end();
1155 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1156 ;
1157 if (__i != __e)
1158 erase_after(__p, __e);
1159 else
1160 {
1161 __n -= __sz;
1162 if (__n > 0)
1163 {
1164 __node_allocator& __a = base::__alloc();
1165 typedef __allocator_destructor<__node_allocator> _D;
1166 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1167 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1168 __ptr = __ptr->__next_)
1169 {
1170 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001171 __node_traits::construct(__a, _STD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001172 __h->__next_ = nullptr;
1173 __ptr->__next_ = __h.release();
1174 }
1175 }
1176 }
1177}
1178
1179template <class _Tp, class _Alloc>
1180void
1181forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1182{
1183 size_type __sz = 0;
1184 iterator __p = before_begin();
1185 iterator __i = begin();
1186 iterator __e = end();
1187 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1188 ;
1189 if (__i != __e)
1190 erase_after(__p, __e);
1191 else
1192 {
1193 __n -= __sz;
1194 if (__n > 0)
1195 {
1196 __node_allocator& __a = base::__alloc();
1197 typedef __allocator_destructor<__node_allocator> _D;
1198 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1199 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1200 __ptr = __ptr->__next_)
1201 {
1202 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001203 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001204 __h->__next_ = nullptr;
1205 __ptr->__next_ = __h.release();
1206 }
1207 }
1208 }
1209}
1210
1211template <class _Tp, class _Alloc>
1212void
1213forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001214 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001215{
1216 if (!__x.empty())
1217 {
1218 if (__p.__ptr_->__next_ != nullptr)
1219 {
1220 const_iterator __lm1 = __x.before_begin();
1221 while (__lm1.__ptr_->__next_ != nullptr)
1222 ++__lm1;
1223 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1224 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1225 }
1226 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1227 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1228 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1229 }
1230}
1231
1232template <class _Tp, class _Alloc>
1233void
1234forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001235 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001236 const_iterator __i)
1237{
1238 const_iterator __lm1 = next(__i);
1239 if (__p != __i && __p != __lm1)
1240 {
1241 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1242 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1243 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1244 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1245 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1246 const_cast<__node_pointer>(__lm1.__ptr_);
1247 }
1248}
1249
1250template <class _Tp, class _Alloc>
1251void
1252forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001253 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001254 const_iterator __f, const_iterator __l)
1255{
1256 if (__f != __l && __p != __f)
1257 {
1258 const_iterator __lm1 = __f;
1259 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1260 ++__lm1;
1261 if (__f != __lm1)
1262 {
1263 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1264 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1265 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1266 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1267 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1268 const_cast<__node_pointer>(__l.__ptr_);
1269 }
1270 }
1271}
1272
Howard Hinnanteb92df72011-01-27 21:00:35 +00001273#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1274
1275template <class _Tp, class _Alloc>
1276inline _LIBCPP_INLINE_VISIBILITY
1277void
1278forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1279 forward_list&& __x)
1280{
1281 splice_after(__p, __x);
1282}
1283
1284template <class _Tp, class _Alloc>
1285inline _LIBCPP_INLINE_VISIBILITY
1286void
1287forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1288 forward_list&& __x,
1289 const_iterator __i)
1290{
1291 splice_after(__p, __x, __i);
1292}
1293
1294template <class _Tp, class _Alloc>
1295inline _LIBCPP_INLINE_VISIBILITY
1296void
1297forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1298 forward_list&& __x,
1299 const_iterator __f, const_iterator __l)
1300{
1301 splice_after(__p, __x, __f, __l);
1302}
1303
1304#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1305
Howard Hinnant3e519522010-05-11 19:42:16 +00001306template <class _Tp, class _Alloc>
1307void
1308forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1309{
1310 iterator __e = end();
1311 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1312 {
1313 if (__i.__ptr_->__next_->__value_ == __v)
1314 {
1315 iterator __j = next(__i, 2);
1316 for (; __j != __e && *__j == __v; ++__j)
1317 ;
1318 erase_after(__i, __j);
1319 if (__j == __e)
1320 break;
1321 __i = __j;
1322 }
1323 else
1324 ++__i;
1325 }
1326}
1327
1328template <class _Tp, class _Alloc>
1329template <class _Predicate>
1330void
1331forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1332{
1333 iterator __e = end();
1334 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1335 {
1336 if (__pred(__i.__ptr_->__next_->__value_))
1337 {
1338 iterator __j = next(__i, 2);
1339 for (; __j != __e && __pred(*__j); ++__j)
1340 ;
1341 erase_after(__i, __j);
1342 if (__j == __e)
1343 break;
1344 __i = __j;
1345 }
1346 else
1347 ++__i;
1348 }
1349}
1350
1351template <class _Tp, class _Alloc>
1352template <class _BinaryPredicate>
1353void
1354forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1355{
1356 for (iterator __i = begin(), __e = end(); __i != __e;)
1357 {
1358 iterator __j = next(__i);
1359 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1360 ;
1361 if (__i.__ptr_->__next_ != __j.__ptr_)
1362 erase_after(__i, __j);
1363 __i = __j;
1364 }
1365}
1366
1367template <class _Tp, class _Alloc>
1368template <class _Compare>
1369void
Howard Hinnant3e519522010-05-11 19:42:16 +00001370forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001371{
1372 if (this != &__x)
1373 {
1374 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1375 __x.__before_begin()->__next_,
1376 __comp);
1377 __x.__before_begin()->__next_ = nullptr;
1378 }
1379}
1380
1381template <class _Tp, class _Alloc>
1382template <class _Compare>
1383typename forward_list<_Tp, _Alloc>::__node_pointer
1384forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1385 _Compare& __comp)
1386{
1387 if (__f1 == nullptr)
1388 return __f2;
1389 if (__f2 == nullptr)
1390 return __f1;
1391 __node_pointer __r;
1392 if (__comp(__f2->__value_, __f1->__value_))
1393 {
1394 __node_pointer __t = __f2;
1395 while (__t->__next_ != nullptr &&
1396 __comp(__t->__next_->__value_, __f1->__value_))
1397 __t = __t->__next_;
1398 __r = __f2;
1399 __f2 = __t->__next_;
1400 __t->__next_ = __f1;
1401 }
1402 else
1403 __r = __f1;
1404 __node_pointer __p = __f1;
1405 __f1 = __f1->__next_;
1406 while (__f1 != nullptr && __f2 != nullptr)
1407 {
1408 if (__comp(__f2->__value_, __f1->__value_))
1409 {
1410 __node_pointer __t = __f2;
1411 while (__t->__next_ != nullptr &&
1412 __comp(__t->__next_->__value_, __f1->__value_))
1413 __t = __t->__next_;
1414 __p->__next_ = __f2;
1415 __f2 = __t->__next_;
1416 __t->__next_ = __f1;
1417 }
1418 __p = __f1;
1419 __f1 = __f1->__next_;
1420 }
1421 if (__f2 != nullptr)
1422 __p->__next_ = __f2;
1423 return __r;
1424}
1425
1426template <class _Tp, class _Alloc>
1427template <class _Compare>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001428inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001429void
1430forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1431{
1432 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1433 _STD::distance(begin(), end()), __comp);
1434}
1435
1436template <class _Tp, class _Alloc>
1437template <class _Compare>
1438typename forward_list<_Tp, _Alloc>::__node_pointer
1439forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1440 _Compare& __comp)
1441{
1442 switch (__sz)
1443 {
1444 case 0:
1445 case 1:
1446 return __f1;
1447 case 2:
1448 if (__comp(__f1->__next_->__value_, __f1->__value_))
1449 {
1450 __node_pointer __t = __f1->__next_;
1451 __t->__next_ = __f1;
1452 __f1->__next_ = nullptr;
1453 __f1 = __t;
1454 }
1455 return __f1;
1456 }
1457 difference_type __sz1 = __sz / 2;
1458 difference_type __sz2 = __sz - __sz1;
1459 __node_pointer __t = next(iterator(__f1), __sz1 - 1).__ptr_;
1460 __node_pointer __f2 = __t->__next_;
1461 __t->__next_ = nullptr;
1462 return __merge(__sort(__f1, __sz1, __comp),
1463 __sort(__f2, __sz2, __comp), __comp);
1464}
1465
1466template <class _Tp, class _Alloc>
1467void
1468forward_list<_Tp, _Alloc>::reverse()
1469{
1470 __node_pointer __p = base::__before_begin()->__next_;
1471 if (__p != nullptr)
1472 {
1473 __node_pointer __f = __p->__next_;
1474 __p->__next_ = nullptr;
1475 while (__f != nullptr)
1476 {
1477 __node_pointer __t = __f->__next_;
1478 __f->__next_ = __p;
1479 __p = __f;
1480 __f = __t;
1481 }
1482 base::__before_begin()->__next_ = __p;
1483 }
1484}
1485
1486template <class _Tp, class _Alloc>
1487bool operator==(const forward_list<_Tp, _Alloc>& __x,
1488 const forward_list<_Tp, _Alloc>& __y)
1489{
1490 typedef forward_list<_Tp, _Alloc> _C;
1491 typedef typename _C::const_iterator _I;
1492 _I __ix = __x.begin();
1493 _I __ex = __x.end();
1494 _I __iy = __y.begin();
1495 _I __ey = __y.end();
1496 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1497 if (!(*__ix == *__iy))
1498 return false;
1499 return (__ix == __ex) == (__iy == __ey);
1500}
1501
1502template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001503inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001504bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1505 const forward_list<_Tp, _Alloc>& __y)
1506{
1507 return !(__x == __y);
1508}
1509
1510template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001511inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001512bool operator< (const forward_list<_Tp, _Alloc>& __x,
1513 const forward_list<_Tp, _Alloc>& __y)
1514{
1515 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1516 __y.begin(), __y.end());
1517}
1518
1519template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001520inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001521bool operator> (const forward_list<_Tp, _Alloc>& __x,
1522 const forward_list<_Tp, _Alloc>& __y)
1523{
1524 return __y < __x;
1525}
1526
1527template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001528inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001529bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1530 const forward_list<_Tp, _Alloc>& __y)
1531{
1532 return !(__x < __y);
1533}
1534
1535template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001536inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001537bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1538 const forward_list<_Tp, _Alloc>& __y)
1539{
1540 return !(__y < __x);
1541}
1542
1543template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001544inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001545void
1546swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1547{
1548 __x.swap(__y);
1549}
1550
1551_LIBCPP_END_NAMESPACE_STD
1552
1553#endif // _LIBCPP_FORWARD_LIST