blob: 038d85d7b5ea4c80e5f06e6e589f945cc4056690 [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------- forward_list ---------------------------------===//
3//
Howard Hinnant5b08a8a2010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:16 +00005//
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
100 void erase_after(const_iterator p);
101 void erase_after(const_iterator first, const_iterator last);
102
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;
217 typedef typename pointer_traits<__node_pointer>::difference_type
218 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;
280 typedef typename pointer_traits<__node_const_pointer>::difference_type
281 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);
361#endif
362
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
431#endif
432
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);
504#endif
505 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);
549#endif
550 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);
558#endif
559 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
571 void erase_after(const_iterator __p);
572 void erase_after(const_iterator __f, const_iterator __l);
573
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);
585#else
586 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);
590#endif
591 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);
598#else
599 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
600 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
601#endif
602 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);
615#endif
616
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
722#endif
723
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
785#endif
786
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
867#endif
868
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
924#endif
925
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 Hinnante57dc142010-08-19 17:40:04 +0000945 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-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 {
957#endif
958 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 }
977#endif
978 __last->__next_ = __r->__next_;
979 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +0000980 __r = __last;
Howard Hinnant3e519522010-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 Hinnante57dc142010-08-19 17:40:04 +0000995 __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
Howard Hinnant3e519522010-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 {
1007#endif
1008 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 }
1027#endif
1028 __last->__next_ = __r->__next_;
1029 __r->__next_ = __first;
Howard Hinnante57dc142010-08-19 17:40:04 +00001030 __r = __last;
Howard Hinnant3e519522010-05-11 19:42:16 +00001031 }
1032 return iterator(__r);
1033}
1034
1035template <class _Tp, class _Alloc>
1036void
1037forward_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);
1045}
1046
1047template <class _Tp, class _Alloc>
1048void
1049forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1050{
1051 if (__f != __l)
1052 {
1053 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1054 __node_pointer __n = __p->__next_;
1055 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
1056 if (__n != __e)
1057 {
1058 __p->__next_ = __e;
1059 __node_allocator& __a = base::__alloc();
1060 do
1061 {
1062 __p = __n->__next_;
1063 __node_traits::destroy(__a, addressof(__n->__value_));
1064 __node_traits::deallocate(__a, __n, 1);
1065 __n = __p;
1066 } while (__n != __e);
1067 }
1068 }
1069}
1070
1071template <class _Tp, class _Alloc>
1072void
1073forward_list<_Tp, _Alloc>::resize(size_type __n)
1074{
1075 size_type __sz = 0;
1076 iterator __p = before_begin();
1077 iterator __i = begin();
1078 iterator __e = end();
1079 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1080 ;
1081 if (__i != __e)
1082 erase_after(__p, __e);
1083 else
1084 {
1085 __n -= __sz;
1086 if (__n > 0)
1087 {
1088 __node_allocator& __a = base::__alloc();
1089 typedef __allocator_destructor<__node_allocator> _D;
1090 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1091 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1092 __ptr = __ptr->__next_)
1093 {
1094 __h.reset(__node_traits::allocate(__a, 1));
1095 __node_traits::construct(__a, addressof(__h->__value_));
1096 __h->__next_ = nullptr;
1097 __ptr->__next_ = __h.release();
1098 }
1099 }
1100 }
1101}
1102
1103template <class _Tp, class _Alloc>
1104void
1105forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1106{
1107 size_type __sz = 0;
1108 iterator __p = before_begin();
1109 iterator __i = begin();
1110 iterator __e = end();
1111 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1112 ;
1113 if (__i != __e)
1114 erase_after(__p, __e);
1115 else
1116 {
1117 __n -= __sz;
1118 if (__n > 0)
1119 {
1120 __node_allocator& __a = base::__alloc();
1121 typedef __allocator_destructor<__node_allocator> _D;
1122 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1123 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1124 __ptr = __ptr->__next_)
1125 {
1126 __h.reset(__node_traits::allocate(__a, 1));
1127 __node_traits::construct(__a, addressof(__h->__value_), __v);
1128 __h->__next_ = nullptr;
1129 __ptr->__next_ = __h.release();
1130 }
1131 }
1132 }
1133}
1134
1135template <class _Tp, class _Alloc>
1136void
1137forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1138#ifdef _LIBCPP_MOVE
1139 forward_list&& __x)
1140#else
1141 forward_list& __x)
1142#endif
1143{
1144 if (!__x.empty())
1145 {
1146 if (__p.__ptr_->__next_ != nullptr)
1147 {
1148 const_iterator __lm1 = __x.before_begin();
1149 while (__lm1.__ptr_->__next_ != nullptr)
1150 ++__lm1;
1151 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1152 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1153 }
1154 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1155 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1156 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1157 }
1158}
1159
1160template <class _Tp, class _Alloc>
1161void
1162forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1163#ifdef _LIBCPP_MOVE
1164 forward_list&& __x,
1165#else
1166 forward_list& __x,
1167#endif
1168 const_iterator __i)
1169{
1170 const_iterator __lm1 = next(__i);
1171 if (__p != __i && __p != __lm1)
1172 {
1173 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1174 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1175 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1176 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1177 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1178 const_cast<__node_pointer>(__lm1.__ptr_);
1179 }
1180}
1181
1182template <class _Tp, class _Alloc>
1183void
1184forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1185#ifdef _LIBCPP_MOVE
1186 forward_list&& __x,
1187#else
1188 forward_list& __x,
1189#endif
1190 const_iterator __f, const_iterator __l)
1191{
1192 if (__f != __l && __p != __f)
1193 {
1194 const_iterator __lm1 = __f;
1195 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1196 ++__lm1;
1197 if (__f != __lm1)
1198 {
1199 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1200 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1201 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1202 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1203 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1204 const_cast<__node_pointer>(__l.__ptr_);
1205 }
1206 }
1207}
1208
1209template <class _Tp, class _Alloc>
1210void
1211forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1212{
1213 iterator __e = end();
1214 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1215 {
1216 if (__i.__ptr_->__next_->__value_ == __v)
1217 {
1218 iterator __j = next(__i, 2);
1219 for (; __j != __e && *__j == __v; ++__j)
1220 ;
1221 erase_after(__i, __j);
1222 if (__j == __e)
1223 break;
1224 __i = __j;
1225 }
1226 else
1227 ++__i;
1228 }
1229}
1230
1231template <class _Tp, class _Alloc>
1232template <class _Predicate>
1233void
1234forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1235{
1236 iterator __e = end();
1237 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1238 {
1239 if (__pred(__i.__ptr_->__next_->__value_))
1240 {
1241 iterator __j = next(__i, 2);
1242 for (; __j != __e && __pred(*__j); ++__j)
1243 ;
1244 erase_after(__i, __j);
1245 if (__j == __e)
1246 break;
1247 __i = __j;
1248 }
1249 else
1250 ++__i;
1251 }
1252}
1253
1254template <class _Tp, class _Alloc>
1255template <class _BinaryPredicate>
1256void
1257forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1258{
1259 for (iterator __i = begin(), __e = end(); __i != __e;)
1260 {
1261 iterator __j = next(__i);
1262 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1263 ;
1264 if (__i.__ptr_->__next_ != __j.__ptr_)
1265 erase_after(__i, __j);
1266 __i = __j;
1267 }
1268}
1269
1270template <class _Tp, class _Alloc>
1271template <class _Compare>
1272void
1273#ifdef _LIBCPP_MOVE
1274forward_list<_Tp, _Alloc>::merge(forward_list&& __x, _Compare __comp)
1275#else
1276forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1277#endif
1278{
1279 if (this != &__x)
1280 {
1281 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1282 __x.__before_begin()->__next_,
1283 __comp);
1284 __x.__before_begin()->__next_ = nullptr;
1285 }
1286}
1287
1288template <class _Tp, class _Alloc>
1289template <class _Compare>
1290typename forward_list<_Tp, _Alloc>::__node_pointer
1291forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1292 _Compare& __comp)
1293{
1294 if (__f1 == nullptr)
1295 return __f2;
1296 if (__f2 == nullptr)
1297 return __f1;
1298 __node_pointer __r;
1299 if (__comp(__f2->__value_, __f1->__value_))
1300 {
1301 __node_pointer __t = __f2;
1302 while (__t->__next_ != nullptr &&
1303 __comp(__t->__next_->__value_, __f1->__value_))
1304 __t = __t->__next_;
1305 __r = __f2;
1306 __f2 = __t->__next_;
1307 __t->__next_ = __f1;
1308 }
1309 else
1310 __r = __f1;
1311 __node_pointer __p = __f1;
1312 __f1 = __f1->__next_;
1313 while (__f1 != nullptr && __f2 != nullptr)
1314 {
1315 if (__comp(__f2->__value_, __f1->__value_))
1316 {
1317 __node_pointer __t = __f2;
1318 while (__t->__next_ != nullptr &&
1319 __comp(__t->__next_->__value_, __f1->__value_))
1320 __t = __t->__next_;
1321 __p->__next_ = __f2;
1322 __f2 = __t->__next_;
1323 __t->__next_ = __f1;
1324 }
1325 __p = __f1;
1326 __f1 = __f1->__next_;
1327 }
1328 if (__f2 != nullptr)
1329 __p->__next_ = __f2;
1330 return __r;
1331}
1332
1333template <class _Tp, class _Alloc>
1334template <class _Compare>
1335inline
1336void
1337forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1338{
1339 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1340 _STD::distance(begin(), end()), __comp);
1341}
1342
1343template <class _Tp, class _Alloc>
1344template <class _Compare>
1345typename forward_list<_Tp, _Alloc>::__node_pointer
1346forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1347 _Compare& __comp)
1348{
1349 switch (__sz)
1350 {
1351 case 0:
1352 case 1:
1353 return __f1;
1354 case 2:
1355 if (__comp(__f1->__next_->__value_, __f1->__value_))
1356 {
1357 __node_pointer __t = __f1->__next_;
1358 __t->__next_ = __f1;
1359 __f1->__next_ = nullptr;
1360 __f1 = __t;
1361 }
1362 return __f1;
1363 }
1364 difference_type __sz1 = __sz / 2;
1365 difference_type __sz2 = __sz - __sz1;
1366 __node_pointer __t = next(iterator(__f1), __sz1 - 1).__ptr_;
1367 __node_pointer __f2 = __t->__next_;
1368 __t->__next_ = nullptr;
1369 return __merge(__sort(__f1, __sz1, __comp),
1370 __sort(__f2, __sz2, __comp), __comp);
1371}
1372
1373template <class _Tp, class _Alloc>
1374void
1375forward_list<_Tp, _Alloc>::reverse()
1376{
1377 __node_pointer __p = base::__before_begin()->__next_;
1378 if (__p != nullptr)
1379 {
1380 __node_pointer __f = __p->__next_;
1381 __p->__next_ = nullptr;
1382 while (__f != nullptr)
1383 {
1384 __node_pointer __t = __f->__next_;
1385 __f->__next_ = __p;
1386 __p = __f;
1387 __f = __t;
1388 }
1389 base::__before_begin()->__next_ = __p;
1390 }
1391}
1392
1393template <class _Tp, class _Alloc>
1394bool operator==(const forward_list<_Tp, _Alloc>& __x,
1395 const forward_list<_Tp, _Alloc>& __y)
1396{
1397 typedef forward_list<_Tp, _Alloc> _C;
1398 typedef typename _C::const_iterator _I;
1399 _I __ix = __x.begin();
1400 _I __ex = __x.end();
1401 _I __iy = __y.begin();
1402 _I __ey = __y.end();
1403 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1404 if (!(*__ix == *__iy))
1405 return false;
1406 return (__ix == __ex) == (__iy == __ey);
1407}
1408
1409template <class _Tp, class _Alloc>
1410inline
1411bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1412 const forward_list<_Tp, _Alloc>& __y)
1413{
1414 return !(__x == __y);
1415}
1416
1417template <class _Tp, class _Alloc>
1418inline
1419bool operator< (const forward_list<_Tp, _Alloc>& __x,
1420 const forward_list<_Tp, _Alloc>& __y)
1421{
1422 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1423 __y.begin(), __y.end());
1424}
1425
1426template <class _Tp, class _Alloc>
1427inline
1428bool operator> (const forward_list<_Tp, _Alloc>& __x,
1429 const forward_list<_Tp, _Alloc>& __y)
1430{
1431 return __y < __x;
1432}
1433
1434template <class _Tp, class _Alloc>
1435inline
1436bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1437 const forward_list<_Tp, _Alloc>& __y)
1438{
1439 return !(__x < __y);
1440}
1441
1442template <class _Tp, class _Alloc>
1443inline
1444bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1445 const forward_list<_Tp, _Alloc>& __y)
1446{
1447 return !(__y < __x);
1448}
1449
1450template <class _Tp, class _Alloc>
1451inline
1452void
1453swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1454{
1455 __x.swap(__y);
1456}
1457
1458_LIBCPP_END_NAMESPACE_STD
1459
1460#endif // _LIBCPP_FORWARD_LIST