blob: 19f748478f5d86286e4304e40d8aebda87a001f5 [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 Hinnantab4f4382011-11-29 16:45:27 +0000177#include <__undef_min_max>
178
Howard Hinnant073458b2011-10-17 20:05:10 +0000179#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +0000180#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000181#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000182
183_LIBCPP_BEGIN_NAMESPACE_STD
184
Howard Hinnantce534202011-06-14 19:58:17 +0000185template <class _Tp, class _VoidPtr> struct __forward_list_node;
Howard Hinnant3e519522010-05-11 19:42:16 +0000186
187template <class _NodePtr>
188struct __forward_begin_node
189{
190 typedef __forward_begin_node __self;
191 typedef _NodePtr pointer;
192
193 pointer __next_;
194
Howard Hinnant0af133f2010-09-21 22:55:27 +0000195 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000196};
197
198template <class _Tp, class _VoidPtr>
199struct __forward_list_node
200 : public __forward_begin_node
201 <
202 typename pointer_traits<_VoidPtr>::template
203#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
204 rebind<__forward_list_node<_Tp, _VoidPtr> >
205#else
206 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
207#endif
208 >
209{
210 typedef _Tp value_type;
211
212 value_type __value_;
213};
214
Howard Hinnantce534202011-06-14 19:58:17 +0000215template<class _Tp, class _Alloc> class forward_list;
216template<class _NodeConstPtr> class __forward_list_const_iterator;
Howard Hinnant3e519522010-05-11 19:42:16 +0000217
218template <class _NodePtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000219class _LIBCPP_VISIBLE __forward_list_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000220{
221 typedef _NodePtr __node_pointer;
222
223 __node_pointer __ptr_;
224
Howard Hinnant0af133f2010-09-21 22:55:27 +0000225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000226 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000227
228 template<class, class> friend class forward_list;
229 template<class> friend class __forward_list_const_iterator;
230
231public:
232 typedef forward_iterator_tag iterator_category;
233 typedef typename pointer_traits<__node_pointer>::element_type::value_type
234 value_type;
235 typedef value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000236 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000237 difference_type;
238 typedef typename pointer_traits<__node_pointer>::template
239#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
240 rebind<value_type>
241#else
242 rebind<value_type>::other
243#endif
244 pointer;
245
Howard Hinnant0af133f2010-09-21 22:55:27 +0000246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000247 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000248
Howard Hinnant0af133f2010-09-21 22:55:27 +0000249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000250 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000252 pointer operator->() const {return &__ptr_->__value_;}
253
Howard Hinnant0af133f2010-09-21 22:55:27 +0000254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000255 __forward_list_iterator& operator++()
256 {
257 __ptr_ = __ptr_->__next_;
258 return *this;
259 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000260 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000261 __forward_list_iterator operator++(int)
262 {
263 __forward_list_iterator __t(*this);
264 ++(*this);
265 return __t;
266 }
267
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.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000272 friend _LIBCPP_INLINE_VISIBILITY
273 bool operator!=(const __forward_list_iterator& __x,
274 const __forward_list_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000275 {return !(__x == __y);}
276};
277
278template <class _NodeConstPtr>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000279class _LIBCPP_VISIBLE __forward_list_const_iterator
Howard Hinnant3e519522010-05-11 19:42:16 +0000280{
281 typedef _NodeConstPtr __node_const_pointer;
282
283 __node_const_pointer __ptr_;
284
Howard Hinnant0af133f2010-09-21 22:55:27 +0000285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000286 explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000287 : __ptr_(__p) {}
288
289 typedef typename remove_const
290 <
291 typename pointer_traits<__node_const_pointer>::element_type
292 >::type __node;
293 typedef typename pointer_traits<__node_const_pointer>::template
294#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
295 rebind<__node>
296#else
297 rebind<__node>::other
298#endif
299 __node_pointer;
300
301 template<class, class> friend class forward_list;
302
303public:
304 typedef forward_iterator_tag iterator_category;
305 typedef typename __node::value_type value_type;
306 typedef const value_type& reference;
Howard Hinnantb3371f62010-08-22 00:02:43 +0000307 typedef typename pointer_traits<__node_const_pointer>::difference_type
Howard Hinnant3e519522010-05-11 19:42:16 +0000308 difference_type;
309 typedef typename pointer_traits<__node_const_pointer>::template
310#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
311 rebind<const value_type>
312#else
313 rebind<const value_type>::other
314#endif
315 pointer;
316
Howard Hinnant0af133f2010-09-21 22:55:27 +0000317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000318 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000320 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000321 : __ptr_(__p.__ptr_) {}
322
Howard Hinnant0af133f2010-09-21 22:55:27 +0000323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000324 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000326 pointer operator->() const {return &__ptr_->__value_;}
327
Howard Hinnant0af133f2010-09-21 22:55:27 +0000328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000329 __forward_list_const_iterator& operator++()
330 {
331 __ptr_ = __ptr_->__next_;
332 return *this;
333 }
Howard Hinnant0af133f2010-09-21 22:55:27 +0000334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000335 __forward_list_const_iterator operator++(int)
336 {
337 __forward_list_const_iterator __t(*this);
338 ++(*this);
339 return __t;
340 }
341
Howard Hinnant0af133f2010-09-21 22:55:27 +0000342 friend _LIBCPP_INLINE_VISIBILITY
343 bool operator==(const __forward_list_const_iterator& __x,
344 const __forward_list_const_iterator& __y)
Howard Hinnant3e519522010-05-11 19:42:16 +0000345 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000346 friend _LIBCPP_INLINE_VISIBILITY
347 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +0000348 const __forward_list_const_iterator& __y)
349 {return !(__x == __y);}
350};
351
352template <class _Tp, class _Alloc>
353class __forward_list_base
354{
355protected:
356 typedef _Tp value_type;
357 typedef _Alloc allocator_type;
358
359 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
360 typedef __forward_list_node<value_type, void_pointer> __node;
361 typedef typename __node::__self __begin_node;
362 typedef typename allocator_traits<allocator_type>::template
363#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
364 rebind_alloc<__node>
365#else
366 rebind_alloc<__node>::other
367#endif
368 __node_allocator;
369 typedef allocator_traits<__node_allocator> __node_traits;
370 typedef typename __node_traits::pointer __node_pointer;
371 typedef typename __node_traits::const_pointer __node_const_pointer;
372
373 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
374
Howard Hinnant0af133f2010-09-21 22:55:27 +0000375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000376 __node_pointer __before_begin() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000377 {return pointer_traits<__node_pointer>::pointer_to(
378 static_cast<__node&>(__before_begin_.first()));}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000379 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000380 __node_const_pointer __before_begin() const _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000381 {return pointer_traits<__node_const_pointer>::pointer_to(
382 static_cast<const __node&>(__before_begin_.first()));}
383
Howard Hinnant0af133f2010-09-21 22:55:27 +0000384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000385 __node_allocator& __alloc() _NOEXCEPT
386 {return __before_begin_.second();}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000388 const __node_allocator& __alloc() const _NOEXCEPT
389 {return __before_begin_.second();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000390
391 typedef __forward_list_iterator<__node_pointer> iterator;
392 typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
393
Howard Hinnant0af133f2010-09-21 22:55:27 +0000394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000395 __forward_list_base()
Howard Hinnant91a47502011-06-03 16:20:53 +0000396 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000397 : __before_begin_(__begin_node()) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000399 __forward_list_base(const allocator_type& __a)
400 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
401
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000402#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000403public:
404 __forward_list_base(__forward_list_base&& __x)
405 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000406 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000407#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000408
409private:
410 __forward_list_base(const __forward_list_base&);
411 __forward_list_base& operator=(const __forward_list_base&);
Howard Hinnant3e519522010-05-11 19:42:16 +0000412
Howard Hinnant91a47502011-06-03 16:20:53 +0000413public:
Howard Hinnant3e519522010-05-11 19:42:16 +0000414 ~__forward_list_base();
415
Howard Hinnant91a47502011-06-03 16:20:53 +0000416protected:
Howard Hinnant0af133f2010-09-21 22:55:27 +0000417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000418 void __copy_assign_alloc(const __forward_list_base& __x)
419 {__copy_assign_alloc(__x, integral_constant<bool,
420 __node_traits::propagate_on_container_copy_assignment::value>());}
421
Howard Hinnant0af133f2010-09-21 22:55:27 +0000422 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000423 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000424 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
425 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000426 {__move_assign_alloc(__x, integral_constant<bool,
427 __node_traits::propagate_on_container_move_assignment::value>());}
428
Howard Hinnant91a47502011-06-03 16:20:53 +0000429public:
430 void swap(__forward_list_base& __x)
431 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
432 __is_nothrow_swappable<__node_allocator>::value);
433protected:
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000434 void clear() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000435
436private:
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&, false_type) {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000440 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
441 {
442 if (__alloc() != __x.__alloc())
443 clear();
444 __alloc() = __x.__alloc();
445 }
446
Howard Hinnant0af133f2010-09-21 22:55:27 +0000447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000448 void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
449 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000451 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000452 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000453 {__alloc() = _VSTD::move(__x.__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000454
Howard Hinnant0af133f2010-09-21 22:55:27 +0000455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000456 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +0000457 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
458 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000459 {__swap_alloc(__x, __y, integral_constant<bool,
460 __node_traits::propagate_on_container_swap::value>());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000461 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000462 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
463 false_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000464 _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000465 {}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000467 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
468 true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000469 _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000470 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000471 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000472 swap(__x, __y);
473 }
474};
475
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000476#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000477
478template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000479inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000480__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000481 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000482 : __before_begin_(_VSTD::move(__x.__before_begin_))
Howard Hinnant3e519522010-05-11 19:42:16 +0000483{
484 __x.__before_begin()->__next_ = nullptr;
485}
486
487template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000488inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000489__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
490 const allocator_type& __a)
491 : __before_begin_(__begin_node(), __node_allocator(__a))
492{
493 if (__alloc() == __x.__alloc())
494 {
495 __before_begin()->__next_ = __x.__before_begin()->__next_;
496 __x.__before_begin()->__next_ = nullptr;
497 }
498}
499
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000500#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000501
502template <class _Tp, class _Alloc>
503__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
504{
505 clear();
506}
507
508template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000509inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000510void
511__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000512 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
513 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000514{
515 __swap_alloc(__alloc(), __x.__alloc());
Howard Hinnantce48a112011-06-30 21:18:19 +0000516 using _VSTD::swap;
Howard Hinnant3e519522010-05-11 19:42:16 +0000517 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
518}
519
520template <class _Tp, class _Alloc>
521void
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000522__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000523{
524 __node_allocator& __a = __alloc();
525 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
526 {
527 __node_pointer __next = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000528 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000529 __node_traits::deallocate(__a, __p, 1);
530 __p = __next;
531 }
532 __before_begin()->__next_ = nullptr;
533}
534
535template <class _Tp, class _Alloc = allocator<_Tp> >
Howard Hinnant0af133f2010-09-21 22:55:27 +0000536class _LIBCPP_VISIBLE forward_list
Howard Hinnant3e519522010-05-11 19:42:16 +0000537 : private __forward_list_base<_Tp, _Alloc>
538{
539 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnant91a47502011-06-03 16:20:53 +0000540 typedef typename base::__node_allocator __node_allocator;
541 typedef typename base::__node __node;
542 typedef typename base::__node_traits __node_traits;
543 typedef typename base::__node_pointer __node_pointer;
544
Howard Hinnant3e519522010-05-11 19:42:16 +0000545public:
546 typedef _Tp value_type;
547 typedef _Alloc allocator_type;
548
549 typedef value_type& reference;
550 typedef const value_type& const_reference;
551 typedef typename allocator_traits<allocator_type>::pointer pointer;
552 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
553 typedef typename allocator_traits<allocator_type>::size_type size_type;
554 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
555
556 typedef typename base::iterator iterator;
557 typedef typename base::const_iterator const_iterator;
558
Howard Hinnant91a47502011-06-03 16:20:53 +0000559 _LIBCPP_INLINE_VISIBILITY
560 forward_list()
561 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
562 {} // = default;
Howard Hinnant3e519522010-05-11 19:42:16 +0000563 explicit forward_list(const allocator_type& __a);
564 explicit forward_list(size_type __n);
565 forward_list(size_type __n, const value_type& __v);
566 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
567 template <class _InputIterator>
568 forward_list(_InputIterator __f, _InputIterator __l,
569 typename enable_if<
570 __is_input_iterator<_InputIterator>::value
571 >::type* = nullptr);
572 template <class _InputIterator>
573 forward_list(_InputIterator __f, _InputIterator __l,
574 const allocator_type& __a,
575 typename enable_if<
576 __is_input_iterator<_InputIterator>::value
577 >::type* = nullptr);
578 forward_list(const forward_list& __x);
579 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000580#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000581 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000582 forward_list(forward_list&& __x)
583 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
Howard Hinnantce48a112011-06-30 21:18:19 +0000584 : base(_VSTD::move(__x)) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000585 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000586#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54976f22011-08-12 21:56:02 +0000587#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000588 forward_list(initializer_list<value_type> __il);
589 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
Howard Hinnant54976f22011-08-12 21:56:02 +0000590#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000591
592 // ~forward_list() = default;
593
594 forward_list& operator=(const forward_list& __x);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000595#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000596 forward_list& operator=(forward_list&& __x)
597 _NOEXCEPT_(
598 __node_traits::propagate_on_container_move_assignment::value &&
599 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000600#endif
Howard Hinnant54976f22011-08-12 21:56:02 +0000601#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000602 forward_list& operator=(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000603#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000604
605 template <class _InputIterator>
606 typename enable_if
607 <
608 __is_input_iterator<_InputIterator>::value,
609 void
610 >::type
611 assign(_InputIterator __f, _InputIterator __l);
612 void assign(size_type __n, const value_type& __v);
Howard Hinnant54976f22011-08-12 21:56:02 +0000613#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000614 void assign(initializer_list<value_type> __il);
Howard Hinnant54976f22011-08-12 21:56:02 +0000615#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
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 allocator_type get_allocator() const _NOEXCEPT
619 {return allocator_type(base::__alloc());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000620
Howard Hinnant0af133f2010-09-21 22:55:27 +0000621 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000622 iterator begin() _NOEXCEPT
623 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000624 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000625 const_iterator begin() const _NOEXCEPT
626 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000627 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000628 iterator end() _NOEXCEPT
629 {return iterator(nullptr);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000630 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000631 const_iterator end() const _NOEXCEPT
632 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000633
Howard Hinnant0af133f2010-09-21 22:55:27 +0000634 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000635 const_iterator cbegin() const _NOEXCEPT
636 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000637 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000638 const_iterator cend() const _NOEXCEPT
639 {return const_iterator(nullptr);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000640
Howard Hinnant0af133f2010-09-21 22:55:27 +0000641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000642 iterator before_begin() _NOEXCEPT
643 {return iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000644 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000645 const_iterator before_begin() const _NOEXCEPT
646 {return const_iterator(base::__before_begin());}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000647 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000648 const_iterator cbefore_begin() const _NOEXCEPT
649 {return const_iterator(base::__before_begin());}
Howard Hinnant3e519522010-05-11 19:42:16 +0000650
Howard Hinnant0af133f2010-09-21 22:55:27 +0000651 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000652 bool empty() const _NOEXCEPT
653 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000655 size_type max_size() const _NOEXCEPT
656 {return numeric_limits<size_type>::max();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000657
Howard Hinnant0af133f2010-09-21 22:55:27 +0000658 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000659 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant0af133f2010-09-21 22:55:27 +0000660 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000661 const_reference front() const {return base::__before_begin()->__next_->__value_;}
662
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000663#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
664#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000665 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000666#endif
Howard Hinnant3e519522010-05-11 19:42:16 +0000667 void push_front(value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000668#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000669 void push_front(const value_type& __v);
670
671 void pop_front();
672
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000673#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
674#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000675 template <class... _Args>
676 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000677#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000678 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000679#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000680 iterator insert_after(const_iterator __p, const value_type& __v);
681 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
682 template <class _InputIterator>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000683 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000684 typename enable_if
685 <
686 __is_input_iterator<_InputIterator>::value,
687 iterator
688 >::type
689 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
Howard Hinnant54976f22011-08-12 21:56:02 +0000690#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000691 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
692 {return insert_after(__p, __il.begin(), __il.end());}
Howard Hinnant54976f22011-08-12 21:56:02 +0000693#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
Howard Hinnant3e519522010-05-11 19:42:16 +0000694
Howard Hinnant3db88032010-08-21 20:58:44 +0000695 iterator erase_after(const_iterator __p);
696 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000697
Howard Hinnant0af133f2010-09-21 22:55:27 +0000698 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91a47502011-06-03 16:20:53 +0000699 void swap(forward_list& __x)
700 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
701 __is_nothrow_swappable<__node_allocator>::value)
702 {base::swap(__x);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000703
704 void resize(size_type __n);
705 void resize(size_type __n, const value_type& __v);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000707 void clear() _NOEXCEPT {base::clear();}
Howard Hinnant3e519522010-05-11 19:42:16 +0000708
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000709#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
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);
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, const_iterator __i);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000714 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000715 void splice_after(const_iterator __p, forward_list&& __x,
716 const_iterator __f, const_iterator __l);
Howard Hinnanteb92df72011-01-27 21:00:35 +0000717#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000718 void splice_after(const_iterator __p, forward_list& __x);
719 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
720 void splice_after(const_iterator __p, forward_list& __x,
721 const_iterator __f, const_iterator __l);
Howard Hinnant3e519522010-05-11 19:42:16 +0000722 void remove(const value_type& __v);
723 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000725 void unique() {unique(__equal_to<value_type>());}
726 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000727#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000728 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteb92df72011-01-27 21:00:35 +0000729 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
730 template <class _Compare>
731 _LIBCPP_INLINE_VISIBILITY
732 void merge(forward_list&& __x, _Compare __comp)
Howard Hinnantce48a112011-06-30 21:18:19 +0000733 {merge(__x, _VSTD::move(__comp));}
Howard Hinnanteb92df72011-01-27 21:00:35 +0000734#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant0af133f2010-09-21 22:55:27 +0000735 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000736 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
737 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant0af133f2010-09-21 22:55:27 +0000738 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000739 void sort() {sort(__less<value_type>());}
740 template <class _Compare> void sort(_Compare __comp);
Howard Hinnantf9dc2832011-06-02 16:44:28 +0000741 void reverse() _NOEXCEPT;
Howard Hinnant3e519522010-05-11 19:42:16 +0000742
743private:
Howard Hinnant3e519522010-05-11 19:42:16 +0000744
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000745#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant91a47502011-06-03 16:20:53 +0000746 void __move_assign(forward_list& __x, true_type)
747 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnant3e519522010-05-11 19:42:16 +0000748 void __move_assign(forward_list& __x, false_type);
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000749#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000750
751 template <class _Compare>
752 static
753 __node_pointer
754 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
755
756 template <class _Compare>
757 static
758 __node_pointer
759 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
760};
761
762template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000763inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000764forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
765 : base(__a)
766{
767}
768
769template <class _Tp, class _Alloc>
770forward_list<_Tp, _Alloc>::forward_list(size_type __n)
771{
772 if (__n > 0)
773 {
774 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +0000775 typedef __allocator_destructor<__node_allocator> _Dp;
776 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Howard Hinnant3e519522010-05-11 19:42:16 +0000777 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
778 __p = __p->__next_)
779 {
780 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +0000781 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000782 __h->__next_ = nullptr;
783 __p->__next_ = __h.release();
784 }
785 }
786}
787
788template <class _Tp, class _Alloc>
789forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
790{
791 insert_after(cbefore_begin(), __n, __v);
792}
793
794template <class _Tp, class _Alloc>
795forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
796 const allocator_type& __a)
797 : base(__a)
798{
799 insert_after(cbefore_begin(), __n, __v);
800}
801
802template <class _Tp, class _Alloc>
803template <class _InputIterator>
804forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
805 typename enable_if<
806 __is_input_iterator<_InputIterator>::value
807 >::type*)
808{
809 insert_after(cbefore_begin(), __f, __l);
810}
811
812template <class _Tp, class _Alloc>
813template <class _InputIterator>
814forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
815 const allocator_type& __a,
816 typename enable_if<
817 __is_input_iterator<_InputIterator>::value
818 >::type*)
819 : base(__a)
820{
821 insert_after(cbefore_begin(), __f, __l);
822}
823
824template <class _Tp, class _Alloc>
825forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
826 : base(allocator_type(
827 __node_traits::select_on_container_copy_construction(__x.__alloc())
828 )
829 )
830{
831 insert_after(cbefore_begin(), __x.begin(), __x.end());
832}
833
834template <class _Tp, class _Alloc>
835forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
836 const allocator_type& __a)
837 : base(__a)
838{
839 insert_after(cbefore_begin(), __x.begin(), __x.end());
840}
841
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000842#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000843
844template <class _Tp, class _Alloc>
845forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
846 const allocator_type& __a)
Howard Hinnantce48a112011-06-30 21:18:19 +0000847 : base(_VSTD::move(__x), __a)
Howard Hinnant3e519522010-05-11 19:42:16 +0000848{
849 if (base::__alloc() != __x.__alloc())
850 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000851 typedef move_iterator<iterator> _Ip;
852 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +0000853 }
854}
855
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000856#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000857
Howard Hinnant54976f22011-08-12 21:56:02 +0000858#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
859
Howard Hinnant3e519522010-05-11 19:42:16 +0000860template <class _Tp, class _Alloc>
861forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
862{
863 insert_after(cbefore_begin(), __il.begin(), __il.end());
864}
865
866template <class _Tp, class _Alloc>
867forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
868 const allocator_type& __a)
869 : base(__a)
870{
871 insert_after(cbefore_begin(), __il.begin(), __il.end());
872}
873
Howard Hinnant54976f22011-08-12 21:56:02 +0000874#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
875
Howard Hinnant3e519522010-05-11 19:42:16 +0000876template <class _Tp, class _Alloc>
877forward_list<_Tp, _Alloc>&
878forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
879{
880 if (this != &__x)
881 {
882 base::__copy_assign_alloc(__x);
883 assign(__x.begin(), __x.end());
884 }
885 return *this;
886}
887
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000888#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000889
890template <class _Tp, class _Alloc>
891void
892forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnant91a47502011-06-03 16:20:53 +0000893 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000894{
895 clear();
896 base::__move_assign_alloc(__x);
897 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
898 __x.__before_begin()->__next_ = nullptr;
899}
900
901template <class _Tp, class _Alloc>
902void
903forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
904{
905 if (base::__alloc() == __x.__alloc())
906 __move_assign(__x, true_type());
907 else
908 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000909 typedef move_iterator<iterator> _Ip;
910 assign(_Ip(__x.begin()), _Ip(__x.end()));
Howard Hinnant3e519522010-05-11 19:42:16 +0000911 }
912}
913
914template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000915inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000916forward_list<_Tp, _Alloc>&
917forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnant91a47502011-06-03 16:20:53 +0000918 _NOEXCEPT_(
919 __node_traits::propagate_on_container_move_assignment::value &&
920 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnant3e519522010-05-11 19:42:16 +0000921{
922 __move_assign(__x, integral_constant<bool,
923 __node_traits::propagate_on_container_move_assignment::value>());
924 return *this;
925}
926
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000927#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +0000928
Howard Hinnant54976f22011-08-12 21:56:02 +0000929#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
930
Howard Hinnant3e519522010-05-11 19:42:16 +0000931template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000932inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000933forward_list<_Tp, _Alloc>&
934forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
935{
936 assign(__il.begin(), __il.end());
937 return *this;
938}
939
Howard Hinnant54976f22011-08-12 21:56:02 +0000940#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
941
Howard Hinnant3e519522010-05-11 19:42:16 +0000942template <class _Tp, class _Alloc>
943template <class _InputIterator>
944typename enable_if
945<
946 __is_input_iterator<_InputIterator>::value,
947 void
948>::type
949forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
950{
951 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +0000952 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000953 iterator __e = end();
954 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
955 *__j = *__f;
956 if (__j == __e)
957 insert_after(__i, __f, __l);
958 else
959 erase_after(__i, __e);
960}
961
962template <class _Tp, class _Alloc>
963void
964forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
965{
966 iterator __i = before_begin();
Howard Hinnantce48a112011-06-30 21:18:19 +0000967 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +0000968 iterator __e = end();
969 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
970 *__j = __v;
971 if (__j == __e)
972 insert_after(__i, __n, __v);
973 else
974 erase_after(__i, __e);
975}
976
Howard Hinnant54976f22011-08-12 21:56:02 +0000977#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
978
Howard Hinnant3e519522010-05-11 19:42:16 +0000979template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +0000980inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000981void
982forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
983{
984 assign(__il.begin(), __il.end());
985}
986
Howard Hinnant54976f22011-08-12 21:56:02 +0000987#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
988
Howard Hinnant7609c9b2010-09-04 23:28:19 +0000989#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
990#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +0000991
992template <class _Tp, class _Alloc>
993template <class... _Args>
994void
995forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
996{
997 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +0000998 typedef __allocator_destructor<__node_allocator> _Dp;
999 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001000 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1001 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001002 __h->__next_ = base::__before_begin()->__next_;
1003 base::__before_begin()->__next_ = __h.release();
1004}
1005
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001006#endif // _LIBCPP_HAS_NO_VARIADICS
1007
Howard Hinnant3e519522010-05-11 19:42:16 +00001008template <class _Tp, class _Alloc>
1009void
1010forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1011{
1012 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001013 typedef __allocator_destructor<__node_allocator> _Dp;
1014 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001015 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001016 __h->__next_ = base::__before_begin()->__next_;
1017 base::__before_begin()->__next_ = __h.release();
1018}
1019
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001020#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001021
1022template <class _Tp, class _Alloc>
1023void
1024forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1025{
1026 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001027 typedef __allocator_destructor<__node_allocator> _Dp;
1028 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001029 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001030 __h->__next_ = base::__before_begin()->__next_;
1031 base::__before_begin()->__next_ = __h.release();
1032}
1033
1034template <class _Tp, class _Alloc>
1035void
1036forward_list<_Tp, _Alloc>::pop_front()
1037{
1038 __node_allocator& __a = base::__alloc();
1039 __node_pointer __p = base::__before_begin()->__next_;
1040 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001041 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001042 __node_traits::deallocate(__a, __p, 1);
1043}
1044
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001045#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1046#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnant3e519522010-05-11 19:42:16 +00001047
1048template <class _Tp, class _Alloc>
1049template <class... _Args>
1050typename forward_list<_Tp, _Alloc>::iterator
1051forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1052{
1053 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1054 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001055 typedef __allocator_destructor<__node_allocator> _Dp;
1056 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001057 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1058 _VSTD::forward<_Args>(__args)...);
Howard Hinnant3e519522010-05-11 19:42:16 +00001059 __h->__next_ = __r->__next_;
1060 __r->__next_ = __h.release();
1061 return iterator(__r->__next_);
1062}
1063
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001064#endif // _LIBCPP_HAS_NO_VARIADICS
1065
Howard Hinnant3e519522010-05-11 19:42:16 +00001066template <class _Tp, class _Alloc>
1067typename forward_list<_Tp, _Alloc>::iterator
1068forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1069{
1070 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1071 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001072 typedef __allocator_destructor<__node_allocator> _Dp;
1073 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001074 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
Howard Hinnant3e519522010-05-11 19:42:16 +00001075 __h->__next_ = __r->__next_;
1076 __r->__next_ = __h.release();
1077 return iterator(__r->__next_);
1078}
1079
Howard Hinnant7609c9b2010-09-04 23:28:19 +00001080#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3e519522010-05-11 19:42:16 +00001081
1082template <class _Tp, class _Alloc>
1083typename forward_list<_Tp, _Alloc>::iterator
1084forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1085{
1086 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1087 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001088 typedef __allocator_destructor<__node_allocator> _Dp;
1089 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001090 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001091 __h->__next_ = __r->__next_;
1092 __r->__next_ = __h.release();
1093 return iterator(__r->__next_);
1094}
1095
1096template <class _Tp, class _Alloc>
1097typename forward_list<_Tp, _Alloc>::iterator
1098forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1099 const value_type& __v)
1100{
Howard Hinnante57dc142010-08-19 17:40:04 +00001101 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001102 if (__n > 0)
1103 {
1104 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001105 typedef __allocator_destructor<__node_allocator> _Dp;
1106 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001107 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001108 __node_pointer __first = __h.release();
1109 __node_pointer __last = __first;
1110#ifndef _LIBCPP_NO_EXCEPTIONS
1111 try
1112 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001113#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001114 for (--__n; __n != 0; --__n, __last = __last->__next_)
1115 {
1116 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001117 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001118 __last->__next_ = __h.release();
1119 }
1120#ifndef _LIBCPP_NO_EXCEPTIONS
1121 }
1122 catch (...)
1123 {
1124 while (__first != nullptr)
1125 {
1126 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001127 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001128 __node_traits::deallocate(__a, __first, 1);
1129 __first = __next;
1130 }
1131 throw;
1132 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001133#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001134 __last->__next_ = __r->__next_;
1135 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001136 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001137 }
1138 return iterator(__r);
1139}
1140
1141template <class _Tp, class _Alloc>
1142template <class _InputIterator>
1143typename enable_if
1144<
1145 __is_input_iterator<_InputIterator>::value,
1146 typename forward_list<_Tp, _Alloc>::iterator
1147>::type
1148forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1149 _InputIterator __f, _InputIterator __l)
1150{
Howard Hinnante57dc142010-08-19 17:40:04 +00001151 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001152 if (__f != __l)
1153 {
1154 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001155 typedef __allocator_destructor<__node_allocator> _Dp;
1156 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001157 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001158 __node_pointer __first = __h.release();
1159 __node_pointer __last = __first;
1160#ifndef _LIBCPP_NO_EXCEPTIONS
1161 try
1162 {
Howard Hinnantb3371f62010-08-22 00:02:43 +00001163#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001164 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1165 {
1166 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001167 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
Howard Hinnant3e519522010-05-11 19:42:16 +00001168 __last->__next_ = __h.release();
1169 }
1170#ifndef _LIBCPP_NO_EXCEPTIONS
1171 }
1172 catch (...)
1173 {
1174 while (__first != nullptr)
1175 {
1176 __node_pointer __next = __first->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001177 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001178 __node_traits::deallocate(__a, __first, 1);
1179 __first = __next;
1180 }
1181 throw;
1182 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001183#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3e519522010-05-11 19:42:16 +00001184 __last->__next_ = __r->__next_;
1185 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001186 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001187 }
1188 return iterator(__r);
1189}
1190
1191template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001192typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001193forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1194{
1195 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1196 __node_pointer __n = __p->__next_;
1197 __p->__next_ = __n->__next_;
1198 __node_allocator& __a = base::__alloc();
Howard Hinnantce48a112011-06-30 21:18:19 +00001199 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001200 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant3db88032010-08-21 20:58:44 +00001201 return iterator(__p->__next_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001202}
1203
1204template <class _Tp, class _Alloc>
Howard Hinnant3db88032010-08-21 20:58:44 +00001205typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnant3e519522010-05-11 19:42:16 +00001206forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1207{
Howard Hinnant3db88032010-08-21 20:58:44 +00001208 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnant3e519522010-05-11 19:42:16 +00001209 if (__f != __l)
1210 {
1211 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1212 __node_pointer __n = __p->__next_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001213 if (__n != __e)
1214 {
1215 __p->__next_ = __e;
1216 __node_allocator& __a = base::__alloc();
1217 do
1218 {
1219 __p = __n->__next_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001220 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001221 __node_traits::deallocate(__a, __n, 1);
1222 __n = __p;
1223 } while (__n != __e);
1224 }
1225 }
Howard Hinnant3db88032010-08-21 20:58:44 +00001226 return iterator(__e);
Howard Hinnant3e519522010-05-11 19:42:16 +00001227}
1228
1229template <class _Tp, class _Alloc>
1230void
1231forward_list<_Tp, _Alloc>::resize(size_type __n)
1232{
1233 size_type __sz = 0;
1234 iterator __p = before_begin();
1235 iterator __i = begin();
1236 iterator __e = end();
1237 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1238 ;
1239 if (__i != __e)
1240 erase_after(__p, __e);
1241 else
1242 {
1243 __n -= __sz;
1244 if (__n > 0)
1245 {
1246 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001247 typedef __allocator_destructor<__node_allocator> _Dp;
1248 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Howard Hinnant3e519522010-05-11 19:42:16 +00001249 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1250 __ptr = __ptr->__next_)
1251 {
1252 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001253 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
Howard Hinnant3e519522010-05-11 19:42:16 +00001254 __h->__next_ = nullptr;
1255 __ptr->__next_ = __h.release();
1256 }
1257 }
1258 }
1259}
1260
1261template <class _Tp, class _Alloc>
1262void
1263forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1264{
1265 size_type __sz = 0;
1266 iterator __p = before_begin();
1267 iterator __i = begin();
1268 iterator __e = end();
1269 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1270 ;
1271 if (__i != __e)
1272 erase_after(__p, __e);
1273 else
1274 {
1275 __n -= __sz;
1276 if (__n > 0)
1277 {
1278 __node_allocator& __a = base::__alloc();
Howard Hinnantc003db12011-11-29 18:15:50 +00001279 typedef __allocator_destructor<__node_allocator> _Dp;
1280 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
Howard Hinnant3e519522010-05-11 19:42:16 +00001281 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1282 __ptr = __ptr->__next_)
1283 {
1284 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnantce48a112011-06-30 21:18:19 +00001285 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
Howard Hinnant3e519522010-05-11 19:42:16 +00001286 __h->__next_ = nullptr;
1287 __ptr->__next_ = __h.release();
1288 }
1289 }
1290 }
1291}
1292
1293template <class _Tp, class _Alloc>
1294void
1295forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001296 forward_list& __x)
Howard Hinnant3e519522010-05-11 19:42:16 +00001297{
1298 if (!__x.empty())
1299 {
1300 if (__p.__ptr_->__next_ != nullptr)
1301 {
1302 const_iterator __lm1 = __x.before_begin();
1303 while (__lm1.__ptr_->__next_ != nullptr)
1304 ++__lm1;
1305 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1306 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1307 }
1308 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1309 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1310 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1311 }
1312}
1313
1314template <class _Tp, class _Alloc>
1315void
1316forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001317 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001318 const_iterator __i)
1319{
Howard Hinnantce48a112011-06-30 21:18:19 +00001320 const_iterator __lm1 = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001321 if (__p != __i && __p != __lm1)
1322 {
1323 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1324 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1325 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1326 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1327 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1328 const_cast<__node_pointer>(__lm1.__ptr_);
1329 }
1330}
1331
1332template <class _Tp, class _Alloc>
1333void
1334forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant3e519522010-05-11 19:42:16 +00001335 forward_list& __x,
Howard Hinnant3e519522010-05-11 19:42:16 +00001336 const_iterator __f, const_iterator __l)
1337{
1338 if (__f != __l && __p != __f)
1339 {
1340 const_iterator __lm1 = __f;
1341 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1342 ++__lm1;
1343 if (__f != __lm1)
1344 {
1345 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1346 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1347 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1348 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1349 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1350 const_cast<__node_pointer>(__l.__ptr_);
1351 }
1352 }
1353}
1354
Howard Hinnanteb92df72011-01-27 21:00:35 +00001355#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1356
1357template <class _Tp, class _Alloc>
1358inline _LIBCPP_INLINE_VISIBILITY
1359void
1360forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1361 forward_list&& __x)
1362{
1363 splice_after(__p, __x);
1364}
1365
1366template <class _Tp, class _Alloc>
1367inline _LIBCPP_INLINE_VISIBILITY
1368void
1369forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1370 forward_list&& __x,
1371 const_iterator __i)
1372{
1373 splice_after(__p, __x, __i);
1374}
1375
1376template <class _Tp, class _Alloc>
1377inline _LIBCPP_INLINE_VISIBILITY
1378void
1379forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1380 forward_list&& __x,
1381 const_iterator __f, const_iterator __l)
1382{
1383 splice_after(__p, __x, __f, __l);
1384}
1385
1386#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1387
Howard Hinnant3e519522010-05-11 19:42:16 +00001388template <class _Tp, class _Alloc>
1389void
1390forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1391{
1392 iterator __e = end();
1393 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1394 {
1395 if (__i.__ptr_->__next_->__value_ == __v)
1396 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001397 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001398 for (; __j != __e && *__j == __v; ++__j)
1399 ;
1400 erase_after(__i, __j);
1401 if (__j == __e)
1402 break;
1403 __i = __j;
1404 }
1405 else
1406 ++__i;
1407 }
1408}
1409
1410template <class _Tp, class _Alloc>
1411template <class _Predicate>
1412void
1413forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1414{
1415 iterator __e = end();
1416 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1417 {
1418 if (__pred(__i.__ptr_->__next_->__value_))
1419 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001420 iterator __j = _VSTD::next(__i, 2);
Howard Hinnant3e519522010-05-11 19:42:16 +00001421 for (; __j != __e && __pred(*__j); ++__j)
1422 ;
1423 erase_after(__i, __j);
1424 if (__j == __e)
1425 break;
1426 __i = __j;
1427 }
1428 else
1429 ++__i;
1430 }
1431}
1432
1433template <class _Tp, class _Alloc>
1434template <class _BinaryPredicate>
1435void
1436forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1437{
1438 for (iterator __i = begin(), __e = end(); __i != __e;)
1439 {
Howard Hinnantce48a112011-06-30 21:18:19 +00001440 iterator __j = _VSTD::next(__i);
Howard Hinnant3e519522010-05-11 19:42:16 +00001441 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1442 ;
1443 if (__i.__ptr_->__next_ != __j.__ptr_)
1444 erase_after(__i, __j);
1445 __i = __j;
1446 }
1447}
1448
1449template <class _Tp, class _Alloc>
1450template <class _Compare>
1451void
Howard Hinnant3e519522010-05-11 19:42:16 +00001452forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnant3e519522010-05-11 19:42:16 +00001453{
1454 if (this != &__x)
1455 {
1456 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1457 __x.__before_begin()->__next_,
1458 __comp);
1459 __x.__before_begin()->__next_ = nullptr;
1460 }
1461}
1462
1463template <class _Tp, class _Alloc>
1464template <class _Compare>
1465typename forward_list<_Tp, _Alloc>::__node_pointer
1466forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1467 _Compare& __comp)
1468{
1469 if (__f1 == nullptr)
1470 return __f2;
1471 if (__f2 == nullptr)
1472 return __f1;
1473 __node_pointer __r;
1474 if (__comp(__f2->__value_, __f1->__value_))
1475 {
1476 __node_pointer __t = __f2;
1477 while (__t->__next_ != nullptr &&
1478 __comp(__t->__next_->__value_, __f1->__value_))
1479 __t = __t->__next_;
1480 __r = __f2;
1481 __f2 = __t->__next_;
1482 __t->__next_ = __f1;
1483 }
1484 else
1485 __r = __f1;
1486 __node_pointer __p = __f1;
1487 __f1 = __f1->__next_;
1488 while (__f1 != nullptr && __f2 != nullptr)
1489 {
1490 if (__comp(__f2->__value_, __f1->__value_))
1491 {
1492 __node_pointer __t = __f2;
1493 while (__t->__next_ != nullptr &&
1494 __comp(__t->__next_->__value_, __f1->__value_))
1495 __t = __t->__next_;
1496 __p->__next_ = __f2;
1497 __f2 = __t->__next_;
1498 __t->__next_ = __f1;
1499 }
1500 __p = __f1;
1501 __f1 = __f1->__next_;
1502 }
1503 if (__f2 != nullptr)
1504 __p->__next_ = __f2;
1505 return __r;
1506}
1507
1508template <class _Tp, class _Alloc>
1509template <class _Compare>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001510inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001511void
1512forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1513{
1514 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
Howard Hinnantce48a112011-06-30 21:18:19 +00001515 _VSTD::distance(begin(), end()), __comp);
Howard Hinnant3e519522010-05-11 19:42:16 +00001516}
1517
1518template <class _Tp, class _Alloc>
1519template <class _Compare>
1520typename forward_list<_Tp, _Alloc>::__node_pointer
1521forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1522 _Compare& __comp)
1523{
1524 switch (__sz)
1525 {
1526 case 0:
1527 case 1:
1528 return __f1;
1529 case 2:
1530 if (__comp(__f1->__next_->__value_, __f1->__value_))
1531 {
1532 __node_pointer __t = __f1->__next_;
1533 __t->__next_ = __f1;
1534 __f1->__next_ = nullptr;
1535 __f1 = __t;
1536 }
1537 return __f1;
1538 }
1539 difference_type __sz1 = __sz / 2;
1540 difference_type __sz2 = __sz - __sz1;
Howard Hinnantce48a112011-06-30 21:18:19 +00001541 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;
Howard Hinnant3e519522010-05-11 19:42:16 +00001542 __node_pointer __f2 = __t->__next_;
1543 __t->__next_ = nullptr;
1544 return __merge(__sort(__f1, __sz1, __comp),
1545 __sort(__f2, __sz2, __comp), __comp);
1546}
1547
1548template <class _Tp, class _Alloc>
1549void
Howard Hinnantf9dc2832011-06-02 16:44:28 +00001550forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001551{
1552 __node_pointer __p = base::__before_begin()->__next_;
1553 if (__p != nullptr)
1554 {
1555 __node_pointer __f = __p->__next_;
1556 __p->__next_ = nullptr;
1557 while (__f != nullptr)
1558 {
1559 __node_pointer __t = __f->__next_;
1560 __f->__next_ = __p;
1561 __p = __f;
1562 __f = __t;
1563 }
1564 base::__before_begin()->__next_ = __p;
1565 }
1566}
1567
1568template <class _Tp, class _Alloc>
1569bool operator==(const forward_list<_Tp, _Alloc>& __x,
1570 const forward_list<_Tp, _Alloc>& __y)
1571{
Howard Hinnantc003db12011-11-29 18:15:50 +00001572 typedef forward_list<_Tp, _Alloc> _Cp;
1573 typedef typename _Cp::const_iterator _Ip;
1574 _Ip __ix = __x.begin();
1575 _Ip __ex = __x.end();
1576 _Ip __iy = __y.begin();
1577 _Ip __ey = __y.end();
Howard Hinnant3e519522010-05-11 19:42:16 +00001578 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1579 if (!(*__ix == *__iy))
1580 return false;
1581 return (__ix == __ex) == (__iy == __ey);
1582}
1583
1584template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001585inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001586bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1587 const forward_list<_Tp, _Alloc>& __y)
1588{
1589 return !(__x == __y);
1590}
1591
1592template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001593inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001594bool operator< (const forward_list<_Tp, _Alloc>& __x,
1595 const forward_list<_Tp, _Alloc>& __y)
1596{
Howard Hinnantce48a112011-06-30 21:18:19 +00001597 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
Howard Hinnant3e519522010-05-11 19:42:16 +00001598 __y.begin(), __y.end());
1599}
1600
1601template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001602inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001603bool operator> (const forward_list<_Tp, _Alloc>& __x,
1604 const forward_list<_Tp, _Alloc>& __y)
1605{
1606 return __y < __x;
1607}
1608
1609template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001610inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001611bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1612 const forward_list<_Tp, _Alloc>& __y)
1613{
1614 return !(__x < __y);
1615}
1616
1617template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001618inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001619bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1620 const forward_list<_Tp, _Alloc>& __y)
1621{
1622 return !(__y < __x);
1623}
1624
1625template <class _Tp, class _Alloc>
Howard Hinnant0af133f2010-09-21 22:55:27 +00001626inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001627void
1628swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnant91a47502011-06-03 16:20:53 +00001629 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnant3e519522010-05-11 19:42:16 +00001630{
1631 __x.swap(__y);
1632}
1633
1634_LIBCPP_END_NAMESPACE_STD
1635
1636#endif // _LIBCPP_FORWARD_LIST