blob: b23981ec7e9e1fa9d24589b197f063480bc24e63 [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//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FORWARD_LIST
12#define _LIBCPP_FORWARD_LIST
13
14/*
15 forward_list synopsis
16
17namespace std
18{
19
20template <class T, class Allocator = allocator<T>>
21class forward_list
22{
23public:
24 typedef T value_type;
25 typedef Allocator allocator_type;
26
27 typedef value_type& reference;
28 typedef const value_type& const_reference;
29 typedef typename allocator_traits<allocator_type>::pointer pointer;
30 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
31 typedef typename allocator_traits<allocator_type>::size_type size_type;
32 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
33
34 typedef <details> iterator;
35 typedef <details> const_iterator;
36
37 forward_list();
38 explicit forward_list(const allocator_type& a);
39 explicit forward_list(size_type n);
40 forward_list(size_type n, const value_type& v);
41 forward_list(size_type n, const value_type& v, const allocator_type& a);
42 template <class InputIterator>
43 forward_list(InputIterator first, InputIterator last);
44 template <class InputIterator>
45 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
46 forward_list(const forward_list& x);
47 forward_list(const forward_list& x, const allocator_type& a);
48 forward_list(forward_list&& x);
49 forward_list(forward_list&& x, const allocator_type& a);
50 forward_list(initializer_list<value_type> il);
51 forward_list(initializer_list<value_type> il, const allocator_type& a);
52
53 ~forward_list();
54
55 forward_list& operator=(const forward_list& x);
56 forward_list& operator=(forward_list&& x);
57 forward_list& operator=(initializer_list<value_type> il);
58
59 template <class InputIterator>
60 void assign(InputIterator first, InputIterator last);
61 void assign(size_type n, const value_type& v);
62 void assign(initializer_list<value_type> il);
63
64 allocator_type get_allocator() const;
65
66 iterator begin();
67 const_iterator begin() const;
68 iterator end();
69 const_iterator end() const;
70
71 const_iterator cbegin() const;
72 const_iterator cend() const;
73
74 iterator before_begin();
75 const_iterator before_begin() const;
76 const_iterator cbefore_begin() const;
77
78 bool empty() const;
79 size_type max_size() const;
80
81 reference front();
82 const_reference front() const;
83
84 template <class... Args> void emplace_front(Args&&... args);
85 void push_front(const value_type& v);
86 void push_front(value_type&& v);
87
88 void pop_front();
89
90 template <class... Args>
91 iterator emplace_after(const_iterator p, Args&&... args);
92 iterator insert_after(const_iterator p, const value_type& v);
93 iterator insert_after(const_iterator p, value_type&& v);
94 iterator insert_after(const_iterator p, size_type n, const value_type& v);
95 template <class InputIterator>
96 iterator insert_after(const_iterator p,
97 InputIterator first, InputIterator last);
98 iterator insert_after(const_iterator p, initializer_list<value_type> il);
99
Howard Hinnant7a2523b2010-08-21 20:58:44 +0000100 iterator erase_after(const_iterator p);
101 iterator erase_after(const_iterator first, const_iterator last);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000102
103 void swap(forward_list& x);
104
105 void resize(size_type n);
106 void resize(size_type n, const value_type& v);
107 void clear();
108
109 void splice_after(const_iterator p, forward_list&& x);
110 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
111 void splice_after(const_iterator p, forward_list&& x,
112 const_iterator first, const_iterator last);
113 void remove(const value_type& v);
114 template <class Predicate> void remove_if(Predicate pred);
115 void unique();
116 template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
117 void merge(forward_list&& x);
118 template <class Compare> void merge(forward_list&& x, Compare comp);
119 void sort();
120 template <class Compare> void sort(Compare comp);
121 void reverse();
122};
123
124template <class T, class Allocator>
125 bool operator==(const forward_list<T, Allocator>& x,
126 const forward_list<T, Allocator>& y);
127
128template <class T, class Allocator>
129 bool operator< (const forward_list<T, Allocator>& x,
130 const forward_list<T, Allocator>& y);
131
132template <class T, class Allocator>
133 bool operator!=(const forward_list<T, Allocator>& x,
134 const forward_list<T, Allocator>& y);
135
136template <class T, class Allocator>
137 bool operator> (const forward_list<T, Allocator>& x,
138 const forward_list<T, Allocator>& y);
139
140template <class T, class Allocator>
141 bool operator>=(const forward_list<T, Allocator>& x,
142 const forward_list<T, Allocator>& y);
143
144template <class T, class Allocator>
145 bool operator<=(const forward_list<T, Allocator>& x,
146 const forward_list<T, Allocator>& y);
147
148template <class T, class Allocator>
149 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y);
150
151} // std
152
153*/
154
155#include <__config>
156
157#include <initializer_list>
158#include <memory>
159#include <limits>
160#include <iterator>
161#include <algorithm>
162
163#pragma GCC system_header
164
165_LIBCPP_BEGIN_NAMESPACE_STD
166
167template <class, class> struct __forward_list_node;
168
169template <class _NodePtr>
170struct __forward_begin_node
171{
172 typedef __forward_begin_node __self;
173 typedef _NodePtr pointer;
174
175 pointer __next_;
176
177 __forward_begin_node() : __next_(nullptr) {}
178};
179
180template <class _Tp, class _VoidPtr>
181struct __forward_list_node
182 : public __forward_begin_node
183 <
184 typename pointer_traits<_VoidPtr>::template
185#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
186 rebind<__forward_list_node<_Tp, _VoidPtr> >
187#else
188 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
189#endif
190 >
191{
192 typedef _Tp value_type;
193
194 value_type __value_;
195};
196
197template<class, class> class forward_list;
198template<class> class __forward_list_const_iterator;
199
200template <class _NodePtr>
201class __forward_list_iterator
202{
203 typedef _NodePtr __node_pointer;
204
205 __node_pointer __ptr_;
206
207 explicit __forward_list_iterator(__node_pointer __p) : __ptr_(__p) {}
208
209 template<class, class> friend class forward_list;
210 template<class> friend class __forward_list_const_iterator;
211
212public:
213 typedef forward_iterator_tag iterator_category;
214 typedef typename pointer_traits<__node_pointer>::element_type::value_type
215 value_type;
216 typedef value_type& reference;
Howard Hinnant324bb032010-08-22 00:02:43 +0000217 typedef typename pointer_traits<__node_pointer>::difference_type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000218 difference_type;
219 typedef typename pointer_traits<__node_pointer>::template
220#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
221 rebind<value_type>
222#else
223 rebind<value_type>::other
224#endif
225 pointer;
226
227 __forward_list_iterator() : __ptr_(nullptr) {}
228
229 reference operator*() const {return __ptr_->__value_;}
230 pointer operator->() const {return &__ptr_->__value_;}
231
232 __forward_list_iterator& operator++()
233 {
234 __ptr_ = __ptr_->__next_;
235 return *this;
236 }
237 __forward_list_iterator operator++(int)
238 {
239 __forward_list_iterator __t(*this);
240 ++(*this);
241 return __t;
242 }
243
244 friend bool operator==(const __forward_list_iterator& __x,
245 const __forward_list_iterator& __y)
246 {return __x.__ptr_ == __y.__ptr_;}
247 friend bool operator!=(const __forward_list_iterator& __x,
248 const __forward_list_iterator& __y)
249 {return !(__x == __y);}
250};
251
252template <class _NodeConstPtr>
253class __forward_list_const_iterator
254{
255 typedef _NodeConstPtr __node_const_pointer;
256
257 __node_const_pointer __ptr_;
258
259 explicit __forward_list_const_iterator(__node_const_pointer __p)
260 : __ptr_(__p) {}
261
262 typedef typename remove_const
263 <
264 typename pointer_traits<__node_const_pointer>::element_type
265 >::type __node;
266 typedef typename pointer_traits<__node_const_pointer>::template
267#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
268 rebind<__node>
269#else
270 rebind<__node>::other
271#endif
272 __node_pointer;
273
274 template<class, class> friend class forward_list;
275
276public:
277 typedef forward_iterator_tag iterator_category;
278 typedef typename __node::value_type value_type;
279 typedef const value_type& reference;
Howard Hinnant324bb032010-08-22 00:02:43 +0000280 typedef typename pointer_traits<__node_const_pointer>::difference_type
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000281 difference_type;
282 typedef typename pointer_traits<__node_const_pointer>::template
283#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
284 rebind<const value_type>
285#else
286 rebind<const value_type>::other
287#endif
288 pointer;
289
290 __forward_list_const_iterator() : __ptr_(nullptr) {}
291 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p)
292 : __ptr_(__p.__ptr_) {}
293
294 reference operator*() const {return __ptr_->__value_;}
295 pointer operator->() const {return &__ptr_->__value_;}
296
297 __forward_list_const_iterator& operator++()
298 {
299 __ptr_ = __ptr_->__next_;
300 return *this;
301 }
302 __forward_list_const_iterator operator++(int)
303 {
304 __forward_list_const_iterator __t(*this);
305 ++(*this);
306 return __t;
307 }
308
309 friend bool operator==(const __forward_list_const_iterator& __x,
310 const __forward_list_const_iterator& __y)
311 {return __x.__ptr_ == __y.__ptr_;}
312 friend bool operator!=(const __forward_list_const_iterator& __x,
313 const __forward_list_const_iterator& __y)
314 {return !(__x == __y);}
315};
316
317template <class _Tp, class _Alloc>
318class __forward_list_base
319{
320protected:
321 typedef _Tp value_type;
322 typedef _Alloc allocator_type;
323
324 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
325 typedef __forward_list_node<value_type, void_pointer> __node;
326 typedef typename __node::__self __begin_node;
327 typedef typename allocator_traits<allocator_type>::template
328#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
329 rebind_alloc<__node>
330#else
331 rebind_alloc<__node>::other
332#endif
333 __node_allocator;
334 typedef allocator_traits<__node_allocator> __node_traits;
335 typedef typename __node_traits::pointer __node_pointer;
336 typedef typename __node_traits::const_pointer __node_const_pointer;
337
338 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
339
340 __node_pointer __before_begin()
341 {return pointer_traits<__node_pointer>::pointer_to(
342 static_cast<__node&>(__before_begin_.first()));}
343 __node_const_pointer __before_begin() const
344 {return pointer_traits<__node_const_pointer>::pointer_to(
345 static_cast<const __node&>(__before_begin_.first()));}
346
347 __node_allocator& __alloc() {return __before_begin_.second();}
348 const __node_allocator& __alloc() const {return __before_begin_.second();}
349
350 typedef __forward_list_iterator<__node_pointer> iterator;
351 typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
352
353 __forward_list_base()
354 : __before_begin_(__begin_node()) {}
355 __forward_list_base(const allocator_type& __a)
356 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
357
Howard Hinnant73d21a42010-09-04 23:28:19 +0000358#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000359 __forward_list_base(__forward_list_base&& __x);
360 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000361#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000362
363private:
364 __forward_list_base(const __forward_list_base&);
365 __forward_list_base& operator=(const __forward_list_base&);
366protected:
367
368 ~__forward_list_base();
369
370 void __copy_assign_alloc(const __forward_list_base& __x)
371 {__copy_assign_alloc(__x, integral_constant<bool,
372 __node_traits::propagate_on_container_copy_assignment::value>());}
373
374 void __move_assign_alloc(__forward_list_base& __x)
375 {__move_assign_alloc(__x, integral_constant<bool,
376 __node_traits::propagate_on_container_move_assignment::value>());}
377
378 void swap(__forward_list_base& __x);
379 void clear();
380
381private:
382 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
383 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
384 {
385 if (__alloc() != __x.__alloc())
386 clear();
387 __alloc() = __x.__alloc();
388 }
389
390 void __move_assign_alloc(__forward_list_base& __x, false_type) {}
391 void __move_assign_alloc(__forward_list_base& __x, true_type)
392 {__alloc() = _STD::move(__x.__alloc());}
393
394 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
395 {__swap_alloc(__x, __y, integral_constant<bool,
396 __node_traits::propagate_on_container_swap::value>());}
397 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
398 false_type)
399 {}
400 static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
401 true_type)
402 {
403 using _STD::swap;
404 swap(__x, __y);
405 }
406};
407
Howard Hinnant73d21a42010-09-04 23:28:19 +0000408#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409
410template <class _Tp, class _Alloc>
411inline
412__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
413 : __before_begin_(_STD::move(__x.__before_begin_))
414{
415 __x.__before_begin()->__next_ = nullptr;
416}
417
418template <class _Tp, class _Alloc>
419inline
420__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
421 const allocator_type& __a)
422 : __before_begin_(__begin_node(), __node_allocator(__a))
423{
424 if (__alloc() == __x.__alloc())
425 {
426 __before_begin()->__next_ = __x.__before_begin()->__next_;
427 __x.__before_begin()->__next_ = nullptr;
428 }
429}
430
Howard Hinnant73d21a42010-09-04 23:28:19 +0000431#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432
433template <class _Tp, class _Alloc>
434__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
435{
436 clear();
437}
438
439template <class _Tp, class _Alloc>
440inline
441void
442__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
443{
444 __swap_alloc(__alloc(), __x.__alloc());
445 using _STD::swap;
446 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
447}
448
449template <class _Tp, class _Alloc>
450void
451__forward_list_base<_Tp, _Alloc>::clear()
452{
453 __node_allocator& __a = __alloc();
454 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
455 {
456 __node_pointer __next = __p->__next_;
457 __node_traits::destroy(__a, addressof(__p->__value_));
458 __node_traits::deallocate(__a, __p, 1);
459 __p = __next;
460 }
461 __before_begin()->__next_ = nullptr;
462}
463
464template <class _Tp, class _Alloc = allocator<_Tp> >
465class forward_list
466 : private __forward_list_base<_Tp, _Alloc>
467{
468 typedef __forward_list_base<_Tp, _Alloc> base;
469public:
470 typedef _Tp value_type;
471 typedef _Alloc allocator_type;
472
473 typedef value_type& reference;
474 typedef const value_type& const_reference;
475 typedef typename allocator_traits<allocator_type>::pointer pointer;
476 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
477 typedef typename allocator_traits<allocator_type>::size_type size_type;
478 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
479
480 typedef typename base::iterator iterator;
481 typedef typename base::const_iterator const_iterator;
482
483 forward_list() {} // = default;
484 explicit forward_list(const allocator_type& __a);
485 explicit forward_list(size_type __n);
486 forward_list(size_type __n, const value_type& __v);
487 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
488 template <class _InputIterator>
489 forward_list(_InputIterator __f, _InputIterator __l,
490 typename enable_if<
491 __is_input_iterator<_InputIterator>::value
492 >::type* = nullptr);
493 template <class _InputIterator>
494 forward_list(_InputIterator __f, _InputIterator __l,
495 const allocator_type& __a,
496 typename enable_if<
497 __is_input_iterator<_InputIterator>::value
498 >::type* = nullptr);
499 forward_list(const forward_list& __x);
500 forward_list(const forward_list& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000501#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000502 forward_list(forward_list&& __x) : base(_STD::move(__x)) {}
503 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000504#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000505 forward_list(initializer_list<value_type> __il);
506 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
507
508 // ~forward_list() = default;
509
510 forward_list& operator=(const forward_list& __x);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000511#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000512 forward_list& operator=(forward_list&& __x);
513#endif
514 forward_list& operator=(initializer_list<value_type> __il);
515
516 template <class _InputIterator>
517 typename enable_if
518 <
519 __is_input_iterator<_InputIterator>::value,
520 void
521 >::type
522 assign(_InputIterator __f, _InputIterator __l);
523 void assign(size_type __n, const value_type& __v);
524 void assign(initializer_list<value_type> __il);
525
526 allocator_type get_allocator() const {return allocator_type(base::__alloc());}
527
528 iterator begin() {return iterator(base::__before_begin()->__next_);}
529 const_iterator begin() const {return const_iterator(base::__before_begin()->__next_);}
530 iterator end() {return iterator(nullptr);}
531 const_iterator end() const {return const_iterator(nullptr);}
532
533 const_iterator cbegin() const {return const_iterator(base::__before_begin()->__next_);}
534 const_iterator cend() const {return const_iterator(nullptr);}
535
536 iterator before_begin() {return iterator(base::__before_begin());}
537 const_iterator before_begin() const {return const_iterator(base::__before_begin());}
538 const_iterator cbefore_begin() const {return const_iterator(base::__before_begin());}
539
540 bool empty() const {return base::__before_begin()->__next_ == nullptr;}
541 size_type max_size() const {return numeric_limits<size_type>::max();}
542
543 reference front() {return base::__before_begin()->__next_->__value_;}
544 const_reference front() const {return base::__before_begin()->__next_->__value_;}
545
Howard Hinnant73d21a42010-09-04 23:28:19 +0000546#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
547#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000548 template <class... _Args> void emplace_front(_Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000549#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000550 void push_front(value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000551#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000552 void push_front(const value_type& __v);
553
554 void pop_front();
555
Howard Hinnant73d21a42010-09-04 23:28:19 +0000556#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
557#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000558 template <class... _Args>
559 iterator emplace_after(const_iterator __p, _Args&&... __args);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000560#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000561 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000562#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000563 iterator insert_after(const_iterator __p, const value_type& __v);
564 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
565 template <class _InputIterator>
566 typename enable_if
567 <
568 __is_input_iterator<_InputIterator>::value,
569 iterator
570 >::type
571 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
572 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
573 {return insert_after(__p, __il.begin(), __il.end());}
574
Howard Hinnant7a2523b2010-08-21 20:58:44 +0000575 iterator erase_after(const_iterator __p);
576 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000577
578 void swap(forward_list& __x) {base::swap(__x);}
579
580 void resize(size_type __n);
581 void resize(size_type __n, const value_type& __v);
582 void clear() {base::clear();}
583
Howard Hinnant73d21a42010-09-04 23:28:19 +0000584#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000585 void splice_after(const_iterator __p, forward_list&& __x);
586 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
587 void splice_after(const_iterator __p, forward_list&& __x,
588 const_iterator __f, const_iterator __l);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000589#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000590 void splice_after(const_iterator __p, forward_list& __x);
591 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
592 void splice_after(const_iterator __p, forward_list& __x,
593 const_iterator __f, const_iterator __l);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000594#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000595 void remove(const value_type& __v);
596 template <class _Predicate> void remove_if(_Predicate __pred);
597 void unique() {unique(__equal_to<value_type>());}
598 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000599#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000600 void merge(forward_list&& __x) {merge(_STD::move(__x), __less<value_type>());}
601 template <class _Compare> void merge(forward_list&& __x, _Compare __comp);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000602#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000603 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
604 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000605#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000606 void sort() {sort(__less<value_type>());}
607 template <class _Compare> void sort(_Compare __comp);
608 void reverse();
609
610private:
611 typedef typename base::__node_allocator __node_allocator;
612 typedef typename base::__node __node;
613 typedef typename base::__node_traits __node_traits;
614 typedef typename base::__node_pointer __node_pointer;
615
Howard Hinnant73d21a42010-09-04 23:28:19 +0000616#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000617 void __move_assign(forward_list& __x, true_type);
618 void __move_assign(forward_list& __x, false_type);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000619#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000620
621 template <class _Compare>
622 static
623 __node_pointer
624 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
625
626 template <class _Compare>
627 static
628 __node_pointer
629 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
630};
631
632template <class _Tp, class _Alloc>
633inline
634forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
635 : base(__a)
636{
637}
638
639template <class _Tp, class _Alloc>
640forward_list<_Tp, _Alloc>::forward_list(size_type __n)
641{
642 if (__n > 0)
643 {
644 __node_allocator& __a = base::__alloc();
645 typedef __allocator_destructor<__node_allocator> _D;
646 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
647 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
648 __p = __p->__next_)
649 {
650 __h.reset(__node_traits::allocate(__a, 1));
651 __node_traits::construct(__a, addressof(__h->__value_));
652 __h->__next_ = nullptr;
653 __p->__next_ = __h.release();
654 }
655 }
656}
657
658template <class _Tp, class _Alloc>
659forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
660{
661 insert_after(cbefore_begin(), __n, __v);
662}
663
664template <class _Tp, class _Alloc>
665forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
666 const allocator_type& __a)
667 : base(__a)
668{
669 insert_after(cbefore_begin(), __n, __v);
670}
671
672template <class _Tp, class _Alloc>
673template <class _InputIterator>
674forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
675 typename enable_if<
676 __is_input_iterator<_InputIterator>::value
677 >::type*)
678{
679 insert_after(cbefore_begin(), __f, __l);
680}
681
682template <class _Tp, class _Alloc>
683template <class _InputIterator>
684forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
685 const allocator_type& __a,
686 typename enable_if<
687 __is_input_iterator<_InputIterator>::value
688 >::type*)
689 : base(__a)
690{
691 insert_after(cbefore_begin(), __f, __l);
692}
693
694template <class _Tp, class _Alloc>
695forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
696 : base(allocator_type(
697 __node_traits::select_on_container_copy_construction(__x.__alloc())
698 )
699 )
700{
701 insert_after(cbefore_begin(), __x.begin(), __x.end());
702}
703
704template <class _Tp, class _Alloc>
705forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
706 const allocator_type& __a)
707 : base(__a)
708{
709 insert_after(cbefore_begin(), __x.begin(), __x.end());
710}
711
Howard Hinnant73d21a42010-09-04 23:28:19 +0000712#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000713
714template <class _Tp, class _Alloc>
715forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
716 const allocator_type& __a)
717 : base(_STD::move(__x), __a)
718{
719 if (base::__alloc() != __x.__alloc())
720 {
721 typedef move_iterator<iterator> _I;
722 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
723 }
724}
725
Howard Hinnant73d21a42010-09-04 23:28:19 +0000726#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000727
728template <class _Tp, class _Alloc>
729forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
730{
731 insert_after(cbefore_begin(), __il.begin(), __il.end());
732}
733
734template <class _Tp, class _Alloc>
735forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
736 const allocator_type& __a)
737 : base(__a)
738{
739 insert_after(cbefore_begin(), __il.begin(), __il.end());
740}
741
742template <class _Tp, class _Alloc>
743forward_list<_Tp, _Alloc>&
744forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
745{
746 if (this != &__x)
747 {
748 base::__copy_assign_alloc(__x);
749 assign(__x.begin(), __x.end());
750 }
751 return *this;
752}
753
Howard Hinnant73d21a42010-09-04 23:28:19 +0000754#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000755
756template <class _Tp, class _Alloc>
757void
758forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
759{
760 clear();
761 base::__move_assign_alloc(__x);
762 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
763 __x.__before_begin()->__next_ = nullptr;
764}
765
766template <class _Tp, class _Alloc>
767void
768forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
769{
770 if (base::__alloc() == __x.__alloc())
771 __move_assign(__x, true_type());
772 else
773 {
774 typedef move_iterator<iterator> _I;
775 assign(_I(__x.begin()), _I(__x.end()));
776 }
777}
778
779template <class _Tp, class _Alloc>
780inline
781forward_list<_Tp, _Alloc>&
782forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
783{
784 __move_assign(__x, integral_constant<bool,
785 __node_traits::propagate_on_container_move_assignment::value>());
786 return *this;
787}
788
Howard Hinnant73d21a42010-09-04 23:28:19 +0000789#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000790
791template <class _Tp, class _Alloc>
792inline
793forward_list<_Tp, _Alloc>&
794forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
795{
796 assign(__il.begin(), __il.end());
797 return *this;
798}
799
800template <class _Tp, class _Alloc>
801template <class _InputIterator>
802typename enable_if
803<
804 __is_input_iterator<_InputIterator>::value,
805 void
806>::type
807forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
808{
809 iterator __i = before_begin();
810 iterator __j = next(__i);
811 iterator __e = end();
812 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
813 *__j = *__f;
814 if (__j == __e)
815 insert_after(__i, __f, __l);
816 else
817 erase_after(__i, __e);
818}
819
820template <class _Tp, class _Alloc>
821void
822forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
823{
824 iterator __i = before_begin();
825 iterator __j = next(__i);
826 iterator __e = end();
827 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
828 *__j = __v;
829 if (__j == __e)
830 insert_after(__i, __n, __v);
831 else
832 erase_after(__i, __e);
833}
834
835template <class _Tp, class _Alloc>
836inline
837void
838forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
839{
840 assign(__il.begin(), __il.end());
841}
842
Howard Hinnant73d21a42010-09-04 23:28:19 +0000843#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
844#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000845
846template <class _Tp, class _Alloc>
847template <class... _Args>
848void
849forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
850{
851 __node_allocator& __a = base::__alloc();
852 typedef __allocator_destructor<__node_allocator> _D;
853 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
854 __node_traits::construct(__a, addressof(__h->__value_),
855 _STD::forward<_Args>(__args)...);
856 __h->__next_ = base::__before_begin()->__next_;
857 base::__before_begin()->__next_ = __h.release();
858}
859
Howard Hinnant73d21a42010-09-04 23:28:19 +0000860#endif // _LIBCPP_HAS_NO_VARIADICS
861
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000862template <class _Tp, class _Alloc>
863void
864forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
865{
866 __node_allocator& __a = base::__alloc();
867 typedef __allocator_destructor<__node_allocator> _D;
868 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
869 __node_traits::construct(__a, addressof(__h->__value_), _STD::move(__v));
870 __h->__next_ = base::__before_begin()->__next_;
871 base::__before_begin()->__next_ = __h.release();
872}
873
Howard Hinnant73d21a42010-09-04 23:28:19 +0000874#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000875
876template <class _Tp, class _Alloc>
877void
878forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
879{
880 __node_allocator& __a = base::__alloc();
881 typedef __allocator_destructor<__node_allocator> _D;
882 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
883 __node_traits::construct(__a, addressof(__h->__value_), __v);
884 __h->__next_ = base::__before_begin()->__next_;
885 base::__before_begin()->__next_ = __h.release();
886}
887
888template <class _Tp, class _Alloc>
889void
890forward_list<_Tp, _Alloc>::pop_front()
891{
892 __node_allocator& __a = base::__alloc();
893 __node_pointer __p = base::__before_begin()->__next_;
894 base::__before_begin()->__next_ = __p->__next_;
895 __node_traits::destroy(__a, addressof(__p->__value_));
896 __node_traits::deallocate(__a, __p, 1);
897}
898
Howard Hinnant73d21a42010-09-04 23:28:19 +0000899#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
900#ifndef _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000901
902template <class _Tp, class _Alloc>
903template <class... _Args>
904typename forward_list<_Tp, _Alloc>::iterator
905forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
906{
907 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
908 __node_allocator& __a = base::__alloc();
909 typedef __allocator_destructor<__node_allocator> _D;
910 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
911 __node_traits::construct(__a, addressof(__h->__value_),
912 _STD::forward<_Args>(__args)...);
913 __h->__next_ = __r->__next_;
914 __r->__next_ = __h.release();
915 return iterator(__r->__next_);
916}
917
Howard Hinnant73d21a42010-09-04 23:28:19 +0000918#endif // _LIBCPP_HAS_NO_VARIADICS
919
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000920template <class _Tp, class _Alloc>
921typename forward_list<_Tp, _Alloc>::iterator
922forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
923{
924 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
925 __node_allocator& __a = base::__alloc();
926 typedef __allocator_destructor<__node_allocator> _D;
927 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
928 __node_traits::construct(__a, addressof(__h->__value_), _STD::move(__v));
929 __h->__next_ = __r->__next_;
930 __r->__next_ = __h.release();
931 return iterator(__r->__next_);
932}
933
Howard Hinnant73d21a42010-09-04 23:28:19 +0000934#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000935
936template <class _Tp, class _Alloc>
937typename forward_list<_Tp, _Alloc>::iterator
938forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
939{
940 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
941 __node_allocator& __a = base::__alloc();
942 typedef __allocator_destructor<__node_allocator> _D;
943 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
944 __node_traits::construct(__a, addressof(__h->__value_), __v);
945 __h->__next_ = __r->__next_;
946 __r->__next_ = __h.release();
947 return iterator(__r->__next_);
948}
949
950template <class _Tp, class _Alloc>
951typename forward_list<_Tp, _Alloc>::iterator
952forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
953 const value_type& __v)
954{
Howard Hinnantba590bd2010-08-19 17:40:04 +0000955 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000956 if (__n > 0)
957 {
958 __node_allocator& __a = base::__alloc();
959 typedef __allocator_destructor<__node_allocator> _D;
960 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
961 __node_traits::construct(__a, addressof(__h->__value_), __v);
962 __node_pointer __first = __h.release();
963 __node_pointer __last = __first;
964#ifndef _LIBCPP_NO_EXCEPTIONS
965 try
966 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000967#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000968 for (--__n; __n != 0; --__n, __last = __last->__next_)
969 {
970 __h.reset(__node_traits::allocate(__a, 1));
971 __node_traits::construct(__a, addressof(__h->__value_), __v);
972 __last->__next_ = __h.release();
973 }
974#ifndef _LIBCPP_NO_EXCEPTIONS
975 }
976 catch (...)
977 {
978 while (__first != nullptr)
979 {
980 __node_pointer __next = __first->__next_;
981 __node_traits::destroy(__a, addressof(__first->__value_));
982 __node_traits::deallocate(__a, __first, 1);
983 __first = __next;
984 }
985 throw;
986 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000987#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000988 __last->__next_ = __r->__next_;
989 __r->__next_ = __first;
Howard Hinnantba590bd2010-08-19 17:40:04 +0000990 __r = __last;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000991 }
992 return iterator(__r);
993}
994
995template <class _Tp, class _Alloc>
996template <class _InputIterator>
997typename enable_if
998<
999 __is_input_iterator<_InputIterator>::value,
1000 typename forward_list<_Tp, _Alloc>::iterator
1001>::type
1002forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1003 _InputIterator __f, _InputIterator __l)
1004{
Howard Hinnantba590bd2010-08-19 17:40:04 +00001005 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001006 if (__f != __l)
1007 {
1008 __node_allocator& __a = base::__alloc();
1009 typedef __allocator_destructor<__node_allocator> _D;
1010 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1011 __node_traits::construct(__a, addressof(__h->__value_), *__f);
1012 __node_pointer __first = __h.release();
1013 __node_pointer __last = __first;
1014#ifndef _LIBCPP_NO_EXCEPTIONS
1015 try
1016 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001017#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001018 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1019 {
1020 __h.reset(__node_traits::allocate(__a, 1));
1021 __node_traits::construct(__a, addressof(__h->__value_), *__f);
1022 __last->__next_ = __h.release();
1023 }
1024#ifndef _LIBCPP_NO_EXCEPTIONS
1025 }
1026 catch (...)
1027 {
1028 while (__first != nullptr)
1029 {
1030 __node_pointer __next = __first->__next_;
1031 __node_traits::destroy(__a, addressof(__first->__value_));
1032 __node_traits::deallocate(__a, __first, 1);
1033 __first = __next;
1034 }
1035 throw;
1036 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001037#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001038 __last->__next_ = __r->__next_;
1039 __r->__next_ = __first;
Howard Hinnantba590bd2010-08-19 17:40:04 +00001040 __r = __last;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001041 }
1042 return iterator(__r);
1043}
1044
1045template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001046typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001047forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1048{
1049 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1050 __node_pointer __n = __p->__next_;
1051 __p->__next_ = __n->__next_;
1052 __node_allocator& __a = base::__alloc();
1053 __node_traits::destroy(__a, addressof(__n->__value_));
1054 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001055 return iterator(__p->__next_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001056}
1057
1058template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001059typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001060forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1061{
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001062 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001063 if (__f != __l)
1064 {
1065 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1066 __node_pointer __n = __p->__next_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001067 if (__n != __e)
1068 {
1069 __p->__next_ = __e;
1070 __node_allocator& __a = base::__alloc();
1071 do
1072 {
1073 __p = __n->__next_;
1074 __node_traits::destroy(__a, addressof(__n->__value_));
1075 __node_traits::deallocate(__a, __n, 1);
1076 __n = __p;
1077 } while (__n != __e);
1078 }
1079 }
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001080 return iterator(__e);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001081}
1082
1083template <class _Tp, class _Alloc>
1084void
1085forward_list<_Tp, _Alloc>::resize(size_type __n)
1086{
1087 size_type __sz = 0;
1088 iterator __p = before_begin();
1089 iterator __i = begin();
1090 iterator __e = end();
1091 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1092 ;
1093 if (__i != __e)
1094 erase_after(__p, __e);
1095 else
1096 {
1097 __n -= __sz;
1098 if (__n > 0)
1099 {
1100 __node_allocator& __a = base::__alloc();
1101 typedef __allocator_destructor<__node_allocator> _D;
1102 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1103 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1104 __ptr = __ptr->__next_)
1105 {
1106 __h.reset(__node_traits::allocate(__a, 1));
1107 __node_traits::construct(__a, addressof(__h->__value_));
1108 __h->__next_ = nullptr;
1109 __ptr->__next_ = __h.release();
1110 }
1111 }
1112 }
1113}
1114
1115template <class _Tp, class _Alloc>
1116void
1117forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1118{
1119 size_type __sz = 0;
1120 iterator __p = before_begin();
1121 iterator __i = begin();
1122 iterator __e = end();
1123 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1124 ;
1125 if (__i != __e)
1126 erase_after(__p, __e);
1127 else
1128 {
1129 __n -= __sz;
1130 if (__n > 0)
1131 {
1132 __node_allocator& __a = base::__alloc();
1133 typedef __allocator_destructor<__node_allocator> _D;
1134 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1135 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1136 __ptr = __ptr->__next_)
1137 {
1138 __h.reset(__node_traits::allocate(__a, 1));
1139 __node_traits::construct(__a, addressof(__h->__value_), __v);
1140 __h->__next_ = nullptr;
1141 __ptr->__next_ = __h.release();
1142 }
1143 }
1144 }
1145}
1146
1147template <class _Tp, class _Alloc>
1148void
1149forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant73d21a42010-09-04 23:28:19 +00001150#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001151 forward_list&& __x)
1152#else
1153 forward_list& __x)
1154#endif
1155{
1156 if (!__x.empty())
1157 {
1158 if (__p.__ptr_->__next_ != nullptr)
1159 {
1160 const_iterator __lm1 = __x.before_begin();
1161 while (__lm1.__ptr_->__next_ != nullptr)
1162 ++__lm1;
1163 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1164 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1165 }
1166 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1167 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1168 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1169 }
1170}
1171
1172template <class _Tp, class _Alloc>
1173void
1174forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant73d21a42010-09-04 23:28:19 +00001175#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001176 forward_list&& __x,
1177#else
1178 forward_list& __x,
1179#endif
1180 const_iterator __i)
1181{
1182 const_iterator __lm1 = next(__i);
1183 if (__p != __i && __p != __lm1)
1184 {
1185 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1186 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1187 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1188 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1189 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1190 const_cast<__node_pointer>(__lm1.__ptr_);
1191 }
1192}
1193
1194template <class _Tp, class _Alloc>
1195void
1196forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
Howard Hinnant73d21a42010-09-04 23:28:19 +00001197#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001198 forward_list&& __x,
1199#else
1200 forward_list& __x,
1201#endif
1202 const_iterator __f, const_iterator __l)
1203{
1204 if (__f != __l && __p != __f)
1205 {
1206 const_iterator __lm1 = __f;
1207 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1208 ++__lm1;
1209 if (__f != __lm1)
1210 {
1211 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1212 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1213 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1214 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1215 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1216 const_cast<__node_pointer>(__l.__ptr_);
1217 }
1218 }
1219}
1220
1221template <class _Tp, class _Alloc>
1222void
1223forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1224{
1225 iterator __e = end();
1226 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1227 {
1228 if (__i.__ptr_->__next_->__value_ == __v)
1229 {
1230 iterator __j = next(__i, 2);
1231 for (; __j != __e && *__j == __v; ++__j)
1232 ;
1233 erase_after(__i, __j);
1234 if (__j == __e)
1235 break;
1236 __i = __j;
1237 }
1238 else
1239 ++__i;
1240 }
1241}
1242
1243template <class _Tp, class _Alloc>
1244template <class _Predicate>
1245void
1246forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1247{
1248 iterator __e = end();
1249 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1250 {
1251 if (__pred(__i.__ptr_->__next_->__value_))
1252 {
1253 iterator __j = next(__i, 2);
1254 for (; __j != __e && __pred(*__j); ++__j)
1255 ;
1256 erase_after(__i, __j);
1257 if (__j == __e)
1258 break;
1259 __i = __j;
1260 }
1261 else
1262 ++__i;
1263 }
1264}
1265
1266template <class _Tp, class _Alloc>
1267template <class _BinaryPredicate>
1268void
1269forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1270{
1271 for (iterator __i = begin(), __e = end(); __i != __e;)
1272 {
1273 iterator __j = next(__i);
1274 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1275 ;
1276 if (__i.__ptr_->__next_ != __j.__ptr_)
1277 erase_after(__i, __j);
1278 __i = __j;
1279 }
1280}
1281
1282template <class _Tp, class _Alloc>
1283template <class _Compare>
1284void
Howard Hinnant73d21a42010-09-04 23:28:19 +00001285#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001286forward_list<_Tp, _Alloc>::merge(forward_list&& __x, _Compare __comp)
1287#else
1288forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1289#endif
1290{
1291 if (this != &__x)
1292 {
1293 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1294 __x.__before_begin()->__next_,
1295 __comp);
1296 __x.__before_begin()->__next_ = nullptr;
1297 }
1298}
1299
1300template <class _Tp, class _Alloc>
1301template <class _Compare>
1302typename forward_list<_Tp, _Alloc>::__node_pointer
1303forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1304 _Compare& __comp)
1305{
1306 if (__f1 == nullptr)
1307 return __f2;
1308 if (__f2 == nullptr)
1309 return __f1;
1310 __node_pointer __r;
1311 if (__comp(__f2->__value_, __f1->__value_))
1312 {
1313 __node_pointer __t = __f2;
1314 while (__t->__next_ != nullptr &&
1315 __comp(__t->__next_->__value_, __f1->__value_))
1316 __t = __t->__next_;
1317 __r = __f2;
1318 __f2 = __t->__next_;
1319 __t->__next_ = __f1;
1320 }
1321 else
1322 __r = __f1;
1323 __node_pointer __p = __f1;
1324 __f1 = __f1->__next_;
1325 while (__f1 != nullptr && __f2 != nullptr)
1326 {
1327 if (__comp(__f2->__value_, __f1->__value_))
1328 {
1329 __node_pointer __t = __f2;
1330 while (__t->__next_ != nullptr &&
1331 __comp(__t->__next_->__value_, __f1->__value_))
1332 __t = __t->__next_;
1333 __p->__next_ = __f2;
1334 __f2 = __t->__next_;
1335 __t->__next_ = __f1;
1336 }
1337 __p = __f1;
1338 __f1 = __f1->__next_;
1339 }
1340 if (__f2 != nullptr)
1341 __p->__next_ = __f2;
1342 return __r;
1343}
1344
1345template <class _Tp, class _Alloc>
1346template <class _Compare>
1347inline
1348void
1349forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1350{
1351 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1352 _STD::distance(begin(), end()), __comp);
1353}
1354
1355template <class _Tp, class _Alloc>
1356template <class _Compare>
1357typename forward_list<_Tp, _Alloc>::__node_pointer
1358forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1359 _Compare& __comp)
1360{
1361 switch (__sz)
1362 {
1363 case 0:
1364 case 1:
1365 return __f1;
1366 case 2:
1367 if (__comp(__f1->__next_->__value_, __f1->__value_))
1368 {
1369 __node_pointer __t = __f1->__next_;
1370 __t->__next_ = __f1;
1371 __f1->__next_ = nullptr;
1372 __f1 = __t;
1373 }
1374 return __f1;
1375 }
1376 difference_type __sz1 = __sz / 2;
1377 difference_type __sz2 = __sz - __sz1;
1378 __node_pointer __t = next(iterator(__f1), __sz1 - 1).__ptr_;
1379 __node_pointer __f2 = __t->__next_;
1380 __t->__next_ = nullptr;
1381 return __merge(__sort(__f1, __sz1, __comp),
1382 __sort(__f2, __sz2, __comp), __comp);
1383}
1384
1385template <class _Tp, class _Alloc>
1386void
1387forward_list<_Tp, _Alloc>::reverse()
1388{
1389 __node_pointer __p = base::__before_begin()->__next_;
1390 if (__p != nullptr)
1391 {
1392 __node_pointer __f = __p->__next_;
1393 __p->__next_ = nullptr;
1394 while (__f != nullptr)
1395 {
1396 __node_pointer __t = __f->__next_;
1397 __f->__next_ = __p;
1398 __p = __f;
1399 __f = __t;
1400 }
1401 base::__before_begin()->__next_ = __p;
1402 }
1403}
1404
1405template <class _Tp, class _Alloc>
1406bool operator==(const forward_list<_Tp, _Alloc>& __x,
1407 const forward_list<_Tp, _Alloc>& __y)
1408{
1409 typedef forward_list<_Tp, _Alloc> _C;
1410 typedef typename _C::const_iterator _I;
1411 _I __ix = __x.begin();
1412 _I __ex = __x.end();
1413 _I __iy = __y.begin();
1414 _I __ey = __y.end();
1415 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1416 if (!(*__ix == *__iy))
1417 return false;
1418 return (__ix == __ex) == (__iy == __ey);
1419}
1420
1421template <class _Tp, class _Alloc>
1422inline
1423bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1424 const forward_list<_Tp, _Alloc>& __y)
1425{
1426 return !(__x == __y);
1427}
1428
1429template <class _Tp, class _Alloc>
1430inline
1431bool operator< (const forward_list<_Tp, _Alloc>& __x,
1432 const forward_list<_Tp, _Alloc>& __y)
1433{
1434 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1435 __y.begin(), __y.end());
1436}
1437
1438template <class _Tp, class _Alloc>
1439inline
1440bool operator> (const forward_list<_Tp, _Alloc>& __x,
1441 const forward_list<_Tp, _Alloc>& __y)
1442{
1443 return __y < __x;
1444}
1445
1446template <class _Tp, class _Alloc>
1447inline
1448bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1449 const forward_list<_Tp, _Alloc>& __y)
1450{
1451 return !(__x < __y);
1452}
1453
1454template <class _Tp, class _Alloc>
1455inline
1456bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1457 const forward_list<_Tp, _Alloc>& __y)
1458{
1459 return !(__y < __x);
1460}
1461
1462template <class _Tp, class _Alloc>
1463inline
1464void
1465swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1466{
1467 __x.swap(__y);
1468}
1469
1470_LIBCPP_END_NAMESPACE_STD
1471
1472#endif // _LIBCPP_FORWARD_LIST