blob: aae3317c8fba1a40c896ef8084ff8c0e7a982a84 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------- forward_list ---------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-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 Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +000037 forward_list()
38 noexcept(is_nothrow_default_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +000049 forward_list(forward_list&& x)
50 noexcept(is_nothrow_move_constructible<allocator_type>::value);
Howard Hinnantbc8d3f92010-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 Hinnantb965fed2011-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 Hinnantbc8d3f92010-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 Hinnant8790cab2011-06-02 16:44:28 +000069 allocator_type get_allocator() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000070
Howard Hinnant8790cab2011-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 Hinnantbc8d3f92010-05-11 19:42:16 +000075
Howard Hinnant8790cab2011-06-02 16:44:28 +000076 const_iterator cbegin() const noexcept;
77 const_iterator cend() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000078
Howard Hinnant8790cab2011-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 Hinnantbc8d3f92010-05-11 19:42:16 +000082
Howard Hinnant8790cab2011-06-02 16:44:28 +000083 bool empty() const noexcept;
84 size_type max_size() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant7a2523b2010-08-21 20:58:44 +0000105 iterator erase_after(const_iterator p);
106 iterator erase_after(const_iterator first, const_iterator last);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000107
Howard Hinnantb965fed2011-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000111
112 void resize(size_type n);
113 void resize(size_type n, const value_type& v);
Howard Hinnant8790cab2011-06-02 16:44:28 +0000114 void clear() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000115
Howard Hinnant99b2f762011-01-27 21:00:35 +0000116 void splice_after(const_iterator p, forward_list& x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000117 void splice_after(const_iterator p, forward_list&& x);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000118 void splice_after(const_iterator p, forward_list& x, const_iterator i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000119 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000120 void splice_after(const_iterator p, forward_list& x,
121 const_iterator first, const_iterator last);
Howard Hinnantbc8d3f92010-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 Hinnant99b2f762011-01-27 21:00:35 +0000128 void merge(forward_list& x);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129 void merge(forward_list&& x);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000130 template <class Compare> void merge(forward_list& x, Compare comp);
Howard Hinnantbc8d3f92010-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 Hinnant8790cab2011-06-02 16:44:28 +0000134 void reverse() noexcept;
Howard Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +0000162 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
Howard Hinnantc5607272011-06-03 17:30:28 +0000163 noexcept(noexcept(x.swap(y)));
Howard Hinnantbc8d3f92010-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
181template <class, class> struct __forward_list_node;
182
183template <class _NodePtr>
184struct __forward_begin_node
185{
186 typedef __forward_begin_node __self;
187 typedef _NodePtr pointer;
188
189 pointer __next_;
190
Howard Hinnant42a63a72010-09-21 22:55:27 +0000191 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
Howard Hinnantbc8d3f92010-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
211template<class, class> class forward_list;
212template<class> class __forward_list_const_iterator;
213
214template <class _NodePtr>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000215class _LIBCPP_VISIBLE __forward_list_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000216{
217 typedef _NodePtr __node_pointer;
218
219 __node_pointer __ptr_;
220
Howard Hinnant42a63a72010-09-21 22:55:27 +0000221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000222 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
Howard Hinnantbc8d3f92010-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 Hinnant324bb032010-08-22 00:02:43 +0000232 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000243 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000244
Howard Hinnant42a63a72010-09-21 22:55:27 +0000245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000246 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000248 pointer operator->() const {return &__ptr_->__value_;}
249
Howard Hinnant42a63a72010-09-21 22:55:27 +0000250 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000251 __forward_list_iterator& operator++()
252 {
253 __ptr_ = __ptr_->__next_;
254 return *this;
255 }
Howard Hinnant42a63a72010-09-21 22:55:27 +0000256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000267 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant42a63a72010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000271 {return !(__x == __y);}
272};
273
274template <class _NodeConstPtr>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000275class _LIBCPP_VISIBLE __forward_list_const_iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000276{
277 typedef _NodeConstPtr __node_const_pointer;
278
279 __node_const_pointer __ptr_;
280
Howard Hinnant42a63a72010-09-21 22:55:27 +0000281 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000282 explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-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 Hinnant324bb032010-08-22 00:02:43 +0000303 typedef typename pointer_traits<__node_const_pointer>::difference_type
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000314 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000316 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317 : __ptr_(__p.__ptr_) {}
318
Howard Hinnant42a63a72010-09-21 22:55:27 +0000319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320 reference operator*() const {return __ptr_->__value_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000322 pointer operator->() const {return &__ptr_->__value_;}
323
Howard Hinnant42a63a72010-09-21 22:55:27 +0000324 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000325 __forward_list_const_iterator& operator++()
326 {
327 __ptr_ = __ptr_->__next_;
328 return *this;
329 }
Howard Hinnant42a63a72010-09-21 22:55:27 +0000330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000341 {return __x.__ptr_ == __y.__ptr_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000342 friend _LIBCPP_INLINE_VISIBILITY
343 bool operator!=(const __forward_list_const_iterator& __x,
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000372 __node_pointer __before_begin() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000373 {return pointer_traits<__node_pointer>::pointer_to(
374 static_cast<__node&>(__before_begin_.first()));}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000376 __node_const_pointer __before_begin() const _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000377 {return pointer_traits<__node_const_pointer>::pointer_to(
378 static_cast<const __node&>(__before_begin_.first()));}
379
Howard Hinnant42a63a72010-09-21 22:55:27 +0000380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000381 __node_allocator& __alloc() _NOEXCEPT
382 {return __before_begin_.second();}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000384 const __node_allocator& __alloc() const _NOEXCEPT
385 {return __before_begin_.second();}
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000391 __forward_list_base()
Howard Hinnantb965fed2011-06-03 16:20:53 +0000392 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000393 : __before_begin_(__begin_node()) {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000395 __forward_list_base(const allocator_type& __a)
396 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
397
Howard Hinnant73d21a42010-09-04 23:28:19 +0000398#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantb965fed2011-06-03 16:20:53 +0000399public:
400 __forward_list_base(__forward_list_base&& __x)
401 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000402 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000403#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000408
Howard Hinnantb965fed2011-06-03 16:20:53 +0000409public:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000410 ~__forward_list_base();
411
Howard Hinnantb965fed2011-06-03 16:20:53 +0000412protected:
Howard Hinnant42a63a72010-09-21 22:55:27 +0000413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000418 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000419 void __move_assign_alloc(__forward_list_base& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000420 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
421 is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000422 {__move_assign_alloc(__x, integral_constant<bool,
423 __node_traits::propagate_on_container_move_assignment::value>());}
424
Howard Hinnantb965fed2011-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 Hinnant8790cab2011-06-02 16:44:28 +0000430 void clear() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000431
432private:
Howard Hinnant42a63a72010-09-21 22:55:27 +0000433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000434 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000444 void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
445 {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000447 void __move_assign_alloc(__forward_list_base& __x, true_type)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000448 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000449 {__alloc() = _STD::move(__x.__alloc());}
450
Howard Hinnant42a63a72010-09-21 22:55:27 +0000451 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000452 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000453 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
454 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000455 {__swap_alloc(__x, __y, integral_constant<bool,
456 __node_traits::propagate_on_container_swap::value>());}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000458 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
459 false_type)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000460 _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000461 {}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000462 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000463 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
464 true_type)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000465 _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000466 {
467 using _STD::swap;
468 swap(__x, __y);
469 }
470};
471
Howard Hinnant73d21a42010-09-04 23:28:19 +0000472#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000473
474template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000475inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000476__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000477 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478 : __before_begin_(_STD::move(__x.__before_begin_))
479{
480 __x.__before_begin()->__next_ = nullptr;
481}
482
483template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000484inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-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 Hinnant73d21a42010-09-04 23:28:19 +0000496#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000505inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000506void
507__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000508 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
509 __is_nothrow_swappable<__node_allocator>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000510{
511 __swap_alloc(__alloc(), __x.__alloc());
512 using _STD::swap;
513 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
514}
515
516template <class _Tp, class _Alloc>
517void
Howard Hinnant8790cab2011-06-02 16:44:28 +0000518__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
Howard Hinnantbc8d3f92010-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 Hinnant2529d022011-02-02 17:36:20 +0000524 __node_traits::destroy(__a, _STD::addressof(__p->__value_));
Howard Hinnantbc8d3f92010-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 Hinnant42a63a72010-09-21 22:55:27 +0000532class _LIBCPP_VISIBLE forward_list
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000533 : private __forward_list_base<_Tp, _Alloc>
534{
535 typedef __forward_list_base<_Tp, _Alloc> base;
Howard Hinnantb965fed2011-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 Hinnantbc8d3f92010-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 Hinnantb965fed2011-06-03 16:20:53 +0000555 _LIBCPP_INLINE_VISIBILITY
556 forward_list()
557 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
558 {} // = default;
Howard Hinnantbc8d3f92010-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 Hinnant73d21a42010-09-04 23:28:19 +0000576#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant42a63a72010-09-21 22:55:27 +0000577 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000578 forward_list(forward_list&& __x)
579 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
580 : base(_STD::move(__x)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000581 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000582#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000583 forward_list(initializer_list<value_type> __il);
584 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
585
586 // ~forward_list() = default;
587
588 forward_list& operator=(const forward_list& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000589#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantb965fed2011-06-03 16:20:53 +0000590 forward_list& operator=(forward_list&& __x)
591 _NOEXCEPT_(
592 __node_traits::propagate_on_container_move_assignment::value &&
593 is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000594#endif
595 forward_list& operator=(initializer_list<value_type> __il);
596
597 template <class _InputIterator>
598 typename enable_if
599 <
600 __is_input_iterator<_InputIterator>::value,
601 void
602 >::type
603 assign(_InputIterator __f, _InputIterator __l);
604 void assign(size_type __n, const value_type& __v);
605 void assign(initializer_list<value_type> __il);
606
Howard Hinnant42a63a72010-09-21 22:55:27 +0000607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000608 allocator_type get_allocator() const _NOEXCEPT
609 {return allocator_type(base::__alloc());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000610
Howard Hinnant42a63a72010-09-21 22:55:27 +0000611 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000612 iterator begin() _NOEXCEPT
613 {return iterator(base::__before_begin()->__next_);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000614 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000615 const_iterator begin() const _NOEXCEPT
616 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000618 iterator end() _NOEXCEPT
619 {return iterator(nullptr);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000621 const_iterator end() const _NOEXCEPT
622 {return const_iterator(nullptr);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000623
Howard Hinnant42a63a72010-09-21 22:55:27 +0000624 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000625 const_iterator cbegin() const _NOEXCEPT
626 {return const_iterator(base::__before_begin()->__next_);}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000627 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000628 const_iterator cend() const _NOEXCEPT
629 {return const_iterator(nullptr);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000630
Howard Hinnant42a63a72010-09-21 22:55:27 +0000631 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000632 iterator before_begin() _NOEXCEPT
633 {return iterator(base::__before_begin());}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000634 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000635 const_iterator before_begin() const _NOEXCEPT
636 {return const_iterator(base::__before_begin());}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000637 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000638 const_iterator cbefore_begin() const _NOEXCEPT
639 {return const_iterator(base::__before_begin());}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000640
Howard Hinnant42a63a72010-09-21 22:55:27 +0000641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000642 bool empty() const _NOEXCEPT
643 {return base::__before_begin()->__next_ == nullptr;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000644 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000645 size_type max_size() const _NOEXCEPT
646 {return numeric_limits<size_type>::max();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000647
Howard Hinnant42a63a72010-09-21 22:55:27 +0000648 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000649 reference front() {return base::__before_begin()->__next_->__value_;}
Howard Hinnant42a63a72010-09-21 22:55:27 +0000650 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000651 const_reference front() const {return base::__before_begin()->__next_->__value_;}
652
Howard Hinnant73d21a42010-09-04 23:28:19 +0000653#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
654#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000655 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000656#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000657 void push_front(value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000658#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000659 void push_front(const value_type& __v);
660
661 void pop_front();
662
Howard Hinnant73d21a42010-09-04 23:28:19 +0000663#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
664#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000665 template <class... _Args>
666 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000667#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000668 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000669#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000670 iterator insert_after(const_iterator __p, const value_type& __v);
671 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
672 template <class _InputIterator>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000673 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000674 typename enable_if
675 <
676 __is_input_iterator<_InputIterator>::value,
677 iterator
678 >::type
679 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
680 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
681 {return insert_after(__p, __il.begin(), __il.end());}
682
Howard Hinnant7a2523b2010-08-21 20:58:44 +0000683 iterator erase_after(const_iterator __p);
684 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000685
Howard Hinnant42a63a72010-09-21 22:55:27 +0000686 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb965fed2011-06-03 16:20:53 +0000687 void swap(forward_list& __x)
688 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
689 __is_nothrow_swappable<__node_allocator>::value)
690 {base::swap(__x);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000691
692 void resize(size_type __n);
693 void resize(size_type __n, const value_type& __v);
Howard Hinnant42a63a72010-09-21 22:55:27 +0000694 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8790cab2011-06-02 16:44:28 +0000695 void clear() _NOEXCEPT {base::clear();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000696
Howard Hinnant73d21a42010-09-04 23:28:19 +0000697#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99b2f762011-01-27 21:00:35 +0000698 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000699 void splice_after(const_iterator __p, forward_list&& __x);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000700 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000701 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000702 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000703 void splice_after(const_iterator __p, forward_list&& __x,
704 const_iterator __f, const_iterator __l);
Howard Hinnant99b2f762011-01-27 21:00:35 +0000705#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000706 void splice_after(const_iterator __p, forward_list& __x);
707 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
708 void splice_after(const_iterator __p, forward_list& __x,
709 const_iterator __f, const_iterator __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000710 void remove(const value_type& __v);
711 template <class _Predicate> void remove_if(_Predicate __pred);
Howard Hinnant42a63a72010-09-21 22:55:27 +0000712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000713 void unique() {unique(__equal_to<value_type>());}
714 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000715#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant42a63a72010-09-21 22:55:27 +0000716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99b2f762011-01-27 21:00:35 +0000717 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
718 template <class _Compare>
719 _LIBCPP_INLINE_VISIBILITY
720 void merge(forward_list&& __x, _Compare __comp)
721 {merge(__x, _STD::move(__comp));}
722#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant42a63a72010-09-21 22:55:27 +0000723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000724 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
725 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant42a63a72010-09-21 22:55:27 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000727 void sort() {sort(__less<value_type>());}
728 template <class _Compare> void sort(_Compare __comp);
Howard Hinnant8790cab2011-06-02 16:44:28 +0000729 void reverse() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730
731private:
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000732
Howard Hinnant73d21a42010-09-04 23:28:19 +0000733#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantb965fed2011-06-03 16:20:53 +0000734 void __move_assign(forward_list& __x, true_type)
735 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000736 void __move_assign(forward_list& __x, false_type);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000737#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000738
739 template <class _Compare>
740 static
741 __node_pointer
742 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
743
744 template <class _Compare>
745 static
746 __node_pointer
747 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
748};
749
750template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000751inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000752forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
753 : base(__a)
754{
755}
756
757template <class _Tp, class _Alloc>
758forward_list<_Tp, _Alloc>::forward_list(size_type __n)
759{
760 if (__n > 0)
761 {
762 __node_allocator& __a = base::__alloc();
763 typedef __allocator_destructor<__node_allocator> _D;
764 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
765 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
766 __p = __p->__next_)
767 {
768 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +0000769 __node_traits::construct(__a, _STD::addressof(__h->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000770 __h->__next_ = nullptr;
771 __p->__next_ = __h.release();
772 }
773 }
774}
775
776template <class _Tp, class _Alloc>
777forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
778{
779 insert_after(cbefore_begin(), __n, __v);
780}
781
782template <class _Tp, class _Alloc>
783forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
784 const allocator_type& __a)
785 : base(__a)
786{
787 insert_after(cbefore_begin(), __n, __v);
788}
789
790template <class _Tp, class _Alloc>
791template <class _InputIterator>
792forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
793 typename enable_if<
794 __is_input_iterator<_InputIterator>::value
795 >::type*)
796{
797 insert_after(cbefore_begin(), __f, __l);
798}
799
800template <class _Tp, class _Alloc>
801template <class _InputIterator>
802forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
803 const allocator_type& __a,
804 typename enable_if<
805 __is_input_iterator<_InputIterator>::value
806 >::type*)
807 : base(__a)
808{
809 insert_after(cbefore_begin(), __f, __l);
810}
811
812template <class _Tp, class _Alloc>
813forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
814 : base(allocator_type(
815 __node_traits::select_on_container_copy_construction(__x.__alloc())
816 )
817 )
818{
819 insert_after(cbefore_begin(), __x.begin(), __x.end());
820}
821
822template <class _Tp, class _Alloc>
823forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
824 const allocator_type& __a)
825 : base(__a)
826{
827 insert_after(cbefore_begin(), __x.begin(), __x.end());
828}
829
Howard Hinnant73d21a42010-09-04 23:28:19 +0000830#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000831
832template <class _Tp, class _Alloc>
833forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
834 const allocator_type& __a)
835 : base(_STD::move(__x), __a)
836{
837 if (base::__alloc() != __x.__alloc())
838 {
839 typedef move_iterator<iterator> _I;
840 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
841 }
842}
843
Howard Hinnant73d21a42010-09-04 23:28:19 +0000844#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000845
846template <class _Tp, class _Alloc>
847forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
848{
849 insert_after(cbefore_begin(), __il.begin(), __il.end());
850}
851
852template <class _Tp, class _Alloc>
853forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
854 const allocator_type& __a)
855 : base(__a)
856{
857 insert_after(cbefore_begin(), __il.begin(), __il.end());
858}
859
860template <class _Tp, class _Alloc>
861forward_list<_Tp, _Alloc>&
862forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
863{
864 if (this != &__x)
865 {
866 base::__copy_assign_alloc(__x);
867 assign(__x.begin(), __x.end());
868 }
869 return *this;
870}
871
Howard Hinnant73d21a42010-09-04 23:28:19 +0000872#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000873
874template <class _Tp, class _Alloc>
875void
876forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000877 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000878{
879 clear();
880 base::__move_assign_alloc(__x);
881 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
882 __x.__before_begin()->__next_ = nullptr;
883}
884
885template <class _Tp, class _Alloc>
886void
887forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
888{
889 if (base::__alloc() == __x.__alloc())
890 __move_assign(__x, true_type());
891 else
892 {
893 typedef move_iterator<iterator> _I;
894 assign(_I(__x.begin()), _I(__x.end()));
895 }
896}
897
898template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000899inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000900forward_list<_Tp, _Alloc>&
901forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
Howard Hinnantb965fed2011-06-03 16:20:53 +0000902 _NOEXCEPT_(
903 __node_traits::propagate_on_container_move_assignment::value &&
904 is_nothrow_move_assignable<allocator_type>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000905{
906 __move_assign(__x, integral_constant<bool,
907 __node_traits::propagate_on_container_move_assignment::value>());
908 return *this;
909}
910
Howard Hinnant73d21a42010-09-04 23:28:19 +0000911#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000912
913template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000914inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000915forward_list<_Tp, _Alloc>&
916forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
917{
918 assign(__il.begin(), __il.end());
919 return *this;
920}
921
922template <class _Tp, class _Alloc>
923template <class _InputIterator>
924typename enable_if
925<
926 __is_input_iterator<_InputIterator>::value,
927 void
928>::type
929forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
930{
931 iterator __i = before_begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000932 iterator __j = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000933 iterator __e = end();
934 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
935 *__j = *__f;
936 if (__j == __e)
937 insert_after(__i, __f, __l);
938 else
939 erase_after(__i, __e);
940}
941
942template <class _Tp, class _Alloc>
943void
944forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
945{
946 iterator __i = before_begin();
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000947 iterator __j = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000948 iterator __e = end();
949 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
950 *__j = __v;
951 if (__j == __e)
952 insert_after(__i, __n, __v);
953 else
954 erase_after(__i, __e);
955}
956
957template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000958inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000959void
960forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
961{
962 assign(__il.begin(), __il.end());
963}
964
Howard Hinnant73d21a42010-09-04 23:28:19 +0000965#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
966#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000967
968template <class _Tp, class _Alloc>
969template <class... _Args>
970void
971forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
972{
973 __node_allocator& __a = base::__alloc();
974 typedef __allocator_destructor<__node_allocator> _D;
975 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +0000976 __node_traits::construct(__a, _STD::addressof(__h->__value_),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000977 _STD::forward<_Args>(__args)...);
978 __h->__next_ = base::__before_begin()->__next_;
979 base::__before_begin()->__next_ = __h.release();
980}
981
Howard Hinnant73d21a42010-09-04 23:28:19 +0000982#endif // _LIBCPP_HAS_NO_VARIADICS
983
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000984template <class _Tp, class _Alloc>
985void
986forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
987{
988 __node_allocator& __a = base::__alloc();
989 typedef __allocator_destructor<__node_allocator> _D;
990 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +0000991 __node_traits::construct(__a, _STD::addressof(__h->__value_), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000992 __h->__next_ = base::__before_begin()->__next_;
993 base::__before_begin()->__next_ = __h.release();
994}
995
Howard Hinnant73d21a42010-09-04 23:28:19 +0000996#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000997
998template <class _Tp, class _Alloc>
999void
1000forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1001{
1002 __node_allocator& __a = base::__alloc();
1003 typedef __allocator_destructor<__node_allocator> _D;
1004 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001005 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001006 __h->__next_ = base::__before_begin()->__next_;
1007 base::__before_begin()->__next_ = __h.release();
1008}
1009
1010template <class _Tp, class _Alloc>
1011void
1012forward_list<_Tp, _Alloc>::pop_front()
1013{
1014 __node_allocator& __a = base::__alloc();
1015 __node_pointer __p = base::__before_begin()->__next_;
1016 base::__before_begin()->__next_ = __p->__next_;
Howard Hinnant2529d022011-02-02 17:36:20 +00001017 __node_traits::destroy(__a, _STD::addressof(__p->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001018 __node_traits::deallocate(__a, __p, 1);
1019}
1020
Howard Hinnant73d21a42010-09-04 23:28:19 +00001021#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1022#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001023
1024template <class _Tp, class _Alloc>
1025template <class... _Args>
1026typename forward_list<_Tp, _Alloc>::iterator
1027forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1028{
1029 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1030 __node_allocator& __a = base::__alloc();
1031 typedef __allocator_destructor<__node_allocator> _D;
1032 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001033 __node_traits::construct(__a, _STD::addressof(__h->__value_),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001034 _STD::forward<_Args>(__args)...);
1035 __h->__next_ = __r->__next_;
1036 __r->__next_ = __h.release();
1037 return iterator(__r->__next_);
1038}
1039
Howard Hinnant73d21a42010-09-04 23:28:19 +00001040#endif // _LIBCPP_HAS_NO_VARIADICS
1041
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001042template <class _Tp, class _Alloc>
1043typename forward_list<_Tp, _Alloc>::iterator
1044forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1045{
1046 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1047 __node_allocator& __a = base::__alloc();
1048 typedef __allocator_destructor<__node_allocator> _D;
1049 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001050 __node_traits::construct(__a, _STD::addressof(__h->__value_), _STD::move(__v));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001051 __h->__next_ = __r->__next_;
1052 __r->__next_ = __h.release();
1053 return iterator(__r->__next_);
1054}
1055
Howard Hinnant73d21a42010-09-04 23:28:19 +00001056#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057
1058template <class _Tp, class _Alloc>
1059typename forward_list<_Tp, _Alloc>::iterator
1060forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1061{
1062 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
1063 __node_allocator& __a = base::__alloc();
1064 typedef __allocator_destructor<__node_allocator> _D;
1065 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001066 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001067 __h->__next_ = __r->__next_;
1068 __r->__next_ = __h.release();
1069 return iterator(__r->__next_);
1070}
1071
1072template <class _Tp, class _Alloc>
1073typename forward_list<_Tp, _Alloc>::iterator
1074forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1075 const value_type& __v)
1076{
Howard Hinnantba590bd2010-08-19 17:40:04 +00001077 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001078 if (__n > 0)
1079 {
1080 __node_allocator& __a = base::__alloc();
1081 typedef __allocator_destructor<__node_allocator> _D;
1082 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001083 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001084 __node_pointer __first = __h.release();
1085 __node_pointer __last = __first;
1086#ifndef _LIBCPP_NO_EXCEPTIONS
1087 try
1088 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001089#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001090 for (--__n; __n != 0; --__n, __last = __last->__next_)
1091 {
1092 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001093 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001094 __last->__next_ = __h.release();
1095 }
1096#ifndef _LIBCPP_NO_EXCEPTIONS
1097 }
1098 catch (...)
1099 {
1100 while (__first != nullptr)
1101 {
1102 __node_pointer __next = __first->__next_;
Howard Hinnant2529d022011-02-02 17:36:20 +00001103 __node_traits::destroy(__a, _STD::addressof(__first->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001104 __node_traits::deallocate(__a, __first, 1);
1105 __first = __next;
1106 }
1107 throw;
1108 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001109#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001110 __last->__next_ = __r->__next_;
1111 __r->__next_ = __first;
Howard Hinnantba590bd2010-08-19 17:40:04 +00001112 __r = __last;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001113 }
1114 return iterator(__r);
1115}
1116
1117template <class _Tp, class _Alloc>
1118template <class _InputIterator>
1119typename enable_if
1120<
1121 __is_input_iterator<_InputIterator>::value,
1122 typename forward_list<_Tp, _Alloc>::iterator
1123>::type
1124forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1125 _InputIterator __f, _InputIterator __l)
1126{
Howard Hinnantba590bd2010-08-19 17:40:04 +00001127 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001128 if (__f != __l)
1129 {
1130 __node_allocator& __a = base::__alloc();
1131 typedef __allocator_destructor<__node_allocator> _D;
1132 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001133 __node_traits::construct(__a, _STD::addressof(__h->__value_), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001134 __node_pointer __first = __h.release();
1135 __node_pointer __last = __first;
1136#ifndef _LIBCPP_NO_EXCEPTIONS
1137 try
1138 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001139#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001140 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1141 {
1142 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001143 __node_traits::construct(__a, _STD::addressof(__h->__value_), *__f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001144 __last->__next_ = __h.release();
1145 }
1146#ifndef _LIBCPP_NO_EXCEPTIONS
1147 }
1148 catch (...)
1149 {
1150 while (__first != nullptr)
1151 {
1152 __node_pointer __next = __first->__next_;
Howard Hinnant2529d022011-02-02 17:36:20 +00001153 __node_traits::destroy(__a, _STD::addressof(__first->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001154 __node_traits::deallocate(__a, __first, 1);
1155 __first = __next;
1156 }
1157 throw;
1158 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001159#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001160 __last->__next_ = __r->__next_;
1161 __r->__next_ = __first;
Howard Hinnantba590bd2010-08-19 17:40:04 +00001162 __r = __last;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001163 }
1164 return iterator(__r);
1165}
1166
1167template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001168typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001169forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1170{
1171 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1172 __node_pointer __n = __p->__next_;
1173 __p->__next_ = __n->__next_;
1174 __node_allocator& __a = base::__alloc();
Howard Hinnant2529d022011-02-02 17:36:20 +00001175 __node_traits::destroy(__a, _STD::addressof(__n->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001176 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001177 return iterator(__p->__next_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001178}
1179
1180template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001181typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001182forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1183{
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001184 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001185 if (__f != __l)
1186 {
1187 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1188 __node_pointer __n = __p->__next_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001189 if (__n != __e)
1190 {
1191 __p->__next_ = __e;
1192 __node_allocator& __a = base::__alloc();
1193 do
1194 {
1195 __p = __n->__next_;
Howard Hinnant2529d022011-02-02 17:36:20 +00001196 __node_traits::destroy(__a, _STD::addressof(__n->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001197 __node_traits::deallocate(__a, __n, 1);
1198 __n = __p;
1199 } while (__n != __e);
1200 }
1201 }
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001202 return iterator(__e);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001203}
1204
1205template <class _Tp, class _Alloc>
1206void
1207forward_list<_Tp, _Alloc>::resize(size_type __n)
1208{
1209 size_type __sz = 0;
1210 iterator __p = before_begin();
1211 iterator __i = begin();
1212 iterator __e = end();
1213 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1214 ;
1215 if (__i != __e)
1216 erase_after(__p, __e);
1217 else
1218 {
1219 __n -= __sz;
1220 if (__n > 0)
1221 {
1222 __node_allocator& __a = base::__alloc();
1223 typedef __allocator_destructor<__node_allocator> _D;
1224 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1225 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1226 __ptr = __ptr->__next_)
1227 {
1228 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001229 __node_traits::construct(__a, _STD::addressof(__h->__value_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001230 __h->__next_ = nullptr;
1231 __ptr->__next_ = __h.release();
1232 }
1233 }
1234 }
1235}
1236
1237template <class _Tp, class _Alloc>
1238void
1239forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1240{
1241 size_type __sz = 0;
1242 iterator __p = before_begin();
1243 iterator __i = begin();
1244 iterator __e = end();
1245 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1246 ;
1247 if (__i != __e)
1248 erase_after(__p, __e);
1249 else
1250 {
1251 __n -= __sz;
1252 if (__n > 0)
1253 {
1254 __node_allocator& __a = base::__alloc();
1255 typedef __allocator_destructor<__node_allocator> _D;
1256 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1257 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1258 __ptr = __ptr->__next_)
1259 {
1260 __h.reset(__node_traits::allocate(__a, 1));
Howard Hinnant2529d022011-02-02 17:36:20 +00001261 __node_traits::construct(__a, _STD::addressof(__h->__value_), __v);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001262 __h->__next_ = nullptr;
1263 __ptr->__next_ = __h.release();
1264 }
1265 }
1266 }
1267}
1268
1269template <class _Tp, class _Alloc>
1270void
1271forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001272 forward_list& __x)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001273{
1274 if (!__x.empty())
1275 {
1276 if (__p.__ptr_->__next_ != nullptr)
1277 {
1278 const_iterator __lm1 = __x.before_begin();
1279 while (__lm1.__ptr_->__next_ != nullptr)
1280 ++__lm1;
1281 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1282 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1283 }
1284 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1285 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1286 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1287 }
1288}
1289
1290template <class _Tp, class _Alloc>
1291void
1292forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001293 forward_list& __x,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001294 const_iterator __i)
1295{
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001296 const_iterator __lm1 = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001297 if (__p != __i && __p != __lm1)
1298 {
1299 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1300 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1301 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1302 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1303 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1304 const_cast<__node_pointer>(__lm1.__ptr_);
1305 }
1306}
1307
1308template <class _Tp, class _Alloc>
1309void
1310forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001311 forward_list& __x,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001312 const_iterator __f, const_iterator __l)
1313{
1314 if (__f != __l && __p != __f)
1315 {
1316 const_iterator __lm1 = __f;
1317 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1318 ++__lm1;
1319 if (__f != __lm1)
1320 {
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>(__f.__ptr_)->__next_;
1325 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1326 const_cast<__node_pointer>(__l.__ptr_);
1327 }
1328 }
1329}
1330
Howard Hinnant99b2f762011-01-27 21:00:35 +00001331#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1332
1333template <class _Tp, class _Alloc>
1334inline _LIBCPP_INLINE_VISIBILITY
1335void
1336forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1337 forward_list&& __x)
1338{
1339 splice_after(__p, __x);
1340}
1341
1342template <class _Tp, class _Alloc>
1343inline _LIBCPP_INLINE_VISIBILITY
1344void
1345forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1346 forward_list&& __x,
1347 const_iterator __i)
1348{
1349 splice_after(__p, __x, __i);
1350}
1351
1352template <class _Tp, class _Alloc>
1353inline _LIBCPP_INLINE_VISIBILITY
1354void
1355forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1356 forward_list&& __x,
1357 const_iterator __f, const_iterator __l)
1358{
1359 splice_after(__p, __x, __f, __l);
1360}
1361
1362#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1363
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001364template <class _Tp, class _Alloc>
1365void
1366forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1367{
1368 iterator __e = end();
1369 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1370 {
1371 if (__i.__ptr_->__next_->__value_ == __v)
1372 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001373 iterator __j = _STD::next(__i, 2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001374 for (; __j != __e && *__j == __v; ++__j)
1375 ;
1376 erase_after(__i, __j);
1377 if (__j == __e)
1378 break;
1379 __i = __j;
1380 }
1381 else
1382 ++__i;
1383 }
1384}
1385
1386template <class _Tp, class _Alloc>
1387template <class _Predicate>
1388void
1389forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1390{
1391 iterator __e = end();
1392 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1393 {
1394 if (__pred(__i.__ptr_->__next_->__value_))
1395 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001396 iterator __j = _STD::next(__i, 2);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001397 for (; __j != __e && __pred(*__j); ++__j)
1398 ;
1399 erase_after(__i, __j);
1400 if (__j == __e)
1401 break;
1402 __i = __j;
1403 }
1404 else
1405 ++__i;
1406 }
1407}
1408
1409template <class _Tp, class _Alloc>
1410template <class _BinaryPredicate>
1411void
1412forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1413{
1414 for (iterator __i = begin(), __e = end(); __i != __e;)
1415 {
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001416 iterator __j = _STD::next(__i);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001417 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1418 ;
1419 if (__i.__ptr_->__next_ != __j.__ptr_)
1420 erase_after(__i, __j);
1421 __i = __j;
1422 }
1423}
1424
1425template <class _Tp, class _Alloc>
1426template <class _Compare>
1427void
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001428forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001429{
1430 if (this != &__x)
1431 {
1432 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1433 __x.__before_begin()->__next_,
1434 __comp);
1435 __x.__before_begin()->__next_ = nullptr;
1436 }
1437}
1438
1439template <class _Tp, class _Alloc>
1440template <class _Compare>
1441typename forward_list<_Tp, _Alloc>::__node_pointer
1442forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1443 _Compare& __comp)
1444{
1445 if (__f1 == nullptr)
1446 return __f2;
1447 if (__f2 == nullptr)
1448 return __f1;
1449 __node_pointer __r;
1450 if (__comp(__f2->__value_, __f1->__value_))
1451 {
1452 __node_pointer __t = __f2;
1453 while (__t->__next_ != nullptr &&
1454 __comp(__t->__next_->__value_, __f1->__value_))
1455 __t = __t->__next_;
1456 __r = __f2;
1457 __f2 = __t->__next_;
1458 __t->__next_ = __f1;
1459 }
1460 else
1461 __r = __f1;
1462 __node_pointer __p = __f1;
1463 __f1 = __f1->__next_;
1464 while (__f1 != nullptr && __f2 != nullptr)
1465 {
1466 if (__comp(__f2->__value_, __f1->__value_))
1467 {
1468 __node_pointer __t = __f2;
1469 while (__t->__next_ != nullptr &&
1470 __comp(__t->__next_->__value_, __f1->__value_))
1471 __t = __t->__next_;
1472 __p->__next_ = __f2;
1473 __f2 = __t->__next_;
1474 __t->__next_ = __f1;
1475 }
1476 __p = __f1;
1477 __f1 = __f1->__next_;
1478 }
1479 if (__f2 != nullptr)
1480 __p->__next_ = __f2;
1481 return __r;
1482}
1483
1484template <class _Tp, class _Alloc>
1485template <class _Compare>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001486inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001487void
1488forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1489{
1490 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1491 _STD::distance(begin(), end()), __comp);
1492}
1493
1494template <class _Tp, class _Alloc>
1495template <class _Compare>
1496typename forward_list<_Tp, _Alloc>::__node_pointer
1497forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1498 _Compare& __comp)
1499{
1500 switch (__sz)
1501 {
1502 case 0:
1503 case 1:
1504 return __f1;
1505 case 2:
1506 if (__comp(__f1->__next_->__value_, __f1->__value_))
1507 {
1508 __node_pointer __t = __f1->__next_;
1509 __t->__next_ = __f1;
1510 __f1->__next_ = nullptr;
1511 __f1 = __t;
1512 }
1513 return __f1;
1514 }
1515 difference_type __sz1 = __sz / 2;
1516 difference_type __sz2 = __sz - __sz1;
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +00001517 __node_pointer __t = _STD::next(iterator(__f1), __sz1 - 1).__ptr_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001518 __node_pointer __f2 = __t->__next_;
1519 __t->__next_ = nullptr;
1520 return __merge(__sort(__f1, __sz1, __comp),
1521 __sort(__f2, __sz2, __comp), __comp);
1522}
1523
1524template <class _Tp, class _Alloc>
1525void
Howard Hinnant8790cab2011-06-02 16:44:28 +00001526forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001527{
1528 __node_pointer __p = base::__before_begin()->__next_;
1529 if (__p != nullptr)
1530 {
1531 __node_pointer __f = __p->__next_;
1532 __p->__next_ = nullptr;
1533 while (__f != nullptr)
1534 {
1535 __node_pointer __t = __f->__next_;
1536 __f->__next_ = __p;
1537 __p = __f;
1538 __f = __t;
1539 }
1540 base::__before_begin()->__next_ = __p;
1541 }
1542}
1543
1544template <class _Tp, class _Alloc>
1545bool operator==(const forward_list<_Tp, _Alloc>& __x,
1546 const forward_list<_Tp, _Alloc>& __y)
1547{
1548 typedef forward_list<_Tp, _Alloc> _C;
1549 typedef typename _C::const_iterator _I;
1550 _I __ix = __x.begin();
1551 _I __ex = __x.end();
1552 _I __iy = __y.begin();
1553 _I __ey = __y.end();
1554 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1555 if (!(*__ix == *__iy))
1556 return false;
1557 return (__ix == __ex) == (__iy == __ey);
1558}
1559
1560template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001561inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001562bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1563 const forward_list<_Tp, _Alloc>& __y)
1564{
1565 return !(__x == __y);
1566}
1567
1568template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001569inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001570bool operator< (const forward_list<_Tp, _Alloc>& __x,
1571 const forward_list<_Tp, _Alloc>& __y)
1572{
1573 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1574 __y.begin(), __y.end());
1575}
1576
1577template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001578inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001579bool operator> (const forward_list<_Tp, _Alloc>& __x,
1580 const forward_list<_Tp, _Alloc>& __y)
1581{
1582 return __y < __x;
1583}
1584
1585template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001586inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001587bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1588 const forward_list<_Tp, _Alloc>& __y)
1589{
1590 return !(__x < __y);
1591}
1592
1593template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001594inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001595bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1596 const forward_list<_Tp, _Alloc>& __y)
1597{
1598 return !(__y < __x);
1599}
1600
1601template <class _Tp, class _Alloc>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001602inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001603void
1604swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
Howard Hinnantb965fed2011-06-03 16:20:53 +00001605 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001606{
1607 __x.swap(__y);
1608}
1609
1610_LIBCPP_END_NAMESPACE_STD
1611
1612#endif // _LIBCPP_FORWARD_LIST