blob: 1babc8f2b1cfd6545ffdc1127aee6a8a470d385f [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
Howard Hinnantf9dc2832011-06-02 16:44:28 +000064 allocator_type get_allocator() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000065
Howard Hinnantf9dc2832011-06-02 16:44:28 +000066 iterator begin() noexcept;
67 const_iterator begin() const noexcept;
68 iterator end() noexcept;
69 const_iterator end() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000070
Howard Hinnantf9dc2832011-06-02 16:44:28 +000071 const_iterator cbegin() const noexcept;
72 const_iterator cend() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000073
Howard Hinnantf9dc2832011-06-02 16:44:28 +000074 iterator before_begin() noexcept;
75 const_iterator before_begin() const noexcept;
76 const_iterator cbefore_begin() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000077
Howard Hinnantf9dc2832011-06-02 16:44:28 +000078 bool empty() const noexcept;
79 size_type max_size() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000080
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);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000107 void clear() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000108
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);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000127 void reverse() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000128};
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 Hinnantf9dc2832011-06-02 16:44:28 +0000214 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000215
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 Hinnantf9dc2832011-06-02 16:44:28 +0000235 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000236
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 Hinnantf9dc2832011-06-02 16:44:28 +0000274 explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000275 : __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 Hinnantf9dc2832011-06-02 16:44:28 +0000306 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000308 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000309 : __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 Hinnantf9dc2832011-06-02 16:44:28 +0000364 __node_pointer __before_begin() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000365 {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 Hinnantf9dc2832011-06-02 16:44:28 +0000368 __node_const_pointer __before_begin() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000369 {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 Hinnantf9dc2832011-06-02 16:44:28 +0000375 const __node_allocator& __alloc() const _NOEXCEPT
376 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000377
378 typedef __forward_list_iterator<__node_pointer> iterator;
379 typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
380
Howard Hinnant0af133f2010-09-21 22:55:27 +0000381 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000382 __forward_list_base()
383 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000385 __forward_list_base(const allocator_type& __a)
386 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
387
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000388#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000389 __forward_list_base(__forward_list_base&& __x);
390 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000391#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000392
393private:
394 __forward_list_base(const __forward_list_base&);
395 __forward_list_base& operator=(const __forward_list_base&);
396protected:
397
398 ~__forward_list_base();
399
Howard Hinnant0af133f2010-09-21 22:55:27 +0000400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000401 void __copy_assign_alloc(const __forward_list_base& __x)
402 {__copy_assign_alloc(__x, integral_constant<bool,
403 __node_traits::propagate_on_container_copy_assignment::value>());}
404
Howard Hinnant0af133f2010-09-21 22:55:27 +0000405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000406 void __move_assign_alloc(__forward_list_base& __x)
407 {__move_assign_alloc(__x, integral_constant<bool,
408 __node_traits::propagate_on_container_move_assignment::value>());}
409
410 void swap(__forward_list_base& __x);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000411 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000412
413private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000415 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000417 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
418 {
419 if (__alloc() != __x.__alloc())
420 clear();
421 __alloc() = __x.__alloc();
422 }
423
Howard Hinnant0af133f2010-09-21 22:55:27 +0000424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000425 void __move_assign_alloc(__forward_list_base& __x, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000426 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000427 void __move_assign_alloc(__forward_list_base& __x, true_type)
428 {__alloc() = _STD::move(__x.__alloc());}
429
Howard Hinnant0af133f2010-09-21 22:55:27 +0000430 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000431 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
432 {__swap_alloc(__x, __y, integral_constant<bool,
433 __node_traits::propagate_on_container_swap::value>());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000434 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000435 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
436 false_type)
437 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000438 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000439 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
440 true_type)
441 {
442 using _STD::swap;
443 swap(__x, __y);
444 }
445};
446
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000447#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000448
449template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000450inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000451__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
452 : __before_begin_(_STD::move(__x.__before_begin_))
453{
454 __x.__before_begin()->__next_ = nullptr;
455}
456
457template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000458inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000459__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
460 const allocator_type& __a)
461 : __before_begin_(__begin_node(), __node_allocator(__a))
462{
463 if (__alloc() == __x.__alloc())
464 {
465 __before_begin()->__next_ = __x.__before_begin()->__next_;
466 __x.__before_begin()->__next_ = nullptr;
467 }
468}
469
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000470#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000471
472template <class _Tp, class _Alloc>
473__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
474{
475 clear();
476}
477
478template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000479inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000480void
481__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
482{
483 __swap_alloc(__alloc(), __x.__alloc());
484 using _STD::swap;
485 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
486}
487
488template <class _Tp, class _Alloc>
489void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000490__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000491{
492 __node_allocator& __a = __alloc();
493 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
494 {
495 __node_pointer __next = __p->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +0000496 __node_traits::destroy(__a, _STD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000497 __node_traits::deallocate(__a, __p, 1);
498 __p = __next;
499 }
500 __before_begin()->__next_ = nullptr;
501}
502
503template <class _Tp, class _Alloc = allocator<_Tp> >
Howard Hinnant0af133f2010-09-21 22:55:27 +0000504class _LIBCPP_VISIBLE forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000505 : private __forward_list_base<_Tp, _Alloc>
506{
507 typedef __forward_list_base<_Tp, _Alloc> base;
508public:
509 typedef _Tp value_type;
510 typedef _Alloc allocator_type;
511
512 typedef value_type& reference;
513 typedef const value_type& const_reference;
514 typedef typename allocator_traits<allocator_type>::pointer pointer;
515 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
516 typedef typename allocator_traits<allocator_type>::size_type size_type;
517 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
518
519 typedef typename base::iterator iterator;
520 typedef typename base::const_iterator const_iterator;
521
Howard Hinnant0af133f2010-09-21 22:55:27 +0000522 _LIBCPP_INLINE_VISIBILITY forward_list() {} // = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000523 explicit forward_list(const allocator_type& __a);
524 explicit forward_list(size_type __n);
525 forward_list(size_type __n, const value_type& __v);
526 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
527 template <class _InputIterator>
528 forward_list(_InputIterator __f, _InputIterator __l,
529 typename enable_if<
530 __is_input_iterator<_InputIterator>::value
531 >::type* = nullptr);
532 template <class _InputIterator>
533 forward_list(_InputIterator __f, _InputIterator __l,
534 const allocator_type& __a,
535 typename enable_if<
536 __is_input_iterator<_InputIterator>::value
537 >::type* = nullptr);
538 forward_list(const forward_list& __x);
539 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000540#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000541 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000542 forward_list(forward_list&& __x) : base(_STD::move(__x)) {}
543 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000544#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000545 forward_list(initializer_list<value_type> __il);
546 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
547
548 // ~forward_list() = default;
549
550 forward_list& operator=(const forward_list& __x);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000551#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000552 forward_list& operator=(forward_list&& __x);
553#endif
554 forward_list& operator=(initializer_list<value_type> __il);
555
556 template <class _InputIterator>
557 typename enable_if
558 <
559 __is_input_iterator<_InputIterator>::value,
560 void
561 >::type
562 assign(_InputIterator __f, _InputIterator __l);
563 void assign(size_type __n, const value_type& __v);
564 void assign(initializer_list<value_type> __il);
565
Howard Hinnant0af133f2010-09-21 22:55:27 +0000566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000567 allocator_type get_allocator() const _NOEXCEPT
568 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000569
Howard Hinnant0af133f2010-09-21 22:55:27 +0000570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000571 iterator begin() _NOEXCEPT
572 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000573 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000574 const_iterator begin() const _NOEXCEPT
575 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000577 iterator end() _NOEXCEPT
578 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000580 const_iterator end() const _NOEXCEPT
581 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000582
Howard Hinnant0af133f2010-09-21 22:55:27 +0000583 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000584 const_iterator cbegin() const _NOEXCEPT
585 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000587 const_iterator cend() const _NOEXCEPT
588 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000589
Howard Hinnant0af133f2010-09-21 22:55:27 +0000590 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000591 iterator before_begin() _NOEXCEPT
592 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000593 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000594 const_iterator before_begin() const _NOEXCEPT
595 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000596 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000597 const_iterator cbefore_begin() const _NOEXCEPT
598 {return const_iterator(base::__before_begin());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000599
Howard Hinnant0af133f2010-09-21 22:55:27 +0000600 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000601 bool empty() const _NOEXCEPT
602 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000604 size_type max_size() const _NOEXCEPT
605 {return numeric_limits<size_type>::max();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000606
Howard Hinnant0af133f2010-09-21 22:55:27 +0000607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000608 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000610 const_reference front() const {return base::__before_begin()->__next_->__value_;}
611
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000612#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
613#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000614 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000615#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000616 void push_front(value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000617#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000618 void push_front(const value_type& __v);
619
620 void pop_front();
621
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000622#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
623#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000624 template <class... _Args>
625 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000626#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000627 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000628#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000629 iterator insert_after(const_iterator __p, const value_type& __v);
630 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
631 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000633 typename enable_if
634 <
635 __is_input_iterator<_InputIterator>::value,
636 iterator
637 >::type
638 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
639 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
640 {return insert_after(__p, __il.begin(), __il.end());}
641
Howard Hinnant3db88032010-08-21 20:58:44 +0000642 iterator erase_after(const_iterator __p);
643 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000644
Howard Hinnant0af133f2010-09-21 22:55:27 +0000645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000646 void swap(forward_list& __x) {base::swap(__x);}
647
648 void resize(size_type __n);
649 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000650 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000651 void clear() _NOEXCEPT {base::clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000652
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000653#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanteb92df72011-01-27 21:00:35 +0000654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000655 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000656 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000657 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000658 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000659 void splice_after(const_iterator __p, forward_list&& __x,
660 const_iterator __f, const_iterator __l);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000661#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000662 void splice_after(const_iterator __p, forward_list& __x);
663 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
664 void splice_after(const_iterator __p, forward_list& __x,
665 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000666 void remove(const value_type& __v);
667 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000668 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000669 void unique() {unique(__equal_to<value_type>());}
670 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000671#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000672 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000673 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
674 template <class _Compare>
675 _LIBCPP_INLINE_VISIBILITY
676 void merge(forward_list&& __x, _Compare __comp)
677 {merge(__x, _STD::move(__comp));}
678#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000680 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
681 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000682 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000683 void sort() {sort(__less<value_type>());}
684 template <class _Compare> void sort(_Compare __comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000685 void reverse() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000686
687private:
688 typedef typename base::__node_allocator __node_allocator;
689 typedef typename base::__node __node;
690 typedef typename base::__node_traits __node_traits;
691 typedef typename base::__node_pointer __node_pointer;
692
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000693#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000694 void __move_assign(forward_list& __x, true_type);
695 void __move_assign(forward_list& __x, false_type);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000696#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000697
698 template <class _Compare>
699 static
700 __node_pointer
701 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
702
703 template <class _Compare>
704 static
705 __node_pointer
706 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
707};
708
709template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000710inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000711forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
712 : base(__a)
713{
714}
715
716template <class _Tp, class _Alloc>
717forward_list<_Tp, _Alloc>::forward_list(size_type __n)
718{
719 if (__n > 0)
720 {
721 __node_allocator& __a = base::__alloc();
722 typedef __allocator_destructor<__node_allocator> _D;
723 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
724 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
725 __p = __p->__next_)
726 {
727 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000728 __node_traits::construct(__a, _STD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000729 __h->__next_ = nullptr;
730 __p->__next_ = __h.release();
731 }
732 }
733}
734
735template <class _Tp, class _Alloc>
736forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
737{
738 insert_after(cbefore_begin(), __n, __v);
739}
740
741template <class _Tp, class _Alloc>
742forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
743 const allocator_type& __a)
744 : base(__a)
745{
746 insert_after(cbefore_begin(), __n, __v);
747}
748
749template <class _Tp, class _Alloc>
750template <class _InputIterator>
751forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
752 typename enable_if<
753 __is_input_iterator<_InputIterator>::value
754 >::type*)
755{
756 insert_after(cbefore_begin(), __f, __l);
757}
758
759template <class _Tp, class _Alloc>
760template <class _InputIterator>
761forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
762 const allocator_type& __a,
763 typename enable_if<
764 __is_input_iterator<_InputIterator>::value
765 >::type*)
766 : base(__a)
767{
768 insert_after(cbefore_begin(), __f, __l);
769}
770
771template <class _Tp, class _Alloc>
772forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
773 : base(allocator_type(
774 __node_traits::select_on_container_copy_construction(__x.__alloc())
775 )
776 )
777{
778 insert_after(cbefore_begin(), __x.begin(), __x.end());
779}
780
781template <class _Tp, class _Alloc>
782forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
783 const allocator_type& __a)
784 : base(__a)
785{
786 insert_after(cbefore_begin(), __x.begin(), __x.end());
787}
788
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000789#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000790
791template <class _Tp, class _Alloc>
792forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
793 const allocator_type& __a)
794 : base(_STD::move(__x), __a)
795{
796 if (base::__alloc() != __x.__alloc())
797 {
798 typedef move_iterator<iterator> _I;
799 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
800 }
801}
802
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000803#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000804
805template <class _Tp, class _Alloc>
806forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
807{
808 insert_after(cbefore_begin(), __il.begin(), __il.end());
809}
810
811template <class _Tp, class _Alloc>
812forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
813 const allocator_type& __a)
814 : base(__a)
815{
816 insert_after(cbefore_begin(), __il.begin(), __il.end());
817}
818
819template <class _Tp, class _Alloc>
820forward_list<_Tp, _Alloc>&
821forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
822{
823 if (this != &__x)
824 {
825 base::__copy_assign_alloc(__x);
826 assign(__x.begin(), __x.end());
827 }
828 return *this;
829}
830
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000831#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000832
833template <class _Tp, class _Alloc>
834void
835forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
836{
837 clear();
838 base::__move_assign_alloc(__x);
839 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
840 __x.__before_begin()->__next_ = nullptr;
841}
842
843template <class _Tp, class _Alloc>
844void
845forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
846{
847 if (base::__alloc() == __x.__alloc())
848 __move_assign(__x, true_type());
849 else
850 {
851 typedef move_iterator<iterator> _I;
852 assign(_I(__x.begin()), _I(__x.end()));
853 }
854}
855
856template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000857inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000858forward_list<_Tp, _Alloc>&
859forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
860{
861 __move_assign(__x, integral_constant<bool,
862 __node_traits::propagate_on_container_move_assignment::value>());
863 return *this;
864}
865
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000866#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000867
868template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000869inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000870forward_list<_Tp, _Alloc>&
871forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
872{
873 assign(__il.begin(), __il.end());
874 return *this;
875}
876
877template <class _Tp, class _Alloc>
878template <class _InputIterator>
879typename enable_if
880<
881 __is_input_iterator<_InputIterator>::value,
882 void
883>::type
884forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
885{
886 iterator __i = before_begin();
Howard Hinnanta0fe8c42011-02-14 19:12:38 +0000887 iterator __j = _STD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000888 iterator __e = end();
889 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
890 *__j = *__f;
891 if (__j == __e)
892 insert_after(__i, __f, __l);
893 else
894 erase_after(__i, __e);
895}
896
897template <class _Tp, class _Alloc>
898void
899forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
900{
901 iterator __i = before_begin();
Howard Hinnanta0fe8c42011-02-14 19:12:38 +0000902 iterator __j = _STD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000903 iterator __e = end();
904 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
905 *__j = __v;
906 if (__j == __e)
907 insert_after(__i, __n, __v);
908 else
909 erase_after(__i, __e);
910}
911
912template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000913inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000914void
915forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
916{
917 assign(__il.begin(), __il.end());
918}
919
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000920#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
921#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000922
923template <class _Tp, class _Alloc>
924template <class... _Args>
925void
926forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
927{
928 __node_allocator& __a = base::__alloc();
929 typedef __allocator_destructor<__node_allocator> _D;
930 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000931 __node_traits::construct(__a, _STD::addressof(__h->__value_),
Howard Hinnant3e519522010-05-11 19:42:16 +0000932 _STD::forward<_Args>(__args)...);
933 __h->__next_ = base::__before_begin()->__next_;
934 base::__before_begin()->__next_ = __h.release();
935}
936
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000937#endif // _LIBCPP_HAS_NO_VARIADICS
938
Howard Hinnant3e519522010-05-11 19:42:16 +0000939template <class _Tp, class _Alloc>
940void
941forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
942{
943 __node_allocator& __a = base::__alloc();
944 typedef __allocator_destructor<__node_allocator> _D;
945 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000946 __node_traits::construct(__a, _STD::addressof(__h->__value_), _STD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +0000947 __h->__next_ = base::__before_begin()->__next_;
948 base::__before_begin()->__next_ = __h.release();
949}
950
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000951#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000952
953template <class _Tp, class _Alloc>
954void
955forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
956{
957 __node_allocator& __a = base::__alloc();
958 typedef __allocator_destructor<__node_allocator> _D;
959 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000960 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +0000961 __h->__next_ = base::__before_begin()->__next_;
962 base::__before_begin()->__next_ = __h.release();
963}
964
965template <class _Tp, class _Alloc>
966void
967forward_list<_Tp, _Alloc>::pop_front()
968{
969 __node_allocator& __a = base::__alloc();
970 __node_pointer __p = base::__before_begin()->__next_;
971 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +0000972 __node_traits::destroy(__a, _STD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000973 __node_traits::deallocate(__a, __p, 1);
974}
975
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000976#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
977#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000978
979template <class _Tp, class _Alloc>
980template <class... _Args>
981typename forward_list<_Tp, _Alloc>::iterator
982forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
983{
984 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
985 __node_allocator& __a = base::__alloc();
986 typedef __allocator_destructor<__node_allocator> _D;
987 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +0000988 __node_traits::construct(__a, _STD::addressof(__h->__value_),
Howard Hinnant3e519522010-05-11 19:42:16 +0000989 _STD::forward<_Args>(__args)...);
990 __h->__next_ = __r->__next_;
991 __r->__next_ = __h.release();
992 return iterator(__r->__next_);
993}
994
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000995#endif // _LIBCPP_HAS_NO_VARIADICS
996
Howard Hinnant3e519522010-05-11 19:42:16 +0000997template <class _Tp, class _Alloc>
998typename forward_list<_Tp, _Alloc>::iterator
999forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1000{
1001 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1002 __node_allocator& __a = base::__alloc();
1003 typedef __allocator_destructor<__node_allocator> _D;
1004 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001005 __node_traits::construct(__a, _STD::addressof(__h->__value_), _STD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001006 __h->__next_ = __r->__next_;
1007 __r->__next_ = __h.release();
1008 return iterator(__r->__next_);
1009}
1010
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001011#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001012
1013template <class _Tp, class _Alloc>
1014typename forward_list<_Tp, _Alloc>::iterator
1015forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1016{
1017 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1018 __node_allocator& __a = base::__alloc();
1019 typedef __allocator_destructor<__node_allocator> _D;
1020 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001021 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001022 __h->__next_ = __r->__next_;
1023 __r->__next_ = __h.release();
1024 return iterator(__r->__next_);
1025}
1026
1027template <class _Tp, class _Alloc>
1028typename forward_list<_Tp, _Alloc>::iterator
1029forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1030 const value_type& __v)
1031{
Howard Hinnante57dc142010-08-19 17:40:04 +00001032 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001033 if (__n > 0)
1034 {
1035 __node_allocator& __a = base::__alloc();
1036 typedef __allocator_destructor<__node_allocator> _D;
1037 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001038 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001039 __node_pointer __first = __h.release();
1040 __node_pointer __last = __first;
1041#ifndef _LIBCPP_NO_EXCEPTIONS
1042 try
1043 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001044#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001045 for (--__n; __n != 0; --__n, __last = __last->__next_)
1046 {
1047 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001048 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001049 __last->__next_ = __h.release();
1050 }
1051#ifndef _LIBCPP_NO_EXCEPTIONS
1052 }
1053 catch (...)
1054 {
1055 while (__first != nullptr)
1056 {
1057 __node_pointer __next = __first->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +00001058 __node_traits::destroy(__a, _STD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001059 __node_traits::deallocate(__a, __first, 1);
1060 __first = __next;
1061 }
1062 throw;
1063 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001064#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001065 __last->__next_ = __r->__next_;
1066 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001067 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001068 }
1069 return iterator(__r);
1070}
1071
1072template <class _Tp, class _Alloc>
1073template <class _InputIterator>
1074typename enable_if
1075<
1076 __is_input_iterator<_InputIterator>::value,
1077 typename forward_list<_Tp, _Alloc>::iterator
1078>::type
1079forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1080 _InputIterator __f, _InputIterator __l)
1081{
Howard Hinnante57dc142010-08-19 17:40:04 +00001082 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001083 if (__f != __l)
1084 {
1085 __node_allocator& __a = base::__alloc();
1086 typedef __allocator_destructor<__node_allocator> _D;
1087 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001088 __node_traits::construct(__a, _STD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001089 __node_pointer __first = __h.release();
1090 __node_pointer __last = __first;
1091#ifndef _LIBCPP_NO_EXCEPTIONS
1092 try
1093 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001094#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001095 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1096 {
1097 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001098 __node_traits::construct(__a, _STD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001099 __last->__next_ = __h.release();
1100 }
1101#ifndef _LIBCPP_NO_EXCEPTIONS
1102 }
1103 catch (...)
1104 {
1105 while (__first != nullptr)
1106 {
1107 __node_pointer __next = __first->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +00001108 __node_traits::destroy(__a, _STD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001109 __node_traits::deallocate(__a, __first, 1);
1110 __first = __next;
1111 }
1112 throw;
1113 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001114#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001115 __last->__next_ = __r->__next_;
1116 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001117 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001118 }
1119 return iterator(__r);
1120}
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)
1125{
1126 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1127 __node_pointer __n = __p->__next_;
1128 __p->__next_ = __n->__next_;
1129 __node_allocator& __a = base::__alloc();
Howard Hinnant72c5e142011-02-02 17:36:20 +00001130 __node_traits::destroy(__a, _STD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001131 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001132 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001133}
1134
1135template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001136typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001137forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1138{
Howard Hinnant3db88032010-08-21 20:58:44 +00001139 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001140 if (__f != __l)
1141 {
1142 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1143 __node_pointer __n = __p->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001144 if (__n != __e)
1145 {
1146 __p->__next_ = __e;
1147 __node_allocator& __a = base::__alloc();
1148 do
1149 {
1150 __p = __n->__next_;
Howard Hinnant72c5e142011-02-02 17:36:20 +00001151 __node_traits::destroy(__a, _STD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001152 __node_traits::deallocate(__a, __n, 1);
1153 __n = __p;
1154 } while (__n != __e);
1155 }
1156 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001157 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001158}
1159
1160template <class _Tp, class _Alloc>
1161void
1162forward_list<_Tp, _Alloc>::resize(size_type __n)
1163{
1164 size_type __sz = 0;
1165 iterator __p = before_begin();
1166 iterator __i = begin();
1167 iterator __e = end();
1168 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1169 ;
1170 if (__i != __e)
1171 erase_after(__p, __e);
1172 else
1173 {
1174 __n -= __sz;
1175 if (__n > 0)
1176 {
1177 __node_allocator& __a = base::__alloc();
1178 typedef __allocator_destructor<__node_allocator> _D;
1179 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1180 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1181 __ptr = __ptr->__next_)
1182 {
1183 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001184 __node_traits::construct(__a, _STD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001185 __h->__next_ = nullptr;
1186 __ptr->__next_ = __h.release();
1187 }
1188 }
1189 }
1190}
1191
1192template <class _Tp, class _Alloc>
1193void
1194forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1195{
1196 size_type __sz = 0;
1197 iterator __p = before_begin();
1198 iterator __i = begin();
1199 iterator __e = end();
1200 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1201 ;
1202 if (__i != __e)
1203 erase_after(__p, __e);
1204 else
1205 {
1206 __n -= __sz;
1207 if (__n > 0)
1208 {
1209 __node_allocator& __a = base::__alloc();
1210 typedef __allocator_destructor<__node_allocator> _D;
1211 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1212 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1213 __ptr = __ptr->__next_)
1214 {
1215 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant72c5e142011-02-02 17:36:20 +00001216 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001217 __h->__next_ = nullptr;
1218 __ptr->__next_ = __h.release();
1219 }
1220 }
1221 }
1222}
1223
1224template <class _Tp, class _Alloc>
1225void
1226forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001227 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001228{
1229 if (!__x.empty())
1230 {
1231 if (__p.__ptr_->__next_ != nullptr)
1232 {
1233 const_iterator __lm1 = __x.before_begin();
1234 while (__lm1.__ptr_->__next_ != nullptr)
1235 ++__lm1;
1236 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1237 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1238 }
1239 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1240 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1241 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1242 }
1243}
1244
1245template <class _Tp, class _Alloc>
1246void
1247forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001248 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001249 const_iterator __i)
1250{
Howard Hinnanta0fe8c42011-02-14 19:12:38 +00001251 const_iterator __lm1 = _STD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001252 if (__p != __i && __p != __lm1)
1253 {
1254 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1255 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1256 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1257 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1258 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1259 const_cast<__node_pointer>(__lm1.__ptr_);
1260 }
1261}
1262
1263template <class _Tp, class _Alloc>
1264void
1265forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001266 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001267 const_iterator __f, const_iterator __l)
1268{
1269 if (__f != __l && __p != __f)
1270 {
1271 const_iterator __lm1 = __f;
1272 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1273 ++__lm1;
1274 if (__f != __lm1)
1275 {
1276 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1277 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1278 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1279 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1280 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1281 const_cast<__node_pointer>(__l.__ptr_);
1282 }
1283 }
1284}
1285
Howard Hinnanteb92df72011-01-27 21:00:35 +00001286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1287
1288template <class _Tp, class _Alloc>
1289inline _LIBCPP_INLINE_VISIBILITY
1290void
1291forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1292 forward_list&& __x)
1293{
1294 splice_after(__p, __x);
1295}
1296
1297template <class _Tp, class _Alloc>
1298inline _LIBCPP_INLINE_VISIBILITY
1299void
1300forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1301 forward_list&& __x,
1302 const_iterator __i)
1303{
1304 splice_after(__p, __x, __i);
1305}
1306
1307template <class _Tp, class _Alloc>
1308inline _LIBCPP_INLINE_VISIBILITY
1309void
1310forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1311 forward_list&& __x,
1312 const_iterator __f, const_iterator __l)
1313{
1314 splice_after(__p, __x, __f, __l);
1315}
1316
1317#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1318
Howard Hinnant3e519522010-05-11 19:42:16 +00001319template <class _Tp, class _Alloc>
1320void
1321forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1322{
1323 iterator __e = end();
1324 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1325 {
1326 if (__i.__ptr_->__next_->__value_ == __v)
1327 {
Howard Hinnanta0fe8c42011-02-14 19:12:38 +00001328 iterator __j = _STD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001329 for (; __j != __e && *__j == __v; ++__j)
1330 ;
1331 erase_after(__i, __j);
1332 if (__j == __e)
1333 break;
1334 __i = __j;
1335 }
1336 else
1337 ++__i;
1338 }
1339}
1340
1341template <class _Tp, class _Alloc>
1342template <class _Predicate>
1343void
1344forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1345{
1346 iterator __e = end();
1347 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1348 {
1349 if (__pred(__i.__ptr_->__next_->__value_))
1350 {
Howard Hinnanta0fe8c42011-02-14 19:12:38 +00001351 iterator __j = _STD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001352 for (; __j != __e && __pred(*__j); ++__j)
1353 ;
1354 erase_after(__i, __j);
1355 if (__j == __e)
1356 break;
1357 __i = __j;
1358 }
1359 else
1360 ++__i;
1361 }
1362}
1363
1364template <class _Tp, class _Alloc>
1365template <class _BinaryPredicate>
1366void
1367forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1368{
1369 for (iterator __i = begin(), __e = end(); __i != __e;)
1370 {
Howard Hinnanta0fe8c42011-02-14 19:12:38 +00001371 iterator __j = _STD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001372 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1373 ;
1374 if (__i.__ptr_->__next_ != __j.__ptr_)
1375 erase_after(__i, __j);
1376 __i = __j;
1377 }
1378}
1379
1380template <class _Tp, class _Alloc>
1381template <class _Compare>
1382void
Howard Hinnant3e519522010-05-11 19:42:16 +00001383forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001384{
1385 if (this != &__x)
1386 {
1387 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1388 __x.__before_begin()->__next_,
1389 __comp);
1390 __x.__before_begin()->__next_ = nullptr;
1391 }
1392}
1393
1394template <class _Tp, class _Alloc>
1395template <class _Compare>
1396typename forward_list<_Tp, _Alloc>::__node_pointer
1397forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1398 _Compare& __comp)
1399{
1400 if (__f1 == nullptr)
1401 return __f2;
1402 if (__f2 == nullptr)
1403 return __f1;
1404 __node_pointer __r;
1405 if (__comp(__f2->__value_, __f1->__value_))
1406 {
1407 __node_pointer __t = __f2;
1408 while (__t->__next_ != nullptr &&
1409 __comp(__t->__next_->__value_, __f1->__value_))
1410 __t = __t->__next_;
1411 __r = __f2;
1412 __f2 = __t->__next_;
1413 __t->__next_ = __f1;
1414 }
1415 else
1416 __r = __f1;
1417 __node_pointer __p = __f1;
1418 __f1 = __f1->__next_;
1419 while (__f1 != nullptr && __f2 != nullptr)
1420 {
1421 if (__comp(__f2->__value_, __f1->__value_))
1422 {
1423 __node_pointer __t = __f2;
1424 while (__t->__next_ != nullptr &&
1425 __comp(__t->__next_->__value_, __f1->__value_))
1426 __t = __t->__next_;
1427 __p->__next_ = __f2;
1428 __f2 = __t->__next_;
1429 __t->__next_ = __f1;
1430 }
1431 __p = __f1;
1432 __f1 = __f1->__next_;
1433 }
1434 if (__f2 != nullptr)
1435 __p->__next_ = __f2;
1436 return __r;
1437}
1438
1439template <class _Tp, class _Alloc>
1440template <class _Compare>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001441inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001442void
1443forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1444{
1445 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1446 _STD::distance(begin(), end()), __comp);
1447}
1448
1449template <class _Tp, class _Alloc>
1450template <class _Compare>
1451typename forward_list<_Tp, _Alloc>::__node_pointer
1452forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1453 _Compare& __comp)
1454{
1455 switch (__sz)
1456 {
1457 case 0:
1458 case 1:
1459 return __f1;
1460 case 2:
1461 if (__comp(__f1->__next_->__value_, __f1->__value_))
1462 {
1463 __node_pointer __t = __f1->__next_;
1464 __t->__next_ = __f1;
1465 __f1->__next_ = nullptr;
1466 __f1 = __t;
1467 }
1468 return __f1;
1469 }
1470 difference_type __sz1 = __sz / 2;
1471 difference_type __sz2 = __sz - __sz1;
Howard Hinnanta0fe8c42011-02-14 19:12:38 +00001472 __node_pointer __t = _STD::next(iterator(__f1), __sz1 - 1).__ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001473 __node_pointer __f2 = __t->__next_;
1474 __t->__next_ = nullptr;
1475 return __merge(__sort(__f1, __sz1, __comp),
1476 __sort(__f2, __sz2, __comp), __comp);
1477}
1478
1479template <class _Tp, class _Alloc>
1480void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001481forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001482{
1483 __node_pointer __p = base::__before_begin()->__next_;
1484 if (__p != nullptr)
1485 {
1486 __node_pointer __f = __p->__next_;
1487 __p->__next_ = nullptr;
1488 while (__f != nullptr)
1489 {
1490 __node_pointer __t = __f->__next_;
1491 __f->__next_ = __p;
1492 __p = __f;
1493 __f = __t;
1494 }
1495 base::__before_begin()->__next_ = __p;
1496 }
1497}
1498
1499template <class _Tp, class _Alloc>
1500bool operator==(const forward_list<_Tp, _Alloc>& __x,
1501 const forward_list<_Tp, _Alloc>& __y)
1502{
1503 typedef forward_list<_Tp, _Alloc> _C;
1504 typedef typename _C::const_iterator _I;
1505 _I __ix = __x.begin();
1506 _I __ex = __x.end();
1507 _I __iy = __y.begin();
1508 _I __ey = __y.end();
1509 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1510 if (!(*__ix == *__iy))
1511 return false;
1512 return (__ix == __ex) == (__iy == __ey);
1513}
1514
1515template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001516inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001517bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1518 const forward_list<_Tp, _Alloc>& __y)
1519{
1520 return !(__x == __y);
1521}
1522
1523template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001524inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001525bool operator< (const forward_list<_Tp, _Alloc>& __x,
1526 const forward_list<_Tp, _Alloc>& __y)
1527{
1528 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1529 __y.begin(), __y.end());
1530}
1531
1532template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001533inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001534bool operator> (const forward_list<_Tp, _Alloc>& __x,
1535 const forward_list<_Tp, _Alloc>& __y)
1536{
1537 return __y < __x;
1538}
1539
1540template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001541inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001542bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1543 const forward_list<_Tp, _Alloc>& __y)
1544{
1545 return !(__x < __y);
1546}
1547
1548template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001549inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001550bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1551 const forward_list<_Tp, _Alloc>& __y)
1552{
1553 return !(__y < __x);
1554}
1555
1556template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001557inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001558void
1559swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1560{
1561 __x.swap(__y);
1562}
1563
1564_LIBCPP_END_NAMESPACE_STD
1565
1566#endif // _LIBCPP_FORWARD_LIST