blob: 61fe290d9e2f1f342555b04032b10c73e178b23c [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------- forward_list ---------------------------------===//
3//
Howard Hinnant5b08a8a2010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:16 +00005//
Howard Hinnant412dbeb2010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FORWARD_LIST
12#define _LIBCPP_FORWARD_LIST
13
14/*
15 forward_list synopsis
16
17namespace std
18{
19
20template <class T, class Allocator = allocator<T>>
21class forward_list
22{
23public:
24 typedef T value_type;
25 typedef Allocator allocator_type;
26
27 typedef value_type& reference;
28 typedef const value_type& const_reference;
29 typedef typename allocator_traits<allocator_type>::pointer pointer;
30 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
31 typedef typename allocator_traits<allocator_type>::size_type size_type;
32 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
33
34 typedef <details> iterator;
35 typedef <details> const_iterator;
36
Howard Hinnant91a47502011-06-03 16:20:53 +000037 forward_list()
38 noexcept(is_nothrow_default_constructible<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000039 explicit forward_list(const allocator_type& a);
40 explicit forward_list(size_type n);
41 forward_list(size_type n, const value_type& v);
42 forward_list(size_type n, const value_type& v, const allocator_type& a);
43 template <class InputIterator>
44 forward_list(InputIterator first, InputIterator last);
45 template <class InputIterator>
46 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
47 forward_list(const forward_list& x);
48 forward_list(const forward_list& x, const allocator_type& a);
Howard Hinnant91a47502011-06-03 16:20:53 +000049 forward_list(forward_list&& x)
50 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000051 forward_list(forward_list&& x, const allocator_type& a);
52 forward_list(initializer_list<value_type> il);
53 forward_list(initializer_list<value_type> il, const allocator_type& a);
54
55 ~forward_list();
56
57 forward_list& operator=(const forward_list& x);
Howard Hinnant91a47502011-06-03 16:20:53 +000058 forward_list& operator=(forward_list&& x)
59 noexcept(
60 allocator_type::propagate_on_container_move_assignment::value &&
61 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +000062 forward_list& operator=(initializer_list<value_type> il);
63
64 template <class InputIterator>
65 void assign(InputIterator first, InputIterator last);
66 void assign(size_type n, const value_type& v);
67 void assign(initializer_list<value_type> il);
68
Howard Hinnantf9dc2832011-06-02 16:44:28 +000069 allocator_type get_allocator() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000070
Howard Hinnantf9dc2832011-06-02 16:44:28 +000071 iterator begin() noexcept;
72 const_iterator begin() const noexcept;
73 iterator end() noexcept;
74 const_iterator end() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000075
Howard Hinnantf9dc2832011-06-02 16:44:28 +000076 const_iterator cbegin() const noexcept;
77 const_iterator cend() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000078
Howard Hinnantf9dc2832011-06-02 16:44:28 +000079 iterator before_begin() noexcept;
80 const_iterator before_begin() const noexcept;
81 const_iterator cbefore_begin() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000082
Howard Hinnantf9dc2832011-06-02 16:44:28 +000083 bool empty() const noexcept;
84 size_type max_size() const noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +000085
86 reference front();
87 const_reference front() const;
88
89 template <class... Args> void emplace_front(Args&&... args);
90 void push_front(const value_type& v);
91 void push_front(value_type&& v);
92
93 void pop_front();
94
95 template <class... Args>
96 iterator emplace_after(const_iterator p, Args&&... args);
97 iterator insert_after(const_iterator p, const value_type& v);
98 iterator insert_after(const_iterator p, value_type&& v);
99 iterator insert_after(const_iterator p, size_type n, const value_type& v);
100 template <class InputIterator>
101 iterator insert_after(const_iterator p,
102 InputIterator first, InputIterator last);
103 iterator insert_after(const_iterator p, initializer_list<value_type> il);
104
Howard Hinnant3db88032010-08-21 20:58:44 +0000105 iterator erase_after(const_iterator p);
106 iterator erase_after(const_iterator first, const_iterator last);
Howard Hinnant3e519522010-05-11 19:42:16 +0000107
Howard Hinnant91a47502011-06-03 16:20:53 +0000108 void swap(forward_list& x)
109 noexcept(!allocator_type::propagate_on_container_swap::value ||
110 __is_nothrow_swappable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000111
112 void resize(size_type n);
113 void resize(size_type n, const value_type& v);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000114 void clear() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000115
Howard Hinnanteb92df72011-01-27 21:00:35 +0000116 void splice_after(const_iterator p, forward_list& x);
Howard Hinnant3e519522010-05-11 19:42:16 +0000117 void splice_after(const_iterator p, forward_list&& x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000118 void splice_after(const_iterator p, forward_list& x, const_iterator i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000119 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000120 void splice_after(const_iterator p, forward_list& x,
121 const_iterator first, const_iterator last);
Howard Hinnant3e519522010-05-11 19:42:16 +0000122 void splice_after(const_iterator p, forward_list&& x,
123 const_iterator first, const_iterator last);
124 void remove(const value_type& v);
125 template <class Predicate> void remove_if(Predicate pred);
126 void unique();
127 template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000128 void merge(forward_list& x);
Howard Hinnant3e519522010-05-11 19:42:16 +0000129 void merge(forward_list&& x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000130 template <class Compare> void merge(forward_list& x, Compare comp);
Howard Hinnant3e519522010-05-11 19:42:16 +0000131 template <class Compare> void merge(forward_list&& x, Compare comp);
132 void sort();
133 template <class Compare> void sort(Compare comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000134 void reverse() noexcept;
Howard Hinnant3e519522010-05-11 19:42:16 +0000135};
136
137template <class T, class Allocator>
138 bool operator==(const forward_list<T, Allocator>& x,
139 const forward_list<T, Allocator>& y);
140
141template <class T, class Allocator>
142 bool operator< (const forward_list<T, Allocator>& x,
143 const forward_list<T, Allocator>& y);
144
145template <class T, class Allocator>
146 bool operator!=(const forward_list<T, Allocator>& x,
147 const forward_list<T, Allocator>& y);
148
149template <class T, class Allocator>
150 bool operator> (const forward_list<T, Allocator>& x,
151 const forward_list<T, Allocator>& y);
152
153template <class T, class Allocator>
154 bool operator>=(const forward_list<T, Allocator>& x,
155 const forward_list<T, Allocator>& y);
156
157template <class T, class Allocator>
158 bool operator<=(const forward_list<T, Allocator>& x,
159 const forward_list<T, Allocator>& y);
160
161template <class T, class Allocator>
Howard Hinnant91a47502011-06-03 16:20:53 +0000162 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
Howard Hinnant45900102011-06-03 17:30:28 +0000163 noexcept(noexcept(x.swap(y)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000164
165} // std
166
167*/
168
169#include <__config>
170
171#include <initializer_list>
172#include <memory>
173#include <limits>
174#include <iterator>
175#include <algorithm>
176
Howard Hinnant073458b2011-10-17 20:05:10 +0000177#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +0000178#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000179#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000180
181_LIBCPP_BEGIN_NAMESPACE_STD
182
Howard Hinnantce534202011-06-14 19:58:17 +0000183template <class _Tp, class _VoidPtr> struct __forward_list_node;
Howard Hinnant3e519522010-05-11 19:42:16 +0000184
185template <class _NodePtr>
186struct __forward_begin_node
187{
188 typedef __forward_begin_node __self;
189 typedef _NodePtr pointer;
190
191 pointer __next_;
192
Howard Hinnant0af133f2010-09-21 22:55:27 +0000193 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000194};
195
196template <class _Tp, class _VoidPtr>
197struct __forward_list_node
198 : public __forward_begin_node
199 <
200 typename pointer_traits<_VoidPtr>::template
201#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
202 rebind<__forward_list_node<_Tp, _VoidPtr> >
203#else
204 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
205#endif
206 >
207{
208 typedef _Tp value_type;
209
210 value_type __value_;
211};
212
Howard Hinnantce534202011-06-14 19:58:17 +0000213template<class _Tp, class _Alloc> class forward_list;
214template<class _NodeConstPtr> class __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000215
216template <class _NodePtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000217class _LIBCPP_VISIBLE __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000218{
219 typedef _NodePtr __node_pointer;
220
221 __node_pointer __ptr_;
222
Howard Hinnant0af133f2010-09-21 22:55:27 +0000223 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000224 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000225
226 template<class, class> friend class forward_list;
227 template<class> friend class __forward_list_const_iterator;
228
229public:
230 typedef forward_iterator_tag iterator_category;
231 typedef typename pointer_traits<__node_pointer>::element_type::value_type
232 value_type;
233 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000234 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000235 difference_type;
236 typedef typename pointer_traits<__node_pointer>::template
237#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
238 rebind<value_type>
239#else
240 rebind<value_type>::other
241#endif
242 pointer;
243
Howard Hinnant0af133f2010-09-21 22:55:27 +0000244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000245 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000246
Howard Hinnant0af133f2010-09-21 22:55:27 +0000247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000248 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000250 pointer operator->() const {return &__ptr_->__value_;}
251
Howard Hinnant0af133f2010-09-21 22:55:27 +0000252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000253 __forward_list_iterator& operator++()
254 {
255 __ptr_ = __ptr_->__next_;
256 return *this;
257 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000258 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000259 __forward_list_iterator operator++(int)
260 {
261 __forward_list_iterator __t(*this);
262 ++(*this);
263 return __t;
264 }
265
Howard Hinnant0af133f2010-09-21 22:55:27 +0000266 friend _LIBCPP_INLINE_VISIBILITY
267 bool operator==(const __forward_list_iterator& __x,
268 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000269 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000270 friend _LIBCPP_INLINE_VISIBILITY
271 bool operator!=(const __forward_list_iterator& __x,
272 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000273 {return !(__x == __y);}
274};
275
276template <class _NodeConstPtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000277class _LIBCPP_VISIBLE __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000278{
279 typedef _NodeConstPtr __node_const_pointer;
280
281 __node_const_pointer __ptr_;
282
Howard Hinnant0af133f2010-09-21 22:55:27 +0000283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000284 explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000285 : __ptr_(__p) {}
286
287 typedef typename remove_const
288 <
289 typename pointer_traits<__node_const_pointer>::element_type
290 >::type __node;
291 typedef typename pointer_traits<__node_const_pointer>::template
292#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
293 rebind<__node>
294#else
295 rebind<__node>::other
296#endif
297 __node_pointer;
298
299 template<class, class> friend class forward_list;
300
301public:
302 typedef forward_iterator_tag iterator_category;
303 typedef typename __node::value_type value_type;
304 typedef const value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000305 typedef typename pointer_traits<__node_const_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000306 difference_type;
307 typedef typename pointer_traits<__node_const_pointer>::template
308#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
309 rebind<const value_type>
310#else
311 rebind<const value_type>::other
312#endif
313 pointer;
314
Howard Hinnant0af133f2010-09-21 22:55:27 +0000315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000316 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000318 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000319 : __ptr_(__p.__ptr_) {}
320
Howard Hinnant0af133f2010-09-21 22:55:27 +0000321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000322 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000324 pointer operator->() const {return &__ptr_->__value_;}
325
Howard Hinnant0af133f2010-09-21 22:55:27 +0000326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000327 __forward_list_const_iterator& operator++()
328 {
329 __ptr_ = __ptr_->__next_;
330 return *this;
331 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000333 __forward_list_const_iterator operator++(int)
334 {
335 __forward_list_const_iterator __t(*this);
336 ++(*this);
337 return __t;
338 }
339
Howard Hinnant0af133f2010-09-21 22:55:27 +0000340 friend _LIBCPP_INLINE_VISIBILITY
341 bool operator==(const __forward_list_const_iterator& __x,
342 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000343 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000344 friend _LIBCPP_INLINE_VISIBILITY
345 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000346 const __forward_list_const_iterator& __y)
347 {return !(__x == __y);}
348};
349
350template <class _Tp, class _Alloc>
351class __forward_list_base
352{
353protected:
354 typedef _Tp value_type;
355 typedef _Alloc allocator_type;
356
357 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
358 typedef __forward_list_node<value_type, void_pointer> __node;
359 typedef typename __node::__self __begin_node;
360 typedef typename allocator_traits<allocator_type>::template
361#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
362 rebind_alloc<__node>
363#else
364 rebind_alloc<__node>::other
365#endif
366 __node_allocator;
367 typedef allocator_traits<__node_allocator> __node_traits;
368 typedef typename __node_traits::pointer __node_pointer;
369 typedef typename __node_traits::const_pointer __node_const_pointer;
370
371 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
372
Howard Hinnant0af133f2010-09-21 22:55:27 +0000373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000374 __node_pointer __before_begin() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000375 {return pointer_traits<__node_pointer>::pointer_to(
376 static_cast<__node&>(__before_begin_.first()));}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000377 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000378 __node_const_pointer __before_begin() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000379 {return pointer_traits<__node_const_pointer>::pointer_to(
380 static_cast<const __node&>(__before_begin_.first()));}
381
Howard Hinnant0af133f2010-09-21 22:55:27 +0000382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000383 __node_allocator& __alloc() _NOEXCEPT
384 {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000386 const __node_allocator& __alloc() const _NOEXCEPT
387 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000388
389 typedef __forward_list_iterator<__node_pointer> iterator;
390 typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
391
Howard Hinnant0af133f2010-09-21 22:55:27 +0000392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000393 __forward_list_base()
Howard Hinnant91a47502011-06-03 16:20:53 +0000394 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000395 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000396 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000397 __forward_list_base(const allocator_type& __a)
398 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
399
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000400#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000401public:
402 __forward_list_base(__forward_list_base&& __x)
403 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000404 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000405#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000406
407private:
408 __forward_list_base(const __forward_list_base&);
409 __forward_list_base& operator=(const __forward_list_base&);
Howard Hinnant3e519522010-05-11 19:42:16 +0000410
Howard Hinnant91a47502011-06-03 16:20:53 +0000411public:
Howard Hinnant3e519522010-05-11 19:42:16 +0000412 ~__forward_list_base();
413
Howard Hinnant91a47502011-06-03 16:20:53 +0000414protected:
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)
417 {__copy_assign_alloc(__x, integral_constant<bool,
418 __node_traits::propagate_on_container_copy_assignment::value>());}
419
Howard Hinnant0af133f2010-09-21 22:55:27 +0000420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000421 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000422 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
423 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000424 {__move_assign_alloc(__x, integral_constant<bool,
425 __node_traits::propagate_on_container_move_assignment::value>());}
426
Howard Hinnant91a47502011-06-03 16:20:53 +0000427public:
428 void swap(__forward_list_base& __x)
429 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
430 __is_nothrow_swappable<__node_allocator>::value);
431protected:
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000432 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000433
434private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000436 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000437 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000438 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
439 {
440 if (__alloc() != __x.__alloc())
441 clear();
442 __alloc() = __x.__alloc();
443 }
444
Howard Hinnant0af133f2010-09-21 22:55:27 +0000445 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000446 void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
447 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000449 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000450 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000451 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000452
Howard Hinnant0af133f2010-09-21 22:55:27 +0000453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000454 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +0000455 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
456 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000457 {__swap_alloc(__x, __y, integral_constant<bool,
458 __node_traits::propagate_on_container_swap::value>());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000459 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000460 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
461 false_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000462 _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000463 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000464 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000465 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
466 true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000467 _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000468 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000469 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000470 swap(__x, __y);
471 }
472};
473
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000474#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000475
476template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000477inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000478__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000479 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000480 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnant3e519522010-05-11 19:42:16 +0000481{
482 __x.__before_begin()->__next_ = nullptr;
483}
484
485template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000486inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000487__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
488 const allocator_type& __a)
489 : __before_begin_(__begin_node(), __node_allocator(__a))
490{
491 if (__alloc() == __x.__alloc())
492 {
493 __before_begin()->__next_ = __x.__before_begin()->__next_;
494 __x.__before_begin()->__next_ = nullptr;
495 }
496}
497
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000498#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000499
500template <class _Tp, class _Alloc>
501__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
502{
503 clear();
504}
505
506template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000507inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000508void
509__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000510 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
511 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000512{
513 __swap_alloc(__alloc(), __x.__alloc());
Howard Hinnantce48a112011-06-30 21:18:19 +0000514 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000515 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
516}
517
518template <class _Tp, class _Alloc>
519void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000520__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000521{
522 __node_allocator& __a = __alloc();
523 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
524 {
525 __node_pointer __next = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000526 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000527 __node_traits::deallocate(__a, __p, 1);
528 __p = __next;
529 }
530 __before_begin()->__next_ = nullptr;
531}
532
533template <class _Tp, class _Alloc = allocator<_Tp> >
Howard Hinnant0af133f2010-09-21 22:55:27 +0000534class _LIBCPP_VISIBLE forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000535 : private __forward_list_base<_Tp, _Alloc>
536{
537 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnant91a47502011-06-03 16:20:53 +0000538 typedef typename base::__node_allocator __node_allocator;
539 typedef typename base::__node __node;
540 typedef typename base::__node_traits __node_traits;
541 typedef typename base::__node_pointer __node_pointer;
542
Howard Hinnant3e519522010-05-11 19:42:16 +0000543public:
544 typedef _Tp value_type;
545 typedef _Alloc allocator_type;
546
547 typedef value_type& reference;
548 typedef const value_type& const_reference;
549 typedef typename allocator_traits<allocator_type>::pointer pointer;
550 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
551 typedef typename allocator_traits<allocator_type>::size_type size_type;
552 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
553
554 typedef typename base::iterator iterator;
555 typedef typename base::const_iterator const_iterator;
556
Howard Hinnant91a47502011-06-03 16:20:53 +0000557 _LIBCPP_INLINE_VISIBILITY
558 forward_list()
559 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
560 {} // = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000561 explicit forward_list(const allocator_type& __a);
562 explicit forward_list(size_type __n);
563 forward_list(size_type __n, const value_type& __v);
564 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
565 template <class _InputIterator>
566 forward_list(_InputIterator __f, _InputIterator __l,
567 typename enable_if<
568 __is_input_iterator<_InputIterator>::value
569 >::type* = nullptr);
570 template <class _InputIterator>
571 forward_list(_InputIterator __f, _InputIterator __l,
572 const allocator_type& __a,
573 typename enable_if<
574 __is_input_iterator<_InputIterator>::value
575 >::type* = nullptr);
576 forward_list(const forward_list& __x);
577 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000578#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000580 forward_list(forward_list&& __x)
581 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000582 : base(_VSTD::move(__x)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000583 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000584#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54976f22011-08-12 21:56:02 +0000585#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000586 forward_list(initializer_list<value_type> __il);
587 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
Howard Hinnant54976f22011-08-12 21:56:02 +0000588#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000589
590 // ~forward_list() = default;
591
592 forward_list& operator=(const forward_list& __x);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000593#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000594 forward_list& operator=(forward_list&& __x)
595 _NOEXCEPT_(
596 __node_traits::propagate_on_container_move_assignment::value &&
597 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000598#endif
Howard Hinnant54976f22011-08-12 21:56:02 +0000599#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000600 forward_list& operator=(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000601#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000602
603 template <class _InputIterator>
604 typename enable_if
605 <
606 __is_input_iterator<_InputIterator>::value,
607 void
608 >::type
609 assign(_InputIterator __f, _InputIterator __l);
610 void assign(size_type __n, const value_type& __v);
Howard Hinnant54976f22011-08-12 21:56:02 +0000611#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000612 void assign(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000613#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000614
Howard Hinnant0af133f2010-09-21 22:55:27 +0000615 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000616 allocator_type get_allocator() const _NOEXCEPT
617 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000618
Howard Hinnant0af133f2010-09-21 22:55:27 +0000619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000620 iterator begin() _NOEXCEPT
621 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000623 const_iterator begin() const _NOEXCEPT
624 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000625 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000626 iterator end() _NOEXCEPT
627 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000628 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000629 const_iterator end() const _NOEXCEPT
630 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000631
Howard Hinnant0af133f2010-09-21 22:55:27 +0000632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000633 const_iterator cbegin() const _NOEXCEPT
634 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000635 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000636 const_iterator cend() const _NOEXCEPT
637 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000638
Howard Hinnant0af133f2010-09-21 22:55:27 +0000639 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000640 iterator before_begin() _NOEXCEPT
641 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000642 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000643 const_iterator before_begin() const _NOEXCEPT
644 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000646 const_iterator cbefore_begin() const _NOEXCEPT
647 {return const_iterator(base::__before_begin());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000648
Howard Hinnant0af133f2010-09-21 22:55:27 +0000649 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000650 bool empty() const _NOEXCEPT
651 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000652 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000653 size_type max_size() const _NOEXCEPT
654 {return numeric_limits<size_type>::max();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000655
Howard Hinnant0af133f2010-09-21 22:55:27 +0000656 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000657 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000658 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000659 const_reference front() const {return base::__before_begin()->__next_->__value_;}
660
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000661#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
662#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000663 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000664#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000665 void push_front(value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000666#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000667 void push_front(const value_type& __v);
668
669 void pop_front();
670
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000671#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
672#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000673 template <class... _Args>
674 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000675#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000676 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000677#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000678 iterator insert_after(const_iterator __p, const value_type& __v);
679 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
680 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000681 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000682 typename enable_if
683 <
684 __is_input_iterator<_InputIterator>::value,
685 iterator
686 >::type
687 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnant54976f22011-08-12 21:56:02 +0000688#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000689 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
690 {return insert_after(__p, __il.begin(), __il.end());}
Howard Hinnant54976f22011-08-12 21:56:02 +0000691#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000692
Howard Hinnant3db88032010-08-21 20:58:44 +0000693 iterator erase_after(const_iterator __p);
694 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000695
Howard Hinnant0af133f2010-09-21 22:55:27 +0000696 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000697 void swap(forward_list& __x)
698 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
699 __is_nothrow_swappable<__node_allocator>::value)
700 {base::swap(__x);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000701
702 void resize(size_type __n);
703 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000705 void clear() _NOEXCEPT {base::clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000706
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000707#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanteb92df72011-01-27 21:00:35 +0000708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000709 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000711 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000713 void splice_after(const_iterator __p, forward_list&& __x,
714 const_iterator __f, const_iterator __l);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000715#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000716 void splice_after(const_iterator __p, forward_list& __x);
717 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
718 void splice_after(const_iterator __p, forward_list& __x,
719 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000720 void remove(const value_type& __v);
721 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000723 void unique() {unique(__equal_to<value_type>());}
724 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000725#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000727 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
728 template <class _Compare>
729 _LIBCPP_INLINE_VISIBILITY
730 void merge(forward_list&& __x, _Compare __comp)
Howard Hinnantce48a112011-06-30 21:18:19 +0000731 {merge(__x, _VSTD::move(__comp));}
Howard Hinnanteb92df72011-01-27 21:00:35 +0000732#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000734 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
735 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000737 void sort() {sort(__less<value_type>());}
738 template <class _Compare> void sort(_Compare __comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000739 void reverse() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000740
741private:
Howard Hinnant3e519522010-05-11 19:42:16 +0000742
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000743#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000744 void __move_assign(forward_list& __x, true_type)
745 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000746 void __move_assign(forward_list& __x, false_type);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000747#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000748
749 template <class _Compare>
750 static
751 __node_pointer
752 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
753
754 template <class _Compare>
755 static
756 __node_pointer
757 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
758};
759
760template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000761inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000762forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
763 : base(__a)
764{
765}
766
767template <class _Tp, class _Alloc>
768forward_list<_Tp, _Alloc>::forward_list(size_type __n)
769{
770 if (__n > 0)
771 {
772 __node_allocator& __a = base::__alloc();
773 typedef __allocator_destructor<__node_allocator> _D;
774 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
775 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
776 __p = __p->__next_)
777 {
778 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000779 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000780 __h->__next_ = nullptr;
781 __p->__next_ = __h.release();
782 }
783 }
784}
785
786template <class _Tp, class _Alloc>
787forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
788{
789 insert_after(cbefore_begin(), __n, __v);
790}
791
792template <class _Tp, class _Alloc>
793forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
794 const allocator_type& __a)
795 : base(__a)
796{
797 insert_after(cbefore_begin(), __n, __v);
798}
799
800template <class _Tp, class _Alloc>
801template <class _InputIterator>
802forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
803 typename enable_if<
804 __is_input_iterator<_InputIterator>::value
805 >::type*)
806{
807 insert_after(cbefore_begin(), __f, __l);
808}
809
810template <class _Tp, class _Alloc>
811template <class _InputIterator>
812forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
813 const allocator_type& __a,
814 typename enable_if<
815 __is_input_iterator<_InputIterator>::value
816 >::type*)
817 : base(__a)
818{
819 insert_after(cbefore_begin(), __f, __l);
820}
821
822template <class _Tp, class _Alloc>
823forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
824 : base(allocator_type(
825 __node_traits::select_on_container_copy_construction(__x.__alloc())
826 )
827 )
828{
829 insert_after(cbefore_begin(), __x.begin(), __x.end());
830}
831
832template <class _Tp, class _Alloc>
833forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
834 const allocator_type& __a)
835 : base(__a)
836{
837 insert_after(cbefore_begin(), __x.begin(), __x.end());
838}
839
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000840#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000841
842template <class _Tp, class _Alloc>
843forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
844 const allocator_type& __a)
Howard Hinnantce48a112011-06-30 21:18:19 +0000845 : base(_VSTD::move(__x), __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000846{
847 if (base::__alloc() != __x.__alloc())
848 {
849 typedef move_iterator<iterator> _I;
850 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
851 }
852}
853
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000854#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000855
Howard Hinnant54976f22011-08-12 21:56:02 +0000856#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
857
Howard Hinnant3e519522010-05-11 19:42:16 +0000858template <class _Tp, class _Alloc>
859forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
860{
861 insert_after(cbefore_begin(), __il.begin(), __il.end());
862}
863
864template <class _Tp, class _Alloc>
865forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
866 const allocator_type& __a)
867 : base(__a)
868{
869 insert_after(cbefore_begin(), __il.begin(), __il.end());
870}
871
Howard Hinnant54976f22011-08-12 21:56:02 +0000872#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
873
Howard Hinnant3e519522010-05-11 19:42:16 +0000874template <class _Tp, class _Alloc>
875forward_list<_Tp, _Alloc>&
876forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
877{
878 if (this != &__x)
879 {
880 base::__copy_assign_alloc(__x);
881 assign(__x.begin(), __x.end());
882 }
883 return *this;
884}
885
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000886#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000887
888template <class _Tp, class _Alloc>
889void
890forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000891 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000892{
893 clear();
894 base::__move_assign_alloc(__x);
895 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
896 __x.__before_begin()->__next_ = nullptr;
897}
898
899template <class _Tp, class _Alloc>
900void
901forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
902{
903 if (base::__alloc() == __x.__alloc())
904 __move_assign(__x, true_type());
905 else
906 {
907 typedef move_iterator<iterator> _I;
908 assign(_I(__x.begin()), _I(__x.end()));
909 }
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 +0000914forward_list<_Tp, _Alloc>&
915forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000916 _NOEXCEPT_(
917 __node_traits::propagate_on_container_move_assignment::value &&
918 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000919{
920 __move_assign(__x, integral_constant<bool,
921 __node_traits::propagate_on_container_move_assignment::value>());
922 return *this;
923}
924
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000925#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000926
Howard Hinnant54976f22011-08-12 21:56:02 +0000927#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
928
Howard Hinnant3e519522010-05-11 19:42:16 +0000929template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000930inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000931forward_list<_Tp, _Alloc>&
932forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
933{
934 assign(__il.begin(), __il.end());
935 return *this;
936}
937
Howard Hinnant54976f22011-08-12 21:56:02 +0000938#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
939
Howard Hinnant3e519522010-05-11 19:42:16 +0000940template <class _Tp, class _Alloc>
941template <class _InputIterator>
942typename enable_if
943<
944 __is_input_iterator<_InputIterator>::value,
945 void
946>::type
947forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
948{
949 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +0000950 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000951 iterator __e = end();
952 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
953 *__j = *__f;
954 if (__j == __e)
955 insert_after(__i, __f, __l);
956 else
957 erase_after(__i, __e);
958}
959
960template <class _Tp, class _Alloc>
961void
962forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
963{
964 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +0000965 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000966 iterator __e = end();
967 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
968 *__j = __v;
969 if (__j == __e)
970 insert_after(__i, __n, __v);
971 else
972 erase_after(__i, __e);
973}
974
Howard Hinnant54976f22011-08-12 21:56:02 +0000975#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
976
Howard Hinnant3e519522010-05-11 19:42:16 +0000977template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000978inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000979void
980forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
981{
982 assign(__il.begin(), __il.end());
983}
984
Howard Hinnant54976f22011-08-12 21:56:02 +0000985#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
986
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000987#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
988#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000989
990template <class _Tp, class _Alloc>
991template <class... _Args>
992void
993forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
994{
995 __node_allocator& __a = base::__alloc();
996 typedef __allocator_destructor<__node_allocator> _D;
997 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000998 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
999 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001000 __h->__next_ = base::__before_begin()->__next_;
1001 base::__before_begin()->__next_ = __h.release();
1002}
1003
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001004#endif // _LIBCPP_HAS_NO_VARIADICS
1005
Howard Hinnant3e519522010-05-11 19:42:16 +00001006template <class _Tp, class _Alloc>
1007void
1008forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1009{
1010 __node_allocator& __a = base::__alloc();
1011 typedef __allocator_destructor<__node_allocator> _D;
1012 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001013 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001014 __h->__next_ = base::__before_begin()->__next_;
1015 base::__before_begin()->__next_ = __h.release();
1016}
1017
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001018#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001019
1020template <class _Tp, class _Alloc>
1021void
1022forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1023{
1024 __node_allocator& __a = base::__alloc();
1025 typedef __allocator_destructor<__node_allocator> _D;
1026 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001027 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001028 __h->__next_ = base::__before_begin()->__next_;
1029 base::__before_begin()->__next_ = __h.release();
1030}
1031
1032template <class _Tp, class _Alloc>
1033void
1034forward_list<_Tp, _Alloc>::pop_front()
1035{
1036 __node_allocator& __a = base::__alloc();
1037 __node_pointer __p = base::__before_begin()->__next_;
1038 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001039 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001040 __node_traits::deallocate(__a, __p, 1);
1041}
1042
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001043#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1044#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +00001045
1046template <class _Tp, class _Alloc>
1047template <class... _Args>
1048typename forward_list<_Tp, _Alloc>::iterator
1049forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1050{
1051 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1052 __node_allocator& __a = base::__alloc();
1053 typedef __allocator_destructor<__node_allocator> _D;
1054 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001055 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1056 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001057 __h->__next_ = __r->__next_;
1058 __r->__next_ = __h.release();
1059 return iterator(__r->__next_);
1060}
1061
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001062#endif // _LIBCPP_HAS_NO_VARIADICS
1063
Howard Hinnant3e519522010-05-11 19:42:16 +00001064template <class _Tp, class _Alloc>
1065typename forward_list<_Tp, _Alloc>::iterator
1066forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1067{
1068 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1069 __node_allocator& __a = base::__alloc();
1070 typedef __allocator_destructor<__node_allocator> _D;
1071 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001072 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001073 __h->__next_ = __r->__next_;
1074 __r->__next_ = __h.release();
1075 return iterator(__r->__next_);
1076}
1077
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001078#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001079
1080template <class _Tp, class _Alloc>
1081typename forward_list<_Tp, _Alloc>::iterator
1082forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1083{
1084 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
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 Hinnantce48a112011-06-30 21:18:19 +00001088 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001089 __h->__next_ = __r->__next_;
1090 __r->__next_ = __h.release();
1091 return iterator(__r->__next_);
1092}
1093
1094template <class _Tp, class _Alloc>
1095typename forward_list<_Tp, _Alloc>::iterator
1096forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1097 const value_type& __v)
1098{
Howard Hinnante57dc142010-08-19 17:40:04 +00001099 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001100 if (__n > 0)
1101 {
1102 __node_allocator& __a = base::__alloc();
1103 typedef __allocator_destructor<__node_allocator> _D;
1104 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001105 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001106 __node_pointer __first = __h.release();
1107 __node_pointer __last = __first;
1108#ifndef _LIBCPP_NO_EXCEPTIONS
1109 try
1110 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001111#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001112 for (--__n; __n != 0; --__n, __last = __last->__next_)
1113 {
1114 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001115 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001116 __last->__next_ = __h.release();
1117 }
1118#ifndef _LIBCPP_NO_EXCEPTIONS
1119 }
1120 catch (...)
1121 {
1122 while (__first != nullptr)
1123 {
1124 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001125 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001126 __node_traits::deallocate(__a, __first, 1);
1127 __first = __next;
1128 }
1129 throw;
1130 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001131#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001132 __last->__next_ = __r->__next_;
1133 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001134 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001135 }
1136 return iterator(__r);
1137}
1138
1139template <class _Tp, class _Alloc>
1140template <class _InputIterator>
1141typename enable_if
1142<
1143 __is_input_iterator<_InputIterator>::value,
1144 typename forward_list<_Tp, _Alloc>::iterator
1145>::type
1146forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1147 _InputIterator __f, _InputIterator __l)
1148{
Howard Hinnante57dc142010-08-19 17:40:04 +00001149 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001150 if (__f != __l)
1151 {
1152 __node_allocator& __a = base::__alloc();
1153 typedef __allocator_destructor<__node_allocator> _D;
1154 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001155 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001156 __node_pointer __first = __h.release();
1157 __node_pointer __last = __first;
1158#ifndef _LIBCPP_NO_EXCEPTIONS
1159 try
1160 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001161#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001162 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1163 {
1164 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001165 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001166 __last->__next_ = __h.release();
1167 }
1168#ifndef _LIBCPP_NO_EXCEPTIONS
1169 }
1170 catch (...)
1171 {
1172 while (__first != nullptr)
1173 {
1174 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001175 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001176 __node_traits::deallocate(__a, __first, 1);
1177 __first = __next;
1178 }
1179 throw;
1180 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001181#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001182 __last->__next_ = __r->__next_;
1183 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001184 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001185 }
1186 return iterator(__r);
1187}
1188
1189template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001190typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001191forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1192{
1193 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1194 __node_pointer __n = __p->__next_;
1195 __p->__next_ = __n->__next_;
1196 __node_allocator& __a = base::__alloc();
Howard Hinnantce48a112011-06-30 21:18:19 +00001197 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001198 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001199 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001200}
1201
1202template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001203typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001204forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1205{
Howard Hinnant3db88032010-08-21 20:58:44 +00001206 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001207 if (__f != __l)
1208 {
1209 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1210 __node_pointer __n = __p->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001211 if (__n != __e)
1212 {
1213 __p->__next_ = __e;
1214 __node_allocator& __a = base::__alloc();
1215 do
1216 {
1217 __p = __n->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001218 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001219 __node_traits::deallocate(__a, __n, 1);
1220 __n = __p;
1221 } while (__n != __e);
1222 }
1223 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001224 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001225}
1226
1227template <class _Tp, class _Alloc>
1228void
1229forward_list<_Tp, _Alloc>::resize(size_type __n)
1230{
1231 size_type __sz = 0;
1232 iterator __p = before_begin();
1233 iterator __i = begin();
1234 iterator __e = end();
1235 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1236 ;
1237 if (__i != __e)
1238 erase_after(__p, __e);
1239 else
1240 {
1241 __n -= __sz;
1242 if (__n > 0)
1243 {
1244 __node_allocator& __a = base::__alloc();
1245 typedef __allocator_destructor<__node_allocator> _D;
1246 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1247 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1248 __ptr = __ptr->__next_)
1249 {
1250 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001251 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001252 __h->__next_ = nullptr;
1253 __ptr->__next_ = __h.release();
1254 }
1255 }
1256 }
1257}
1258
1259template <class _Tp, class _Alloc>
1260void
1261forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1262{
1263 size_type __sz = 0;
1264 iterator __p = before_begin();
1265 iterator __i = begin();
1266 iterator __e = end();
1267 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1268 ;
1269 if (__i != __e)
1270 erase_after(__p, __e);
1271 else
1272 {
1273 __n -= __sz;
1274 if (__n > 0)
1275 {
1276 __node_allocator& __a = base::__alloc();
1277 typedef __allocator_destructor<__node_allocator> _D;
1278 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1279 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1280 __ptr = __ptr->__next_)
1281 {
1282 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001283 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001284 __h->__next_ = nullptr;
1285 __ptr->__next_ = __h.release();
1286 }
1287 }
1288 }
1289}
1290
1291template <class _Tp, class _Alloc>
1292void
1293forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001294 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001295{
1296 if (!__x.empty())
1297 {
1298 if (__p.__ptr_->__next_ != nullptr)
1299 {
1300 const_iterator __lm1 = __x.before_begin();
1301 while (__lm1.__ptr_->__next_ != nullptr)
1302 ++__lm1;
1303 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1304 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1305 }
1306 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1307 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1308 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1309 }
1310}
1311
1312template <class _Tp, class _Alloc>
1313void
1314forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001315 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001316 const_iterator __i)
1317{
Howard Hinnantce48a112011-06-30 21:18:19 +00001318 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001319 if (__p != __i && __p != __lm1)
1320 {
1321 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1322 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1323 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1324 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1325 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1326 const_cast<__node_pointer>(__lm1.__ptr_);
1327 }
1328}
1329
1330template <class _Tp, class _Alloc>
1331void
1332forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001333 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001334 const_iterator __f, const_iterator __l)
1335{
1336 if (__f != __l && __p != __f)
1337 {
1338 const_iterator __lm1 = __f;
1339 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1340 ++__lm1;
1341 if (__f != __lm1)
1342 {
1343 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1344 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1345 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1346 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1347 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1348 const_cast<__node_pointer>(__l.__ptr_);
1349 }
1350 }
1351}
1352
Howard Hinnanteb92df72011-01-27 21:00:35 +00001353#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1354
1355template <class _Tp, class _Alloc>
1356inline _LIBCPP_INLINE_VISIBILITY
1357void
1358forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1359 forward_list&& __x)
1360{
1361 splice_after(__p, __x);
1362}
1363
1364template <class _Tp, class _Alloc>
1365inline _LIBCPP_INLINE_VISIBILITY
1366void
1367forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1368 forward_list&& __x,
1369 const_iterator __i)
1370{
1371 splice_after(__p, __x, __i);
1372}
1373
1374template <class _Tp, class _Alloc>
1375inline _LIBCPP_INLINE_VISIBILITY
1376void
1377forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1378 forward_list&& __x,
1379 const_iterator __f, const_iterator __l)
1380{
1381 splice_after(__p, __x, __f, __l);
1382}
1383
1384#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1385
Howard Hinnant3e519522010-05-11 19:42:16 +00001386template <class _Tp, class _Alloc>
1387void
1388forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1389{
1390 iterator __e = end();
1391 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1392 {
1393 if (__i.__ptr_->__next_->__value_ == __v)
1394 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001395 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001396 for (; __j != __e && *__j == __v; ++__j)
1397 ;
1398 erase_after(__i, __j);
1399 if (__j == __e)
1400 break;
1401 __i = __j;
1402 }
1403 else
1404 ++__i;
1405 }
1406}
1407
1408template <class _Tp, class _Alloc>
1409template <class _Predicate>
1410void
1411forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1412{
1413 iterator __e = end();
1414 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1415 {
1416 if (__pred(__i.__ptr_->__next_->__value_))
1417 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001418 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001419 for (; __j != __e && __pred(*__j); ++__j)
1420 ;
1421 erase_after(__i, __j);
1422 if (__j == __e)
1423 break;
1424 __i = __j;
1425 }
1426 else
1427 ++__i;
1428 }
1429}
1430
1431template <class _Tp, class _Alloc>
1432template <class _BinaryPredicate>
1433void
1434forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1435{
1436 for (iterator __i = begin(), __e = end(); __i != __e;)
1437 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001438 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001439 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1440 ;
1441 if (__i.__ptr_->__next_ != __j.__ptr_)
1442 erase_after(__i, __j);
1443 __i = __j;
1444 }
1445}
1446
1447template <class _Tp, class _Alloc>
1448template <class _Compare>
1449void
Howard Hinnant3e519522010-05-11 19:42:16 +00001450forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001451{
1452 if (this != &__x)
1453 {
1454 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1455 __x.__before_begin()->__next_,
1456 __comp);
1457 __x.__before_begin()->__next_ = nullptr;
1458 }
1459}
1460
1461template <class _Tp, class _Alloc>
1462template <class _Compare>
1463typename forward_list<_Tp, _Alloc>::__node_pointer
1464forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1465 _Compare& __comp)
1466{
1467 if (__f1 == nullptr)
1468 return __f2;
1469 if (__f2 == nullptr)
1470 return __f1;
1471 __node_pointer __r;
1472 if (__comp(__f2->__value_, __f1->__value_))
1473 {
1474 __node_pointer __t = __f2;
1475 while (__t->__next_ != nullptr &&
1476 __comp(__t->__next_->__value_, __f1->__value_))
1477 __t = __t->__next_;
1478 __r = __f2;
1479 __f2 = __t->__next_;
1480 __t->__next_ = __f1;
1481 }
1482 else
1483 __r = __f1;
1484 __node_pointer __p = __f1;
1485 __f1 = __f1->__next_;
1486 while (__f1 != nullptr && __f2 != nullptr)
1487 {
1488 if (__comp(__f2->__value_, __f1->__value_))
1489 {
1490 __node_pointer __t = __f2;
1491 while (__t->__next_ != nullptr &&
1492 __comp(__t->__next_->__value_, __f1->__value_))
1493 __t = __t->__next_;
1494 __p->__next_ = __f2;
1495 __f2 = __t->__next_;
1496 __t->__next_ = __f1;
1497 }
1498 __p = __f1;
1499 __f1 = __f1->__next_;
1500 }
1501 if (__f2 != nullptr)
1502 __p->__next_ = __f2;
1503 return __r;
1504}
1505
1506template <class _Tp, class _Alloc>
1507template <class _Compare>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001508inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001509void
1510forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1511{
1512 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnantce48a112011-06-30 21:18:19 +00001513 _VSTD::distance(begin(), end()), __comp);
Howard Hinnant3e519522010-05-11 19:42:16 +00001514}
1515
1516template <class _Tp, class _Alloc>
1517template <class _Compare>
1518typename forward_list<_Tp, _Alloc>::__node_pointer
1519forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1520 _Compare& __comp)
1521{
1522 switch (__sz)
1523 {
1524 case 0:
1525 case 1:
1526 return __f1;
1527 case 2:
1528 if (__comp(__f1->__next_->__value_, __f1->__value_))
1529 {
1530 __node_pointer __t = __f1->__next_;
1531 __t->__next_ = __f1;
1532 __f1->__next_ = nullptr;
1533 __f1 = __t;
1534 }
1535 return __f1;
1536 }
1537 difference_type __sz1 = __sz / 2;
1538 difference_type __sz2 = __sz - __sz1;
Howard Hinnantce48a112011-06-30 21:18:19 +00001539 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001540 __node_pointer __f2 = __t->__next_;
1541 __t->__next_ = nullptr;
1542 return __merge(__sort(__f1, __sz1, __comp),
1543 __sort(__f2, __sz2, __comp), __comp);
1544}
1545
1546template <class _Tp, class _Alloc>
1547void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001548forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001549{
1550 __node_pointer __p = base::__before_begin()->__next_;
1551 if (__p != nullptr)
1552 {
1553 __node_pointer __f = __p->__next_;
1554 __p->__next_ = nullptr;
1555 while (__f != nullptr)
1556 {
1557 __node_pointer __t = __f->__next_;
1558 __f->__next_ = __p;
1559 __p = __f;
1560 __f = __t;
1561 }
1562 base::__before_begin()->__next_ = __p;
1563 }
1564}
1565
1566template <class _Tp, class _Alloc>
1567bool operator==(const forward_list<_Tp, _Alloc>& __x,
1568 const forward_list<_Tp, _Alloc>& __y)
1569{
1570 typedef forward_list<_Tp, _Alloc> _C;
1571 typedef typename _C::const_iterator _I;
1572 _I __ix = __x.begin();
1573 _I __ex = __x.end();
1574 _I __iy = __y.begin();
1575 _I __ey = __y.end();
1576 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1577 if (!(*__ix == *__iy))
1578 return false;
1579 return (__ix == __ex) == (__iy == __ey);
1580}
1581
1582template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001583inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001584bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1585 const forward_list<_Tp, _Alloc>& __y)
1586{
1587 return !(__x == __y);
1588}
1589
1590template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001591inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001592bool operator< (const forward_list<_Tp, _Alloc>& __x,
1593 const forward_list<_Tp, _Alloc>& __y)
1594{
Howard Hinnantce48a112011-06-30 21:18:19 +00001595 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnant3e519522010-05-11 19:42:16 +00001596 __y.begin(), __y.end());
1597}
1598
1599template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001600inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001601bool operator> (const forward_list<_Tp, _Alloc>& __x,
1602 const forward_list<_Tp, _Alloc>& __y)
1603{
1604 return __y < __x;
1605}
1606
1607template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001608inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001609bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1610 const forward_list<_Tp, _Alloc>& __y)
1611{
1612 return !(__x < __y);
1613}
1614
1615template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001616inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001617bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1618 const forward_list<_Tp, _Alloc>& __y)
1619{
1620 return !(__y < __x);
1621}
1622
1623template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001624inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001625void
1626swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +00001627 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001628{
1629 __x.swap(__y);
1630}
1631
1632_LIBCPP_END_NAMESPACE_STD
1633
1634#endif // _LIBCPP_FORWARD_LIST