blob: 0dd6bb241b069c83b194a74a89cc1a56802be96f [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
177#pragma GCC system_header
178
179_LIBCPP_BEGIN_NAMESPACE_STD
180
Howard Hinnantce534202011-06-14 19:58:17 +0000181template <class _Tp, class _VoidPtr> struct __forward_list_node;
Howard Hinnant3e519522010-05-11 19:42:16 +0000182
183template <class _NodePtr>
184struct __forward_begin_node
185{
186 typedef __forward_begin_node __self;
187 typedef _NodePtr pointer;
188
189 pointer __next_;
190
Howard Hinnant0af133f2010-09-21 22:55:27 +0000191 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000192};
193
194template <class _Tp, class _VoidPtr>
195struct __forward_list_node
196 : public __forward_begin_node
197 <
198 typename pointer_traits<_VoidPtr>::template
199#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
200 rebind<__forward_list_node<_Tp, _VoidPtr> >
201#else
202 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
203#endif
204 >
205{
206 typedef _Tp value_type;
207
208 value_type __value_;
209};
210
Howard Hinnantce534202011-06-14 19:58:17 +0000211template<class _Tp, class _Alloc> class forward_list;
212template<class _NodeConstPtr> class __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000213
214template <class _NodePtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000215class _LIBCPP_VISIBLE __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000216{
217 typedef _NodePtr __node_pointer;
218
219 __node_pointer __ptr_;
220
Howard Hinnant0af133f2010-09-21 22:55:27 +0000221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000222 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000223
224 template<class, class> friend class forward_list;
225 template<class> friend class __forward_list_const_iterator;
226
227public:
228 typedef forward_iterator_tag iterator_category;
229 typedef typename pointer_traits<__node_pointer>::element_type::value_type
230 value_type;
231 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000232 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000233 difference_type;
234 typedef typename pointer_traits<__node_pointer>::template
235#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
236 rebind<value_type>
237#else
238 rebind<value_type>::other
239#endif
240 pointer;
241
Howard Hinnant0af133f2010-09-21 22:55:27 +0000242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000243 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000244
Howard Hinnant0af133f2010-09-21 22:55:27 +0000245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000246 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000248 pointer operator->() const {return &__ptr_->__value_;}
249
Howard Hinnant0af133f2010-09-21 22:55:27 +0000250 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000251 __forward_list_iterator& operator++()
252 {
253 __ptr_ = __ptr_->__next_;
254 return *this;
255 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000257 __forward_list_iterator operator++(int)
258 {
259 __forward_list_iterator __t(*this);
260 ++(*this);
261 return __t;
262 }
263
Howard Hinnant0af133f2010-09-21 22:55:27 +0000264 friend _LIBCPP_INLINE_VISIBILITY
265 bool operator==(const __forward_list_iterator& __x,
266 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000267 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000268 friend _LIBCPP_INLINE_VISIBILITY
269 bool operator!=(const __forward_list_iterator& __x,
270 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000271 {return !(__x == __y);}
272};
273
274template <class _NodeConstPtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000275class _LIBCPP_VISIBLE __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000276{
277 typedef _NodeConstPtr __node_const_pointer;
278
279 __node_const_pointer __ptr_;
280
Howard Hinnant0af133f2010-09-21 22:55:27 +0000281 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000282 explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000283 : __ptr_(__p) {}
284
285 typedef typename remove_const
286 <
287 typename pointer_traits<__node_const_pointer>::element_type
288 >::type __node;
289 typedef typename pointer_traits<__node_const_pointer>::template
290#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
291 rebind<__node>
292#else
293 rebind<__node>::other
294#endif
295 __node_pointer;
296
297 template<class, class> friend class forward_list;
298
299public:
300 typedef forward_iterator_tag iterator_category;
301 typedef typename __node::value_type value_type;
302 typedef const value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000303 typedef typename pointer_traits<__node_const_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000304 difference_type;
305 typedef typename pointer_traits<__node_const_pointer>::template
306#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
307 rebind<const value_type>
308#else
309 rebind<const value_type>::other
310#endif
311 pointer;
312
Howard Hinnant0af133f2010-09-21 22:55:27 +0000313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000314 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000316 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000317 : __ptr_(__p.__ptr_) {}
318
Howard Hinnant0af133f2010-09-21 22:55:27 +0000319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000320 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000322 pointer operator->() const {return &__ptr_->__value_;}
323
Howard Hinnant0af133f2010-09-21 22:55:27 +0000324 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000325 __forward_list_const_iterator& operator++()
326 {
327 __ptr_ = __ptr_->__next_;
328 return *this;
329 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000331 __forward_list_const_iterator operator++(int)
332 {
333 __forward_list_const_iterator __t(*this);
334 ++(*this);
335 return __t;
336 }
337
Howard Hinnant0af133f2010-09-21 22:55:27 +0000338 friend _LIBCPP_INLINE_VISIBILITY
339 bool operator==(const __forward_list_const_iterator& __x,
340 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000341 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000342 friend _LIBCPP_INLINE_VISIBILITY
343 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000344 const __forward_list_const_iterator& __y)
345 {return !(__x == __y);}
346};
347
348template <class _Tp, class _Alloc>
349class __forward_list_base
350{
351protected:
352 typedef _Tp value_type;
353 typedef _Alloc allocator_type;
354
355 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
356 typedef __forward_list_node<value_type, void_pointer> __node;
357 typedef typename __node::__self __begin_node;
358 typedef typename allocator_traits<allocator_type>::template
359#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
360 rebind_alloc<__node>
361#else
362 rebind_alloc<__node>::other
363#endif
364 __node_allocator;
365 typedef allocator_traits<__node_allocator> __node_traits;
366 typedef typename __node_traits::pointer __node_pointer;
367 typedef typename __node_traits::const_pointer __node_const_pointer;
368
369 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
370
Howard Hinnant0af133f2010-09-21 22:55:27 +0000371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000372 __node_pointer __before_begin() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000373 {return pointer_traits<__node_pointer>::pointer_to(
374 static_cast<__node&>(__before_begin_.first()));}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000376 __node_const_pointer __before_begin() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000377 {return pointer_traits<__node_const_pointer>::pointer_to(
378 static_cast<const __node&>(__before_begin_.first()));}
379
Howard Hinnant0af133f2010-09-21 22:55:27 +0000380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000381 __node_allocator& __alloc() _NOEXCEPT
382 {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000384 const __node_allocator& __alloc() const _NOEXCEPT
385 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000386
387 typedef __forward_list_iterator<__node_pointer> iterator;
388 typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
389
Howard Hinnant0af133f2010-09-21 22:55:27 +0000390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000391 __forward_list_base()
Howard Hinnant91a47502011-06-03 16:20:53 +0000392 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000393 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000395 __forward_list_base(const allocator_type& __a)
396 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
397
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000398#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000399public:
400 __forward_list_base(__forward_list_base&& __x)
401 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000402 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000403#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000404
405private:
406 __forward_list_base(const __forward_list_base&);
407 __forward_list_base& operator=(const __forward_list_base&);
Howard Hinnant3e519522010-05-11 19:42:16 +0000408
Howard Hinnant91a47502011-06-03 16:20:53 +0000409public:
Howard Hinnant3e519522010-05-11 19:42:16 +0000410 ~__forward_list_base();
411
Howard Hinnant91a47502011-06-03 16:20:53 +0000412protected:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000414 void __copy_assign_alloc(const __forward_list_base& __x)
415 {__copy_assign_alloc(__x, integral_constant<bool,
416 __node_traits::propagate_on_container_copy_assignment::value>());}
417
Howard Hinnant0af133f2010-09-21 22:55:27 +0000418 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000419 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000420 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
421 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000422 {__move_assign_alloc(__x, integral_constant<bool,
423 __node_traits::propagate_on_container_move_assignment::value>());}
424
Howard Hinnant91a47502011-06-03 16:20:53 +0000425public:
426 void swap(__forward_list_base& __x)
427 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
428 __is_nothrow_swappable<__node_allocator>::value);
429protected:
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000430 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000431
432private:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000434 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
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& __x, true_type)
437 {
438 if (__alloc() != __x.__alloc())
439 clear();
440 __alloc() = __x.__alloc();
441 }
442
Howard Hinnant0af133f2010-09-21 22:55:27 +0000443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000444 void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
445 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000447 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000448 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000449 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000450
Howard Hinnant0af133f2010-09-21 22:55:27 +0000451 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000452 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +0000453 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
454 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000455 {__swap_alloc(__x, __y, integral_constant<bool,
456 __node_traits::propagate_on_container_swap::value>());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000458 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
459 false_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000460 _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000461 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000462 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000463 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
464 true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000465 _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000466 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000467 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000468 swap(__x, __y);
469 }
470};
471
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000472#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000473
474template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000475inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000476__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000477 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000478 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnant3e519522010-05-11 19:42:16 +0000479{
480 __x.__before_begin()->__next_ = nullptr;
481}
482
483template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000484inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000485__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
486 const allocator_type& __a)
487 : __before_begin_(__begin_node(), __node_allocator(__a))
488{
489 if (__alloc() == __x.__alloc())
490 {
491 __before_begin()->__next_ = __x.__before_begin()->__next_;
492 __x.__before_begin()->__next_ = nullptr;
493 }
494}
495
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000496#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000497
498template <class _Tp, class _Alloc>
499__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
500{
501 clear();
502}
503
504template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000505inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000506void
507__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000508 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
509 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000510{
511 __swap_alloc(__alloc(), __x.__alloc());
Howard Hinnantce48a112011-06-30 21:18:19 +0000512 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000513 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
514}
515
516template <class _Tp, class _Alloc>
517void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000518__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000519{
520 __node_allocator& __a = __alloc();
521 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
522 {
523 __node_pointer __next = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000524 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000525 __node_traits::deallocate(__a, __p, 1);
526 __p = __next;
527 }
528 __before_begin()->__next_ = nullptr;
529}
530
531template <class _Tp, class _Alloc = allocator<_Tp> >
Howard Hinnant0af133f2010-09-21 22:55:27 +0000532class _LIBCPP_VISIBLE forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000533 : private __forward_list_base<_Tp, _Alloc>
534{
535 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnant91a47502011-06-03 16:20:53 +0000536 typedef typename base::__node_allocator __node_allocator;
537 typedef typename base::__node __node;
538 typedef typename base::__node_traits __node_traits;
539 typedef typename base::__node_pointer __node_pointer;
540
Howard Hinnant3e519522010-05-11 19:42:16 +0000541public:
542 typedef _Tp value_type;
543 typedef _Alloc allocator_type;
544
545 typedef value_type& reference;
546 typedef const value_type& const_reference;
547 typedef typename allocator_traits<allocator_type>::pointer pointer;
548 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
549 typedef typename allocator_traits<allocator_type>::size_type size_type;
550 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
551
552 typedef typename base::iterator iterator;
553 typedef typename base::const_iterator const_iterator;
554
Howard Hinnant91a47502011-06-03 16:20:53 +0000555 _LIBCPP_INLINE_VISIBILITY
556 forward_list()
557 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
558 {} // = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000559 explicit forward_list(const allocator_type& __a);
560 explicit forward_list(size_type __n);
561 forward_list(size_type __n, const value_type& __v);
562 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
563 template <class _InputIterator>
564 forward_list(_InputIterator __f, _InputIterator __l,
565 typename enable_if<
566 __is_input_iterator<_InputIterator>::value
567 >::type* = nullptr);
568 template <class _InputIterator>
569 forward_list(_InputIterator __f, _InputIterator __l,
570 const allocator_type& __a,
571 typename enable_if<
572 __is_input_iterator<_InputIterator>::value
573 >::type* = nullptr);
574 forward_list(const forward_list& __x);
575 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000576#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000577 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000578 forward_list(forward_list&& __x)
579 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000580 : base(_VSTD::move(__x)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000581 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000582#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54976f22011-08-12 21:56:02 +0000583#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000584 forward_list(initializer_list<value_type> __il);
585 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
Howard Hinnant54976f22011-08-12 21:56:02 +0000586#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000587
588 // ~forward_list() = default;
589
590 forward_list& operator=(const forward_list& __x);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000591#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000592 forward_list& operator=(forward_list&& __x)
593 _NOEXCEPT_(
594 __node_traits::propagate_on_container_move_assignment::value &&
595 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000596#endif
Howard Hinnant54976f22011-08-12 21:56:02 +0000597#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000598 forward_list& operator=(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000599#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000600
601 template <class _InputIterator>
602 typename enable_if
603 <
604 __is_input_iterator<_InputIterator>::value,
605 void
606 >::type
607 assign(_InputIterator __f, _InputIterator __l);
608 void assign(size_type __n, const value_type& __v);
Howard Hinnant54976f22011-08-12 21:56:02 +0000609#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000610 void assign(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000611#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000612
Howard Hinnant0af133f2010-09-21 22:55:27 +0000613 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000614 allocator_type get_allocator() const _NOEXCEPT
615 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000616
Howard Hinnant0af133f2010-09-21 22:55:27 +0000617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000618 iterator begin() _NOEXCEPT
619 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000621 const_iterator begin() const _NOEXCEPT
622 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000623 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000624 iterator end() _NOEXCEPT
625 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000627 const_iterator end() const _NOEXCEPT
628 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000629
Howard Hinnant0af133f2010-09-21 22:55:27 +0000630 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000631 const_iterator cbegin() const _NOEXCEPT
632 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000633 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000634 const_iterator cend() const _NOEXCEPT
635 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000636
Howard Hinnant0af133f2010-09-21 22:55:27 +0000637 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000638 iterator before_begin() _NOEXCEPT
639 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000640 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000641 const_iterator before_begin() const _NOEXCEPT
642 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000643 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000644 const_iterator cbefore_begin() const _NOEXCEPT
645 {return const_iterator(base::__before_begin());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000646
Howard Hinnant0af133f2010-09-21 22:55:27 +0000647 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000648 bool empty() const _NOEXCEPT
649 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000650 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000651 size_type max_size() const _NOEXCEPT
652 {return numeric_limits<size_type>::max();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000653
Howard Hinnant0af133f2010-09-21 22:55:27 +0000654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000655 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000656 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000657 const_reference front() const {return base::__before_begin()->__next_->__value_;}
658
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000659#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
660#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000661 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000662#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000663 void push_front(value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000664#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000665 void push_front(const value_type& __v);
666
667 void pop_front();
668
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000669#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
670#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000671 template <class... _Args>
672 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000673#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000674 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000675#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000676 iterator insert_after(const_iterator __p, const value_type& __v);
677 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
678 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000680 typename enable_if
681 <
682 __is_input_iterator<_InputIterator>::value,
683 iterator
684 >::type
685 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnant54976f22011-08-12 21:56:02 +0000686#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000687 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
688 {return insert_after(__p, __il.begin(), __il.end());}
Howard Hinnant54976f22011-08-12 21:56:02 +0000689#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000690
Howard Hinnant3db88032010-08-21 20:58:44 +0000691 iterator erase_after(const_iterator __p);
692 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000693
Howard Hinnant0af133f2010-09-21 22:55:27 +0000694 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000695 void swap(forward_list& __x)
696 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
697 __is_nothrow_swappable<__node_allocator>::value)
698 {base::swap(__x);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000699
700 void resize(size_type __n);
701 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000702 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000703 void clear() _NOEXCEPT {base::clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000704
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000705#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanteb92df72011-01-27 21:00:35 +0000706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000707 void splice_after(const_iterator __p, forward_list&& __x);
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, const_iterator __i);
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,
712 const_iterator __f, const_iterator __l);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000713#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000714 void splice_after(const_iterator __p, forward_list& __x);
715 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
716 void splice_after(const_iterator __p, forward_list& __x,
717 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000718 void remove(const value_type& __v);
719 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000720 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000721 void unique() {unique(__equal_to<value_type>());}
722 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000723#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000725 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
726 template <class _Compare>
727 _LIBCPP_INLINE_VISIBILITY
728 void merge(forward_list&& __x, _Compare __comp)
Howard Hinnantce48a112011-06-30 21:18:19 +0000729 {merge(__x, _VSTD::move(__comp));}
Howard Hinnanteb92df72011-01-27 21:00:35 +0000730#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000731 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000732 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
733 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000734 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000735 void sort() {sort(__less<value_type>());}
736 template <class _Compare> void sort(_Compare __comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000737 void reverse() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000738
739private:
Howard Hinnant3e519522010-05-11 19:42:16 +0000740
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000741#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000742 void __move_assign(forward_list& __x, true_type)
743 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000744 void __move_assign(forward_list& __x, false_type);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000745#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000746
747 template <class _Compare>
748 static
749 __node_pointer
750 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
751
752 template <class _Compare>
753 static
754 __node_pointer
755 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
756};
757
758template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000759inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000760forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
761 : base(__a)
762{
763}
764
765template <class _Tp, class _Alloc>
766forward_list<_Tp, _Alloc>::forward_list(size_type __n)
767{
768 if (__n > 0)
769 {
770 __node_allocator& __a = base::__alloc();
771 typedef __allocator_destructor<__node_allocator> _D;
772 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
773 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
774 __p = __p->__next_)
775 {
776 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000777 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000778 __h->__next_ = nullptr;
779 __p->__next_ = __h.release();
780 }
781 }
782}
783
784template <class _Tp, class _Alloc>
785forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
786{
787 insert_after(cbefore_begin(), __n, __v);
788}
789
790template <class _Tp, class _Alloc>
791forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
792 const allocator_type& __a)
793 : base(__a)
794{
795 insert_after(cbefore_begin(), __n, __v);
796}
797
798template <class _Tp, class _Alloc>
799template <class _InputIterator>
800forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
801 typename enable_if<
802 __is_input_iterator<_InputIterator>::value
803 >::type*)
804{
805 insert_after(cbefore_begin(), __f, __l);
806}
807
808template <class _Tp, class _Alloc>
809template <class _InputIterator>
810forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
811 const allocator_type& __a,
812 typename enable_if<
813 __is_input_iterator<_InputIterator>::value
814 >::type*)
815 : base(__a)
816{
817 insert_after(cbefore_begin(), __f, __l);
818}
819
820template <class _Tp, class _Alloc>
821forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
822 : base(allocator_type(
823 __node_traits::select_on_container_copy_construction(__x.__alloc())
824 )
825 )
826{
827 insert_after(cbefore_begin(), __x.begin(), __x.end());
828}
829
830template <class _Tp, class _Alloc>
831forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
832 const allocator_type& __a)
833 : base(__a)
834{
835 insert_after(cbefore_begin(), __x.begin(), __x.end());
836}
837
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000838#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000839
840template <class _Tp, class _Alloc>
841forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
842 const allocator_type& __a)
Howard Hinnantce48a112011-06-30 21:18:19 +0000843 : base(_VSTD::move(__x), __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000844{
845 if (base::__alloc() != __x.__alloc())
846 {
847 typedef move_iterator<iterator> _I;
848 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
849 }
850}
851
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000852#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000853
Howard Hinnant54976f22011-08-12 21:56:02 +0000854#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
855
Howard Hinnant3e519522010-05-11 19:42:16 +0000856template <class _Tp, class _Alloc>
857forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
858{
859 insert_after(cbefore_begin(), __il.begin(), __il.end());
860}
861
862template <class _Tp, class _Alloc>
863forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
864 const allocator_type& __a)
865 : base(__a)
866{
867 insert_after(cbefore_begin(), __il.begin(), __il.end());
868}
869
Howard Hinnant54976f22011-08-12 21:56:02 +0000870#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
871
Howard Hinnant3e519522010-05-11 19:42:16 +0000872template <class _Tp, class _Alloc>
873forward_list<_Tp, _Alloc>&
874forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
875{
876 if (this != &__x)
877 {
878 base::__copy_assign_alloc(__x);
879 assign(__x.begin(), __x.end());
880 }
881 return *this;
882}
883
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000884#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000885
886template <class _Tp, class _Alloc>
887void
888forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000889 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000890{
891 clear();
892 base::__move_assign_alloc(__x);
893 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
894 __x.__before_begin()->__next_ = nullptr;
895}
896
897template <class _Tp, class _Alloc>
898void
899forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
900{
901 if (base::__alloc() == __x.__alloc())
902 __move_assign(__x, true_type());
903 else
904 {
905 typedef move_iterator<iterator> _I;
906 assign(_I(__x.begin()), _I(__x.end()));
907 }
908}
909
910template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000911inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000912forward_list<_Tp, _Alloc>&
913forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000914 _NOEXCEPT_(
915 __node_traits::propagate_on_container_move_assignment::value &&
916 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000917{
918 __move_assign(__x, integral_constant<bool,
919 __node_traits::propagate_on_container_move_assignment::value>());
920 return *this;
921}
922
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000923#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000924
Howard Hinnant54976f22011-08-12 21:56:02 +0000925#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
926
Howard Hinnant3e519522010-05-11 19:42:16 +0000927template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000928inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000929forward_list<_Tp, _Alloc>&
930forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
931{
932 assign(__il.begin(), __il.end());
933 return *this;
934}
935
Howard Hinnant54976f22011-08-12 21:56:02 +0000936#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
937
Howard Hinnant3e519522010-05-11 19:42:16 +0000938template <class _Tp, class _Alloc>
939template <class _InputIterator>
940typename enable_if
941<
942 __is_input_iterator<_InputIterator>::value,
943 void
944>::type
945forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
946{
947 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +0000948 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000949 iterator __e = end();
950 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
951 *__j = *__f;
952 if (__j == __e)
953 insert_after(__i, __f, __l);
954 else
955 erase_after(__i, __e);
956}
957
958template <class _Tp, class _Alloc>
959void
960forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
961{
962 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +0000963 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000964 iterator __e = end();
965 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
966 *__j = __v;
967 if (__j == __e)
968 insert_after(__i, __n, __v);
969 else
970 erase_after(__i, __e);
971}
972
Howard Hinnant54976f22011-08-12 21:56:02 +0000973#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
974
Howard Hinnant3e519522010-05-11 19:42:16 +0000975template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000976inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000977void
978forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
979{
980 assign(__il.begin(), __il.end());
981}
982
Howard Hinnant54976f22011-08-12 21:56:02 +0000983#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
984
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000985#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
986#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000987
988template <class _Tp, class _Alloc>
989template <class... _Args>
990void
991forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
992{
993 __node_allocator& __a = base::__alloc();
994 typedef __allocator_destructor<__node_allocator> _D;
995 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000996 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
997 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +0000998 __h->__next_ = base::__before_begin()->__next_;
999 base::__before_begin()->__next_ = __h.release();
1000}
1001
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001002#endif // _LIBCPP_HAS_NO_VARIADICS
1003
Howard Hinnant3e519522010-05-11 19:42:16 +00001004template <class _Tp, class _Alloc>
1005void
1006forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1007{
1008 __node_allocator& __a = base::__alloc();
1009 typedef __allocator_destructor<__node_allocator> _D;
1010 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001011 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001012 __h->__next_ = base::__before_begin()->__next_;
1013 base::__before_begin()->__next_ = __h.release();
1014}
1015
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001016#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001017
1018template <class _Tp, class _Alloc>
1019void
1020forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1021{
1022 __node_allocator& __a = base::__alloc();
1023 typedef __allocator_destructor<__node_allocator> _D;
1024 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001025 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001026 __h->__next_ = base::__before_begin()->__next_;
1027 base::__before_begin()->__next_ = __h.release();
1028}
1029
1030template <class _Tp, class _Alloc>
1031void
1032forward_list<_Tp, _Alloc>::pop_front()
1033{
1034 __node_allocator& __a = base::__alloc();
1035 __node_pointer __p = base::__before_begin()->__next_;
1036 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001037 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001038 __node_traits::deallocate(__a, __p, 1);
1039}
1040
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001041#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1042#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +00001043
1044template <class _Tp, class _Alloc>
1045template <class... _Args>
1046typename forward_list<_Tp, _Alloc>::iterator
1047forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1048{
1049 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1050 __node_allocator& __a = base::__alloc();
1051 typedef __allocator_destructor<__node_allocator> _D;
1052 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001053 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1054 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001055 __h->__next_ = __r->__next_;
1056 __r->__next_ = __h.release();
1057 return iterator(__r->__next_);
1058}
1059
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001060#endif // _LIBCPP_HAS_NO_VARIADICS
1061
Howard Hinnant3e519522010-05-11 19:42:16 +00001062template <class _Tp, class _Alloc>
1063typename forward_list<_Tp, _Alloc>::iterator
1064forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1065{
1066 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1067 __node_allocator& __a = base::__alloc();
1068 typedef __allocator_destructor<__node_allocator> _D;
1069 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001070 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001071 __h->__next_ = __r->__next_;
1072 __r->__next_ = __h.release();
1073 return iterator(__r->__next_);
1074}
1075
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001076#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001077
1078template <class _Tp, class _Alloc>
1079typename forward_list<_Tp, _Alloc>::iterator
1080forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1081{
1082 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1083 __node_allocator& __a = base::__alloc();
1084 typedef __allocator_destructor<__node_allocator> _D;
1085 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001086 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001087 __h->__next_ = __r->__next_;
1088 __r->__next_ = __h.release();
1089 return iterator(__r->__next_);
1090}
1091
1092template <class _Tp, class _Alloc>
1093typename forward_list<_Tp, _Alloc>::iterator
1094forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1095 const value_type& __v)
1096{
Howard Hinnante57dc142010-08-19 17:40:04 +00001097 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001098 if (__n > 0)
1099 {
1100 __node_allocator& __a = base::__alloc();
1101 typedef __allocator_destructor<__node_allocator> _D;
1102 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001103 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001104 __node_pointer __first = __h.release();
1105 __node_pointer __last = __first;
1106#ifndef _LIBCPP_NO_EXCEPTIONS
1107 try
1108 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001109#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001110 for (--__n; __n != 0; --__n, __last = __last->__next_)
1111 {
1112 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001113 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001114 __last->__next_ = __h.release();
1115 }
1116#ifndef _LIBCPP_NO_EXCEPTIONS
1117 }
1118 catch (...)
1119 {
1120 while (__first != nullptr)
1121 {
1122 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001123 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001124 __node_traits::deallocate(__a, __first, 1);
1125 __first = __next;
1126 }
1127 throw;
1128 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001129#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001130 __last->__next_ = __r->__next_;
1131 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001132 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001133 }
1134 return iterator(__r);
1135}
1136
1137template <class _Tp, class _Alloc>
1138template <class _InputIterator>
1139typename enable_if
1140<
1141 __is_input_iterator<_InputIterator>::value,
1142 typename forward_list<_Tp, _Alloc>::iterator
1143>::type
1144forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1145 _InputIterator __f, _InputIterator __l)
1146{
Howard Hinnante57dc142010-08-19 17:40:04 +00001147 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001148 if (__f != __l)
1149 {
1150 __node_allocator& __a = base::__alloc();
1151 typedef __allocator_destructor<__node_allocator> _D;
1152 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001153 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001154 __node_pointer __first = __h.release();
1155 __node_pointer __last = __first;
1156#ifndef _LIBCPP_NO_EXCEPTIONS
1157 try
1158 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001159#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001160 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1161 {
1162 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001163 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001164 __last->__next_ = __h.release();
1165 }
1166#ifndef _LIBCPP_NO_EXCEPTIONS
1167 }
1168 catch (...)
1169 {
1170 while (__first != nullptr)
1171 {
1172 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001173 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001174 __node_traits::deallocate(__a, __first, 1);
1175 __first = __next;
1176 }
1177 throw;
1178 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001179#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001180 __last->__next_ = __r->__next_;
1181 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001182 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001183 }
1184 return iterator(__r);
1185}
1186
1187template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001188typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001189forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1190{
1191 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1192 __node_pointer __n = __p->__next_;
1193 __p->__next_ = __n->__next_;
1194 __node_allocator& __a = base::__alloc();
Howard Hinnantce48a112011-06-30 21:18:19 +00001195 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001196 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001197 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001198}
1199
1200template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001201typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001202forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1203{
Howard Hinnant3db88032010-08-21 20:58:44 +00001204 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001205 if (__f != __l)
1206 {
1207 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1208 __node_pointer __n = __p->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001209 if (__n != __e)
1210 {
1211 __p->__next_ = __e;
1212 __node_allocator& __a = base::__alloc();
1213 do
1214 {
1215 __p = __n->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001216 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001217 __node_traits::deallocate(__a, __n, 1);
1218 __n = __p;
1219 } while (__n != __e);
1220 }
1221 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001222 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001223}
1224
1225template <class _Tp, class _Alloc>
1226void
1227forward_list<_Tp, _Alloc>::resize(size_type __n)
1228{
1229 size_type __sz = 0;
1230 iterator __p = before_begin();
1231 iterator __i = begin();
1232 iterator __e = end();
1233 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1234 ;
1235 if (__i != __e)
1236 erase_after(__p, __e);
1237 else
1238 {
1239 __n -= __sz;
1240 if (__n > 0)
1241 {
1242 __node_allocator& __a = base::__alloc();
1243 typedef __allocator_destructor<__node_allocator> _D;
1244 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1245 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1246 __ptr = __ptr->__next_)
1247 {
1248 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001249 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001250 __h->__next_ = nullptr;
1251 __ptr->__next_ = __h.release();
1252 }
1253 }
1254 }
1255}
1256
1257template <class _Tp, class _Alloc>
1258void
1259forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1260{
1261 size_type __sz = 0;
1262 iterator __p = before_begin();
1263 iterator __i = begin();
1264 iterator __e = end();
1265 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1266 ;
1267 if (__i != __e)
1268 erase_after(__p, __e);
1269 else
1270 {
1271 __n -= __sz;
1272 if (__n > 0)
1273 {
1274 __node_allocator& __a = base::__alloc();
1275 typedef __allocator_destructor<__node_allocator> _D;
1276 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1277 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1278 __ptr = __ptr->__next_)
1279 {
1280 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001281 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001282 __h->__next_ = nullptr;
1283 __ptr->__next_ = __h.release();
1284 }
1285 }
1286 }
1287}
1288
1289template <class _Tp, class _Alloc>
1290void
1291forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001292 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001293{
1294 if (!__x.empty())
1295 {
1296 if (__p.__ptr_->__next_ != nullptr)
1297 {
1298 const_iterator __lm1 = __x.before_begin();
1299 while (__lm1.__ptr_->__next_ != nullptr)
1300 ++__lm1;
1301 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1302 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1303 }
1304 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1305 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1306 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1307 }
1308}
1309
1310template <class _Tp, class _Alloc>
1311void
1312forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001313 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001314 const_iterator __i)
1315{
Howard Hinnantce48a112011-06-30 21:18:19 +00001316 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001317 if (__p != __i && __p != __lm1)
1318 {
1319 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1320 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1321 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1322 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1323 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1324 const_cast<__node_pointer>(__lm1.__ptr_);
1325 }
1326}
1327
1328template <class _Tp, class _Alloc>
1329void
1330forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001331 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001332 const_iterator __f, const_iterator __l)
1333{
1334 if (__f != __l && __p != __f)
1335 {
1336 const_iterator __lm1 = __f;
1337 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1338 ++__lm1;
1339 if (__f != __lm1)
1340 {
1341 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1342 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1343 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1344 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1345 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1346 const_cast<__node_pointer>(__l.__ptr_);
1347 }
1348 }
1349}
1350
Howard Hinnanteb92df72011-01-27 21:00:35 +00001351#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1352
1353template <class _Tp, class _Alloc>
1354inline _LIBCPP_INLINE_VISIBILITY
1355void
1356forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1357 forward_list&& __x)
1358{
1359 splice_after(__p, __x);
1360}
1361
1362template <class _Tp, class _Alloc>
1363inline _LIBCPP_INLINE_VISIBILITY
1364void
1365forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1366 forward_list&& __x,
1367 const_iterator __i)
1368{
1369 splice_after(__p, __x, __i);
1370}
1371
1372template <class _Tp, class _Alloc>
1373inline _LIBCPP_INLINE_VISIBILITY
1374void
1375forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1376 forward_list&& __x,
1377 const_iterator __f, const_iterator __l)
1378{
1379 splice_after(__p, __x, __f, __l);
1380}
1381
1382#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1383
Howard Hinnant3e519522010-05-11 19:42:16 +00001384template <class _Tp, class _Alloc>
1385void
1386forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1387{
1388 iterator __e = end();
1389 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1390 {
1391 if (__i.__ptr_->__next_->__value_ == __v)
1392 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001393 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001394 for (; __j != __e && *__j == __v; ++__j)
1395 ;
1396 erase_after(__i, __j);
1397 if (__j == __e)
1398 break;
1399 __i = __j;
1400 }
1401 else
1402 ++__i;
1403 }
1404}
1405
1406template <class _Tp, class _Alloc>
1407template <class _Predicate>
1408void
1409forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1410{
1411 iterator __e = end();
1412 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1413 {
1414 if (__pred(__i.__ptr_->__next_->__value_))
1415 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001416 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001417 for (; __j != __e && __pred(*__j); ++__j)
1418 ;
1419 erase_after(__i, __j);
1420 if (__j == __e)
1421 break;
1422 __i = __j;
1423 }
1424 else
1425 ++__i;
1426 }
1427}
1428
1429template <class _Tp, class _Alloc>
1430template <class _BinaryPredicate>
1431void
1432forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1433{
1434 for (iterator __i = begin(), __e = end(); __i != __e;)
1435 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001436 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001437 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1438 ;
1439 if (__i.__ptr_->__next_ != __j.__ptr_)
1440 erase_after(__i, __j);
1441 __i = __j;
1442 }
1443}
1444
1445template <class _Tp, class _Alloc>
1446template <class _Compare>
1447void
Howard Hinnant3e519522010-05-11 19:42:16 +00001448forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001449{
1450 if (this != &__x)
1451 {
1452 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1453 __x.__before_begin()->__next_,
1454 __comp);
1455 __x.__before_begin()->__next_ = nullptr;
1456 }
1457}
1458
1459template <class _Tp, class _Alloc>
1460template <class _Compare>
1461typename forward_list<_Tp, _Alloc>::__node_pointer
1462forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1463 _Compare& __comp)
1464{
1465 if (__f1 == nullptr)
1466 return __f2;
1467 if (__f2 == nullptr)
1468 return __f1;
1469 __node_pointer __r;
1470 if (__comp(__f2->__value_, __f1->__value_))
1471 {
1472 __node_pointer __t = __f2;
1473 while (__t->__next_ != nullptr &&
1474 __comp(__t->__next_->__value_, __f1->__value_))
1475 __t = __t->__next_;
1476 __r = __f2;
1477 __f2 = __t->__next_;
1478 __t->__next_ = __f1;
1479 }
1480 else
1481 __r = __f1;
1482 __node_pointer __p = __f1;
1483 __f1 = __f1->__next_;
1484 while (__f1 != nullptr && __f2 != nullptr)
1485 {
1486 if (__comp(__f2->__value_, __f1->__value_))
1487 {
1488 __node_pointer __t = __f2;
1489 while (__t->__next_ != nullptr &&
1490 __comp(__t->__next_->__value_, __f1->__value_))
1491 __t = __t->__next_;
1492 __p->__next_ = __f2;
1493 __f2 = __t->__next_;
1494 __t->__next_ = __f1;
1495 }
1496 __p = __f1;
1497 __f1 = __f1->__next_;
1498 }
1499 if (__f2 != nullptr)
1500 __p->__next_ = __f2;
1501 return __r;
1502}
1503
1504template <class _Tp, class _Alloc>
1505template <class _Compare>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001506inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001507void
1508forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1509{
1510 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnantce48a112011-06-30 21:18:19 +00001511 _VSTD::distance(begin(), end()), __comp);
Howard Hinnant3e519522010-05-11 19:42:16 +00001512}
1513
1514template <class _Tp, class _Alloc>
1515template <class _Compare>
1516typename forward_list<_Tp, _Alloc>::__node_pointer
1517forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1518 _Compare& __comp)
1519{
1520 switch (__sz)
1521 {
1522 case 0:
1523 case 1:
1524 return __f1;
1525 case 2:
1526 if (__comp(__f1->__next_->__value_, __f1->__value_))
1527 {
1528 __node_pointer __t = __f1->__next_;
1529 __t->__next_ = __f1;
1530 __f1->__next_ = nullptr;
1531 __f1 = __t;
1532 }
1533 return __f1;
1534 }
1535 difference_type __sz1 = __sz / 2;
1536 difference_type __sz2 = __sz - __sz1;
Howard Hinnantce48a112011-06-30 21:18:19 +00001537 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001538 __node_pointer __f2 = __t->__next_;
1539 __t->__next_ = nullptr;
1540 return __merge(__sort(__f1, __sz1, __comp),
1541 __sort(__f2, __sz2, __comp), __comp);
1542}
1543
1544template <class _Tp, class _Alloc>
1545void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001546forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001547{
1548 __node_pointer __p = base::__before_begin()->__next_;
1549 if (__p != nullptr)
1550 {
1551 __node_pointer __f = __p->__next_;
1552 __p->__next_ = nullptr;
1553 while (__f != nullptr)
1554 {
1555 __node_pointer __t = __f->__next_;
1556 __f->__next_ = __p;
1557 __p = __f;
1558 __f = __t;
1559 }
1560 base::__before_begin()->__next_ = __p;
1561 }
1562}
1563
1564template <class _Tp, class _Alloc>
1565bool operator==(const forward_list<_Tp, _Alloc>& __x,
1566 const forward_list<_Tp, _Alloc>& __y)
1567{
1568 typedef forward_list<_Tp, _Alloc> _C;
1569 typedef typename _C::const_iterator _I;
1570 _I __ix = __x.begin();
1571 _I __ex = __x.end();
1572 _I __iy = __y.begin();
1573 _I __ey = __y.end();
1574 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1575 if (!(*__ix == *__iy))
1576 return false;
1577 return (__ix == __ex) == (__iy == __ey);
1578}
1579
1580template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001581inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001582bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1583 const forward_list<_Tp, _Alloc>& __y)
1584{
1585 return !(__x == __y);
1586}
1587
1588template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001589inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001590bool operator< (const forward_list<_Tp, _Alloc>& __x,
1591 const forward_list<_Tp, _Alloc>& __y)
1592{
Howard Hinnantce48a112011-06-30 21:18:19 +00001593 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnant3e519522010-05-11 19:42:16 +00001594 __y.begin(), __y.end());
1595}
1596
1597template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001598inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001599bool operator> (const forward_list<_Tp, _Alloc>& __x,
1600 const forward_list<_Tp, _Alloc>& __y)
1601{
1602 return __y < __x;
1603}
1604
1605template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001606inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001607bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1608 const forward_list<_Tp, _Alloc>& __y)
1609{
1610 return !(__x < __y);
1611}
1612
1613template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001614inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001615bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1616 const forward_list<_Tp, _Alloc>& __y)
1617{
1618 return !(__y < __x);
1619}
1620
1621template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001622inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001623void
1624swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +00001625 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001626{
1627 __x.swap(__y);
1628}
1629
1630_LIBCPP_END_NAMESPACE_STD
1631
1632#endif // _LIBCPP_FORWARD_LIST