blob: 9e68dfd47493544503f10e4af14c209dc799ea53 [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
358#ifdef _LIBCPP_MOVE
359 __forward_list_base(__forward_list_base&& __x);
360 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
Howard Hinnant324bb032010-08-22 00:02:43 +0000361#endif // _LIBCPP_MOVE
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
408#ifdef _LIBCPP_MOVE
409
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 Hinnant324bb032010-08-22 00:02:43 +0000431#endif // _LIBCPP_MOVE
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);
501#ifdef _LIBCPP_MOVE
502 forward_list(forward_list&& __x) : base(_STD::move(__x)) {}
503 forward_list(forward_list&& __x, const allocator_type& __a);
Howard Hinnant324bb032010-08-22 00:02:43 +0000504#endif // _LIBCPP_MOVE
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);
511#ifdef _LIBCPP_MOVE
512 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
546#ifdef _LIBCPP_MOVE
547 template <class... _Args> void emplace_front(_Args&&... __args);
548 void push_front(value_type&& __v);
Howard Hinnant324bb032010-08-22 00:02:43 +0000549#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000550 void push_front(const value_type& __v);
551
552 void pop_front();
553
554#ifdef _LIBCPP_MOVE
555 template <class... _Args>
556 iterator emplace_after(const_iterator __p, _Args&&... __args);
557 iterator insert_after(const_iterator __p, value_type&& __v);
Howard Hinnant324bb032010-08-22 00:02:43 +0000558#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000559 iterator insert_after(const_iterator __p, const value_type& __v);
560 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
561 template <class _InputIterator>
562 typename enable_if
563 <
564 __is_input_iterator<_InputIterator>::value,
565 iterator
566 >::type
567 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
568 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
569 {return insert_after(__p, __il.begin(), __il.end());}
570
Howard Hinnant7a2523b2010-08-21 20:58:44 +0000571 iterator erase_after(const_iterator __p);
572 iterator erase_after(const_iterator __f, const_iterator __l);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000573
574 void swap(forward_list& __x) {base::swap(__x);}
575
576 void resize(size_type __n);
577 void resize(size_type __n, const value_type& __v);
578 void clear() {base::clear();}
579
580#ifdef _LIBCPP_MOVE
581 void splice_after(const_iterator __p, forward_list&& __x);
582 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
583 void splice_after(const_iterator __p, forward_list&& __x,
584 const_iterator __f, const_iterator __l);
Howard Hinnant324bb032010-08-22 00:02:43 +0000585#else // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000586 void splice_after(const_iterator __p, forward_list& __x);
587 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
588 void splice_after(const_iterator __p, forward_list& __x,
589 const_iterator __f, const_iterator __l);
Howard Hinnant324bb032010-08-22 00:02:43 +0000590#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000591 void remove(const value_type& __v);
592 template <class _Predicate> void remove_if(_Predicate __pred);
593 void unique() {unique(__equal_to<value_type>());}
594 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
595#ifdef _LIBCPP_MOVE
596 void merge(forward_list&& __x) {merge(_STD::move(__x), __less<value_type>());}
597 template <class _Compare> void merge(forward_list&& __x, _Compare __comp);
Howard Hinnant324bb032010-08-22 00:02:43 +0000598#else // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000599 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
600 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
Howard Hinnant324bb032010-08-22 00:02:43 +0000601#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000602 void sort() {sort(__less<value_type>());}
603 template <class _Compare> void sort(_Compare __comp);
604 void reverse();
605
606private:
607 typedef typename base::__node_allocator __node_allocator;
608 typedef typename base::__node __node;
609 typedef typename base::__node_traits __node_traits;
610 typedef typename base::__node_pointer __node_pointer;
611
612#ifdef _LIBCPP_MOVE
613 void __move_assign(forward_list& __x, true_type);
614 void __move_assign(forward_list& __x, false_type);
Howard Hinnant324bb032010-08-22 00:02:43 +0000615#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000616
617 template <class _Compare>
618 static
619 __node_pointer
620 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
621
622 template <class _Compare>
623 static
624 __node_pointer
625 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
626};
627
628template <class _Tp, class _Alloc>
629inline
630forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
631 : base(__a)
632{
633}
634
635template <class _Tp, class _Alloc>
636forward_list<_Tp, _Alloc>::forward_list(size_type __n)
637{
638 if (__n > 0)
639 {
640 __node_allocator& __a = base::__alloc();
641 typedef __allocator_destructor<__node_allocator> _D;
642 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
643 for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
644 __p = __p->__next_)
645 {
646 __h.reset(__node_traits::allocate(__a, 1));
647 __node_traits::construct(__a, addressof(__h->__value_));
648 __h->__next_ = nullptr;
649 __p->__next_ = __h.release();
650 }
651 }
652}
653
654template <class _Tp, class _Alloc>
655forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
656{
657 insert_after(cbefore_begin(), __n, __v);
658}
659
660template <class _Tp, class _Alloc>
661forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
662 const allocator_type& __a)
663 : base(__a)
664{
665 insert_after(cbefore_begin(), __n, __v);
666}
667
668template <class _Tp, class _Alloc>
669template <class _InputIterator>
670forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
671 typename enable_if<
672 __is_input_iterator<_InputIterator>::value
673 >::type*)
674{
675 insert_after(cbefore_begin(), __f, __l);
676}
677
678template <class _Tp, class _Alloc>
679template <class _InputIterator>
680forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
681 const allocator_type& __a,
682 typename enable_if<
683 __is_input_iterator<_InputIterator>::value
684 >::type*)
685 : base(__a)
686{
687 insert_after(cbefore_begin(), __f, __l);
688}
689
690template <class _Tp, class _Alloc>
691forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
692 : base(allocator_type(
693 __node_traits::select_on_container_copy_construction(__x.__alloc())
694 )
695 )
696{
697 insert_after(cbefore_begin(), __x.begin(), __x.end());
698}
699
700template <class _Tp, class _Alloc>
701forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
702 const allocator_type& __a)
703 : base(__a)
704{
705 insert_after(cbefore_begin(), __x.begin(), __x.end());
706}
707
708#ifdef _LIBCPP_MOVE
709
710template <class _Tp, class _Alloc>
711forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
712 const allocator_type& __a)
713 : base(_STD::move(__x), __a)
714{
715 if (base::__alloc() != __x.__alloc())
716 {
717 typedef move_iterator<iterator> _I;
718 insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end()));
719 }
720}
721
Howard Hinnant324bb032010-08-22 00:02:43 +0000722#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723
724template <class _Tp, class _Alloc>
725forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
726{
727 insert_after(cbefore_begin(), __il.begin(), __il.end());
728}
729
730template <class _Tp, class _Alloc>
731forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
732 const allocator_type& __a)
733 : base(__a)
734{
735 insert_after(cbefore_begin(), __il.begin(), __il.end());
736}
737
738template <class _Tp, class _Alloc>
739forward_list<_Tp, _Alloc>&
740forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
741{
742 if (this != &__x)
743 {
744 base::__copy_assign_alloc(__x);
745 assign(__x.begin(), __x.end());
746 }
747 return *this;
748}
749
750#ifdef _LIBCPP_MOVE
751
752template <class _Tp, class _Alloc>
753void
754forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
755{
756 clear();
757 base::__move_assign_alloc(__x);
758 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
759 __x.__before_begin()->__next_ = nullptr;
760}
761
762template <class _Tp, class _Alloc>
763void
764forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
765{
766 if (base::__alloc() == __x.__alloc())
767 __move_assign(__x, true_type());
768 else
769 {
770 typedef move_iterator<iterator> _I;
771 assign(_I(__x.begin()), _I(__x.end()));
772 }
773}
774
775template <class _Tp, class _Alloc>
776inline
777forward_list<_Tp, _Alloc>&
778forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
779{
780 __move_assign(__x, integral_constant<bool,
781 __node_traits::propagate_on_container_move_assignment::value>());
782 return *this;
783}
784
Howard Hinnant324bb032010-08-22 00:02:43 +0000785#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000786
787template <class _Tp, class _Alloc>
788inline
789forward_list<_Tp, _Alloc>&
790forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
791{
792 assign(__il.begin(), __il.end());
793 return *this;
794}
795
796template <class _Tp, class _Alloc>
797template <class _InputIterator>
798typename enable_if
799<
800 __is_input_iterator<_InputIterator>::value,
801 void
802>::type
803forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
804{
805 iterator __i = before_begin();
806 iterator __j = next(__i);
807 iterator __e = end();
808 for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
809 *__j = *__f;
810 if (__j == __e)
811 insert_after(__i, __f, __l);
812 else
813 erase_after(__i, __e);
814}
815
816template <class _Tp, class _Alloc>
817void
818forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
819{
820 iterator __i = before_begin();
821 iterator __j = next(__i);
822 iterator __e = end();
823 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
824 *__j = __v;
825 if (__j == __e)
826 insert_after(__i, __n, __v);
827 else
828 erase_after(__i, __e);
829}
830
831template <class _Tp, class _Alloc>
832inline
833void
834forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
835{
836 assign(__il.begin(), __il.end());
837}
838
839#ifdef _LIBCPP_MOVE
840
841template <class _Tp, class _Alloc>
842template <class... _Args>
843void
844forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
845{
846 __node_allocator& __a = base::__alloc();
847 typedef __allocator_destructor<__node_allocator> _D;
848 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
849 __node_traits::construct(__a, addressof(__h->__value_),
850 _STD::forward<_Args>(__args)...);
851 __h->__next_ = base::__before_begin()->__next_;
852 base::__before_begin()->__next_ = __h.release();
853}
854
855template <class _Tp, class _Alloc>
856void
857forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
858{
859 __node_allocator& __a = base::__alloc();
860 typedef __allocator_destructor<__node_allocator> _D;
861 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
862 __node_traits::construct(__a, addressof(__h->__value_), _STD::move(__v));
863 __h->__next_ = base::__before_begin()->__next_;
864 base::__before_begin()->__next_ = __h.release();
865}
866
Howard Hinnant324bb032010-08-22 00:02:43 +0000867#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000868
869template <class _Tp, class _Alloc>
870void
871forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
872{
873 __node_allocator& __a = base::__alloc();
874 typedef __allocator_destructor<__node_allocator> _D;
875 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
876 __node_traits::construct(__a, addressof(__h->__value_), __v);
877 __h->__next_ = base::__before_begin()->__next_;
878 base::__before_begin()->__next_ = __h.release();
879}
880
881template <class _Tp, class _Alloc>
882void
883forward_list<_Tp, _Alloc>::pop_front()
884{
885 __node_allocator& __a = base::__alloc();
886 __node_pointer __p = base::__before_begin()->__next_;
887 base::__before_begin()->__next_ = __p->__next_;
888 __node_traits::destroy(__a, addressof(__p->__value_));
889 __node_traits::deallocate(__a, __p, 1);
890}
891
892#ifdef _LIBCPP_MOVE
893
894template <class _Tp, class _Alloc>
895template <class... _Args>
896typename forward_list<_Tp, _Alloc>::iterator
897forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
898{
899 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
900 __node_allocator& __a = base::__alloc();
901 typedef __allocator_destructor<__node_allocator> _D;
902 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
903 __node_traits::construct(__a, addressof(__h->__value_),
904 _STD::forward<_Args>(__args)...);
905 __h->__next_ = __r->__next_;
906 __r->__next_ = __h.release();
907 return iterator(__r->__next_);
908}
909
910template <class _Tp, class _Alloc>
911typename forward_list<_Tp, _Alloc>::iterator
912forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
913{
914 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
915 __node_allocator& __a = base::__alloc();
916 typedef __allocator_destructor<__node_allocator> _D;
917 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
918 __node_traits::construct(__a, addressof(__h->__value_), _STD::move(__v));
919 __h->__next_ = __r->__next_;
920 __r->__next_ = __h.release();
921 return iterator(__r->__next_);
922}
923
Howard Hinnant324bb032010-08-22 00:02:43 +0000924#endif // _LIBCPP_MOVE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000925
926template <class _Tp, class _Alloc>
927typename forward_list<_Tp, _Alloc>::iterator
928forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
929{
930 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
931 __node_allocator& __a = base::__alloc();
932 typedef __allocator_destructor<__node_allocator> _D;
933 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
934 __node_traits::construct(__a, addressof(__h->__value_), __v);
935 __h->__next_ = __r->__next_;
936 __r->__next_ = __h.release();
937 return iterator(__r->__next_);
938}
939
940template <class _Tp, class _Alloc>
941typename forward_list<_Tp, _Alloc>::iterator
942forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
943 const value_type& __v)
944{
Howard Hinnantba590bd2010-08-19 17:40:04 +0000945 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000946 if (__n > 0)
947 {
948 __node_allocator& __a = base::__alloc();
949 typedef __allocator_destructor<__node_allocator> _D;
950 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
951 __node_traits::construct(__a, addressof(__h->__value_), __v);
952 __node_pointer __first = __h.release();
953 __node_pointer __last = __first;
954#ifndef _LIBCPP_NO_EXCEPTIONS
955 try
956 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000957#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000958 for (--__n; __n != 0; --__n, __last = __last->__next_)
959 {
960 __h.reset(__node_traits::allocate(__a, 1));
961 __node_traits::construct(__a, addressof(__h->__value_), __v);
962 __last->__next_ = __h.release();
963 }
964#ifndef _LIBCPP_NO_EXCEPTIONS
965 }
966 catch (...)
967 {
968 while (__first != nullptr)
969 {
970 __node_pointer __next = __first->__next_;
971 __node_traits::destroy(__a, addressof(__first->__value_));
972 __node_traits::deallocate(__a, __first, 1);
973 __first = __next;
974 }
975 throw;
976 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000977#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000978 __last->__next_ = __r->__next_;
979 __r->__next_ = __first;
Howard Hinnantba590bd2010-08-19 17:40:04 +0000980 __r = __last;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000981 }
982 return iterator(__r);
983}
984
985template <class _Tp, class _Alloc>
986template <class _InputIterator>
987typename enable_if
988<
989 __is_input_iterator<_InputIterator>::value,
990 typename forward_list<_Tp, _Alloc>::iterator
991>::type
992forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
993 _InputIterator __f, _InputIterator __l)
994{
Howard Hinnantba590bd2010-08-19 17:40:04 +0000995 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000996 if (__f != __l)
997 {
998 __node_allocator& __a = base::__alloc();
999 typedef __allocator_destructor<__node_allocator> _D;
1000 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1001 __node_traits::construct(__a, addressof(__h->__value_), *__f);
1002 __node_pointer __first = __h.release();
1003 __node_pointer __last = __first;
1004#ifndef _LIBCPP_NO_EXCEPTIONS
1005 try
1006 {
Howard Hinnant324bb032010-08-22 00:02:43 +00001007#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001008 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1009 {
1010 __h.reset(__node_traits::allocate(__a, 1));
1011 __node_traits::construct(__a, addressof(__h->__value_), *__f);
1012 __last->__next_ = __h.release();
1013 }
1014#ifndef _LIBCPP_NO_EXCEPTIONS
1015 }
1016 catch (...)
1017 {
1018 while (__first != nullptr)
1019 {
1020 __node_pointer __next = __first->__next_;
1021 __node_traits::destroy(__a, addressof(__first->__value_));
1022 __node_traits::deallocate(__a, __first, 1);
1023 __first = __next;
1024 }
1025 throw;
1026 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001027#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001028 __last->__next_ = __r->__next_;
1029 __r->__next_ = __first;
Howard Hinnantba590bd2010-08-19 17:40:04 +00001030 __r = __last;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001031 }
1032 return iterator(__r);
1033}
1034
1035template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001036typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001037forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1038{
1039 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1040 __node_pointer __n = __p->__next_;
1041 __p->__next_ = __n->__next_;
1042 __node_allocator& __a = base::__alloc();
1043 __node_traits::destroy(__a, addressof(__n->__value_));
1044 __node_traits::deallocate(__a, __n, 1);
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001045 return iterator(__p->__next_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001046}
1047
1048template <class _Tp, class _Alloc>
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001049typename forward_list<_Tp, _Alloc>::iterator
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001050forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1051{
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001052 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001053 if (__f != __l)
1054 {
1055 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1056 __node_pointer __n = __p->__next_;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001057 if (__n != __e)
1058 {
1059 __p->__next_ = __e;
1060 __node_allocator& __a = base::__alloc();
1061 do
1062 {
1063 __p = __n->__next_;
1064 __node_traits::destroy(__a, addressof(__n->__value_));
1065 __node_traits::deallocate(__a, __n, 1);
1066 __n = __p;
1067 } while (__n != __e);
1068 }
1069 }
Howard Hinnant7a2523b2010-08-21 20:58:44 +00001070 return iterator(__e);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001071}
1072
1073template <class _Tp, class _Alloc>
1074void
1075forward_list<_Tp, _Alloc>::resize(size_type __n)
1076{
1077 size_type __sz = 0;
1078 iterator __p = before_begin();
1079 iterator __i = begin();
1080 iterator __e = end();
1081 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1082 ;
1083 if (__i != __e)
1084 erase_after(__p, __e);
1085 else
1086 {
1087 __n -= __sz;
1088 if (__n > 0)
1089 {
1090 __node_allocator& __a = base::__alloc();
1091 typedef __allocator_destructor<__node_allocator> _D;
1092 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1093 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1094 __ptr = __ptr->__next_)
1095 {
1096 __h.reset(__node_traits::allocate(__a, 1));
1097 __node_traits::construct(__a, addressof(__h->__value_));
1098 __h->__next_ = nullptr;
1099 __ptr->__next_ = __h.release();
1100 }
1101 }
1102 }
1103}
1104
1105template <class _Tp, class _Alloc>
1106void
1107forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1108{
1109 size_type __sz = 0;
1110 iterator __p = before_begin();
1111 iterator __i = begin();
1112 iterator __e = end();
1113 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1114 ;
1115 if (__i != __e)
1116 erase_after(__p, __e);
1117 else
1118 {
1119 __n -= __sz;
1120 if (__n > 0)
1121 {
1122 __node_allocator& __a = base::__alloc();
1123 typedef __allocator_destructor<__node_allocator> _D;
1124 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1125 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1126 __ptr = __ptr->__next_)
1127 {
1128 __h.reset(__node_traits::allocate(__a, 1));
1129 __node_traits::construct(__a, addressof(__h->__value_), __v);
1130 __h->__next_ = nullptr;
1131 __ptr->__next_ = __h.release();
1132 }
1133 }
1134 }
1135}
1136
1137template <class _Tp, class _Alloc>
1138void
1139forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1140#ifdef _LIBCPP_MOVE
1141 forward_list&& __x)
1142#else
1143 forward_list& __x)
1144#endif
1145{
1146 if (!__x.empty())
1147 {
1148 if (__p.__ptr_->__next_ != nullptr)
1149 {
1150 const_iterator __lm1 = __x.before_begin();
1151 while (__lm1.__ptr_->__next_ != nullptr)
1152 ++__lm1;
1153 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1154 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1155 }
1156 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1157 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1158 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1159 }
1160}
1161
1162template <class _Tp, class _Alloc>
1163void
1164forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1165#ifdef _LIBCPP_MOVE
1166 forward_list&& __x,
1167#else
1168 forward_list& __x,
1169#endif
1170 const_iterator __i)
1171{
1172 const_iterator __lm1 = next(__i);
1173 if (__p != __i && __p != __lm1)
1174 {
1175 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1176 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1177 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1178 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1179 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1180 const_cast<__node_pointer>(__lm1.__ptr_);
1181 }
1182}
1183
1184template <class _Tp, class _Alloc>
1185void
1186forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1187#ifdef _LIBCPP_MOVE
1188 forward_list&& __x,
1189#else
1190 forward_list& __x,
1191#endif
1192 const_iterator __f, const_iterator __l)
1193{
1194 if (__f != __l && __p != __f)
1195 {
1196 const_iterator __lm1 = __f;
1197 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1198 ++__lm1;
1199 if (__f != __lm1)
1200 {
1201 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1202 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1203 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1204 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1205 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1206 const_cast<__node_pointer>(__l.__ptr_);
1207 }
1208 }
1209}
1210
1211template <class _Tp, class _Alloc>
1212void
1213forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1214{
1215 iterator __e = end();
1216 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1217 {
1218 if (__i.__ptr_->__next_->__value_ == __v)
1219 {
1220 iterator __j = next(__i, 2);
1221 for (; __j != __e && *__j == __v; ++__j)
1222 ;
1223 erase_after(__i, __j);
1224 if (__j == __e)
1225 break;
1226 __i = __j;
1227 }
1228 else
1229 ++__i;
1230 }
1231}
1232
1233template <class _Tp, class _Alloc>
1234template <class _Predicate>
1235void
1236forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1237{
1238 iterator __e = end();
1239 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1240 {
1241 if (__pred(__i.__ptr_->__next_->__value_))
1242 {
1243 iterator __j = next(__i, 2);
1244 for (; __j != __e && __pred(*__j); ++__j)
1245 ;
1246 erase_after(__i, __j);
1247 if (__j == __e)
1248 break;
1249 __i = __j;
1250 }
1251 else
1252 ++__i;
1253 }
1254}
1255
1256template <class _Tp, class _Alloc>
1257template <class _BinaryPredicate>
1258void
1259forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1260{
1261 for (iterator __i = begin(), __e = end(); __i != __e;)
1262 {
1263 iterator __j = next(__i);
1264 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1265 ;
1266 if (__i.__ptr_->__next_ != __j.__ptr_)
1267 erase_after(__i, __j);
1268 __i = __j;
1269 }
1270}
1271
1272template <class _Tp, class _Alloc>
1273template <class _Compare>
1274void
1275#ifdef _LIBCPP_MOVE
1276forward_list<_Tp, _Alloc>::merge(forward_list&& __x, _Compare __comp)
1277#else
1278forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1279#endif
1280{
1281 if (this != &__x)
1282 {
1283 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1284 __x.__before_begin()->__next_,
1285 __comp);
1286 __x.__before_begin()->__next_ = nullptr;
1287 }
1288}
1289
1290template <class _Tp, class _Alloc>
1291template <class _Compare>
1292typename forward_list<_Tp, _Alloc>::__node_pointer
1293forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1294 _Compare& __comp)
1295{
1296 if (__f1 == nullptr)
1297 return __f2;
1298 if (__f2 == nullptr)
1299 return __f1;
1300 __node_pointer __r;
1301 if (__comp(__f2->__value_, __f1->__value_))
1302 {
1303 __node_pointer __t = __f2;
1304 while (__t->__next_ != nullptr &&
1305 __comp(__t->__next_->__value_, __f1->__value_))
1306 __t = __t->__next_;
1307 __r = __f2;
1308 __f2 = __t->__next_;
1309 __t->__next_ = __f1;
1310 }
1311 else
1312 __r = __f1;
1313 __node_pointer __p = __f1;
1314 __f1 = __f1->__next_;
1315 while (__f1 != nullptr && __f2 != nullptr)
1316 {
1317 if (__comp(__f2->__value_, __f1->__value_))
1318 {
1319 __node_pointer __t = __f2;
1320 while (__t->__next_ != nullptr &&
1321 __comp(__t->__next_->__value_, __f1->__value_))
1322 __t = __t->__next_;
1323 __p->__next_ = __f2;
1324 __f2 = __t->__next_;
1325 __t->__next_ = __f1;
1326 }
1327 __p = __f1;
1328 __f1 = __f1->__next_;
1329 }
1330 if (__f2 != nullptr)
1331 __p->__next_ = __f2;
1332 return __r;
1333}
1334
1335template <class _Tp, class _Alloc>
1336template <class _Compare>
1337inline
1338void
1339forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1340{
1341 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1342 _STD::distance(begin(), end()), __comp);
1343}
1344
1345template <class _Tp, class _Alloc>
1346template <class _Compare>
1347typename forward_list<_Tp, _Alloc>::__node_pointer
1348forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1349 _Compare& __comp)
1350{
1351 switch (__sz)
1352 {
1353 case 0:
1354 case 1:
1355 return __f1;
1356 case 2:
1357 if (__comp(__f1->__next_->__value_, __f1->__value_))
1358 {
1359 __node_pointer __t = __f1->__next_;
1360 __t->__next_ = __f1;
1361 __f1->__next_ = nullptr;
1362 __f1 = __t;
1363 }
1364 return __f1;
1365 }
1366 difference_type __sz1 = __sz / 2;
1367 difference_type __sz2 = __sz - __sz1;
1368 __node_pointer __t = next(iterator(__f1), __sz1 - 1).__ptr_;
1369 __node_pointer __f2 = __t->__next_;
1370 __t->__next_ = nullptr;
1371 return __merge(__sort(__f1, __sz1, __comp),
1372 __sort(__f2, __sz2, __comp), __comp);
1373}
1374
1375template <class _Tp, class _Alloc>
1376void
1377forward_list<_Tp, _Alloc>::reverse()
1378{
1379 __node_pointer __p = base::__before_begin()->__next_;
1380 if (__p != nullptr)
1381 {
1382 __node_pointer __f = __p->__next_;
1383 __p->__next_ = nullptr;
1384 while (__f != nullptr)
1385 {
1386 __node_pointer __t = __f->__next_;
1387 __f->__next_ = __p;
1388 __p = __f;
1389 __f = __t;
1390 }
1391 base::__before_begin()->__next_ = __p;
1392 }
1393}
1394
1395template <class _Tp, class _Alloc>
1396bool operator==(const forward_list<_Tp, _Alloc>& __x,
1397 const forward_list<_Tp, _Alloc>& __y)
1398{
1399 typedef forward_list<_Tp, _Alloc> _C;
1400 typedef typename _C::const_iterator _I;
1401 _I __ix = __x.begin();
1402 _I __ex = __x.end();
1403 _I __iy = __y.begin();
1404 _I __ey = __y.end();
1405 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1406 if (!(*__ix == *__iy))
1407 return false;
1408 return (__ix == __ex) == (__iy == __ey);
1409}
1410
1411template <class _Tp, class _Alloc>
1412inline
1413bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1414 const forward_list<_Tp, _Alloc>& __y)
1415{
1416 return !(__x == __y);
1417}
1418
1419template <class _Tp, class _Alloc>
1420inline
1421bool operator< (const forward_list<_Tp, _Alloc>& __x,
1422 const forward_list<_Tp, _Alloc>& __y)
1423{
1424 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1425 __y.begin(), __y.end());
1426}
1427
1428template <class _Tp, class _Alloc>
1429inline
1430bool operator> (const forward_list<_Tp, _Alloc>& __x,
1431 const forward_list<_Tp, _Alloc>& __y)
1432{
1433 return __y < __x;
1434}
1435
1436template <class _Tp, class _Alloc>
1437inline
1438bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1439 const forward_list<_Tp, _Alloc>& __y)
1440{
1441 return !(__x < __y);
1442}
1443
1444template <class _Tp, class _Alloc>
1445inline
1446bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1447 const forward_list<_Tp, _Alloc>& __y)
1448{
1449 return !(__y < __x);
1450}
1451
1452template <class _Tp, class _Alloc>
1453inline
1454void
1455swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1456{
1457 __x.swap(__y);
1458}
1459
1460_LIBCPP_END_NAMESPACE_STD
1461
1462#endif // _LIBCPP_FORWARD_LIST