blob: 44d381ab32be5241d7605098fc5d0413b991438e [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{
945 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
946 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;
980 }
981 return iterator(__r);
982}
983
984template <class _Tp, class _Alloc>
985template <class _InputIterator>
986typename enable_if
987<
988 __is_input_iterator<_InputIterator>::value,
989 typename forward_list<_Tp, _Alloc>::iterator
990>::type
991forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
992 _InputIterator __f, _InputIterator __l)
993{
994 __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
995 if (__f != __l)
996 {
997 __node_allocator& __a = base::__alloc();
998 typedef __allocator_destructor<__node_allocator> _D;
999 unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1));
1000 __node_traits::construct(__a, addressof(__h->__value_), *__f);
1001 __node_pointer __first = __h.release();
1002 __node_pointer __last = __first;
1003#ifndef _LIBCPP_NO_EXCEPTIONS
1004 try
1005 {
1006#endif
1007 for (++__f; __f != __l; ++__f, __last = __last->__next_)
1008 {
1009 __h.reset(__node_traits::allocate(__a, 1));
1010 __node_traits::construct(__a, addressof(__h->__value_), *__f);
1011 __last->__next_ = __h.release();
1012 }
1013#ifndef _LIBCPP_NO_EXCEPTIONS
1014 }
1015 catch (...)
1016 {
1017 while (__first != nullptr)
1018 {
1019 __node_pointer __next = __first->__next_;
1020 __node_traits::destroy(__a, addressof(__first->__value_));
1021 __node_traits::deallocate(__a, __first, 1);
1022 __first = __next;
1023 }
1024 throw;
1025 }
1026#endif
1027 __last->__next_ = __r->__next_;
1028 __r->__next_ = __first;
1029 }
1030 return iterator(__r);
1031}
1032
1033template <class _Tp, class _Alloc>
1034void
1035forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1036{
1037 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1038 __node_pointer __n = __p->__next_;
1039 __p->__next_ = __n->__next_;
1040 __node_allocator& __a = base::__alloc();
1041 __node_traits::destroy(__a, addressof(__n->__value_));
1042 __node_traits::deallocate(__a, __n, 1);
1043}
1044
1045template <class _Tp, class _Alloc>
1046void
1047forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1048{
1049 if (__f != __l)
1050 {
1051 __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
1052 __node_pointer __n = __p->__next_;
1053 __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
1054 if (__n != __e)
1055 {
1056 __p->__next_ = __e;
1057 __node_allocator& __a = base::__alloc();
1058 do
1059 {
1060 __p = __n->__next_;
1061 __node_traits::destroy(__a, addressof(__n->__value_));
1062 __node_traits::deallocate(__a, __n, 1);
1063 __n = __p;
1064 } while (__n != __e);
1065 }
1066 }
1067}
1068
1069template <class _Tp, class _Alloc>
1070void
1071forward_list<_Tp, _Alloc>::resize(size_type __n)
1072{
1073 size_type __sz = 0;
1074 iterator __p = before_begin();
1075 iterator __i = begin();
1076 iterator __e = end();
1077 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1078 ;
1079 if (__i != __e)
1080 erase_after(__p, __e);
1081 else
1082 {
1083 __n -= __sz;
1084 if (__n > 0)
1085 {
1086 __node_allocator& __a = base::__alloc();
1087 typedef __allocator_destructor<__node_allocator> _D;
1088 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1089 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1090 __ptr = __ptr->__next_)
1091 {
1092 __h.reset(__node_traits::allocate(__a, 1));
1093 __node_traits::construct(__a, addressof(__h->__value_));
1094 __h->__next_ = nullptr;
1095 __ptr->__next_ = __h.release();
1096 }
1097 }
1098 }
1099}
1100
1101template <class _Tp, class _Alloc>
1102void
1103forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1104{
1105 size_type __sz = 0;
1106 iterator __p = before_begin();
1107 iterator __i = begin();
1108 iterator __e = end();
1109 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1110 ;
1111 if (__i != __e)
1112 erase_after(__p, __e);
1113 else
1114 {
1115 __n -= __sz;
1116 if (__n > 0)
1117 {
1118 __node_allocator& __a = base::__alloc();
1119 typedef __allocator_destructor<__node_allocator> _D;
1120 unique_ptr<__node, _D> __h(nullptr, _D(__a, 1));
1121 for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
1122 __ptr = __ptr->__next_)
1123 {
1124 __h.reset(__node_traits::allocate(__a, 1));
1125 __node_traits::construct(__a, addressof(__h->__value_), __v);
1126 __h->__next_ = nullptr;
1127 __ptr->__next_ = __h.release();
1128 }
1129 }
1130 }
1131}
1132
1133template <class _Tp, class _Alloc>
1134void
1135forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1136#ifdef _LIBCPP_MOVE
1137 forward_list&& __x)
1138#else
1139 forward_list& __x)
1140#endif
1141{
1142 if (!__x.empty())
1143 {
1144 if (__p.__ptr_->__next_ != nullptr)
1145 {
1146 const_iterator __lm1 = __x.before_begin();
1147 while (__lm1.__ptr_->__next_ != nullptr)
1148 ++__lm1;
1149 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1150 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1151 }
1152 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1153 const_cast<__node_pointer>(__x.__before_begin())->__next_;
1154 const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
1155 }
1156}
1157
1158template <class _Tp, class _Alloc>
1159void
1160forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1161#ifdef _LIBCPP_MOVE
1162 forward_list&& __x,
1163#else
1164 forward_list& __x,
1165#endif
1166 const_iterator __i)
1167{
1168 const_iterator __lm1 = next(__i);
1169 if (__p != __i && __p != __lm1)
1170 {
1171 const_cast<__node_pointer>(__i.__ptr_)->__next_ =
1172 const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
1173 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1174 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1175 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1176 const_cast<__node_pointer>(__lm1.__ptr_);
1177 }
1178}
1179
1180template <class _Tp, class _Alloc>
1181void
1182forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1183#ifdef _LIBCPP_MOVE
1184 forward_list&& __x,
1185#else
1186 forward_list& __x,
1187#endif
1188 const_iterator __f, const_iterator __l)
1189{
1190 if (__f != __l && __p != __f)
1191 {
1192 const_iterator __lm1 = __f;
1193 while (__lm1.__ptr_->__next_ != __l.__ptr_)
1194 ++__lm1;
1195 if (__f != __lm1)
1196 {
1197 const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
1198 const_cast<__node_pointer>(__p.__ptr_)->__next_;
1199 const_cast<__node_pointer>(__p.__ptr_)->__next_ =
1200 const_cast<__node_pointer>(__f.__ptr_)->__next_;
1201 const_cast<__node_pointer>(__f.__ptr_)->__next_ =
1202 const_cast<__node_pointer>(__l.__ptr_);
1203 }
1204 }
1205}
1206
1207template <class _Tp, class _Alloc>
1208void
1209forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1210{
1211 iterator __e = end();
1212 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1213 {
1214 if (__i.__ptr_->__next_->__value_ == __v)
1215 {
1216 iterator __j = next(__i, 2);
1217 for (; __j != __e && *__j == __v; ++__j)
1218 ;
1219 erase_after(__i, __j);
1220 if (__j == __e)
1221 break;
1222 __i = __j;
1223 }
1224 else
1225 ++__i;
1226 }
1227}
1228
1229template <class _Tp, class _Alloc>
1230template <class _Predicate>
1231void
1232forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1233{
1234 iterator __e = end();
1235 for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
1236 {
1237 if (__pred(__i.__ptr_->__next_->__value_))
1238 {
1239 iterator __j = next(__i, 2);
1240 for (; __j != __e && __pred(*__j); ++__j)
1241 ;
1242 erase_after(__i, __j);
1243 if (__j == __e)
1244 break;
1245 __i = __j;
1246 }
1247 else
1248 ++__i;
1249 }
1250}
1251
1252template <class _Tp, class _Alloc>
1253template <class _BinaryPredicate>
1254void
1255forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1256{
1257 for (iterator __i = begin(), __e = end(); __i != __e;)
1258 {
1259 iterator __j = next(__i);
1260 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1261 ;
1262 if (__i.__ptr_->__next_ != __j.__ptr_)
1263 erase_after(__i, __j);
1264 __i = __j;
1265 }
1266}
1267
1268template <class _Tp, class _Alloc>
1269template <class _Compare>
1270void
1271#ifdef _LIBCPP_MOVE
1272forward_list<_Tp, _Alloc>::merge(forward_list&& __x, _Compare __comp)
1273#else
1274forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1275#endif
1276{
1277 if (this != &__x)
1278 {
1279 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1280 __x.__before_begin()->__next_,
1281 __comp);
1282 __x.__before_begin()->__next_ = nullptr;
1283 }
1284}
1285
1286template <class _Tp, class _Alloc>
1287template <class _Compare>
1288typename forward_list<_Tp, _Alloc>::__node_pointer
1289forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1290 _Compare& __comp)
1291{
1292 if (__f1 == nullptr)
1293 return __f2;
1294 if (__f2 == nullptr)
1295 return __f1;
1296 __node_pointer __r;
1297 if (__comp(__f2->__value_, __f1->__value_))
1298 {
1299 __node_pointer __t = __f2;
1300 while (__t->__next_ != nullptr &&
1301 __comp(__t->__next_->__value_, __f1->__value_))
1302 __t = __t->__next_;
1303 __r = __f2;
1304 __f2 = __t->__next_;
1305 __t->__next_ = __f1;
1306 }
1307 else
1308 __r = __f1;
1309 __node_pointer __p = __f1;
1310 __f1 = __f1->__next_;
1311 while (__f1 != nullptr && __f2 != nullptr)
1312 {
1313 if (__comp(__f2->__value_, __f1->__value_))
1314 {
1315 __node_pointer __t = __f2;
1316 while (__t->__next_ != nullptr &&
1317 __comp(__t->__next_->__value_, __f1->__value_))
1318 __t = __t->__next_;
1319 __p->__next_ = __f2;
1320 __f2 = __t->__next_;
1321 __t->__next_ = __f1;
1322 }
1323 __p = __f1;
1324 __f1 = __f1->__next_;
1325 }
1326 if (__f2 != nullptr)
1327 __p->__next_ = __f2;
1328 return __r;
1329}
1330
1331template <class _Tp, class _Alloc>
1332template <class _Compare>
1333inline
1334void
1335forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1336{
1337 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1338 _STD::distance(begin(), end()), __comp);
1339}
1340
1341template <class _Tp, class _Alloc>
1342template <class _Compare>
1343typename forward_list<_Tp, _Alloc>::__node_pointer
1344forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1345 _Compare& __comp)
1346{
1347 switch (__sz)
1348 {
1349 case 0:
1350 case 1:
1351 return __f1;
1352 case 2:
1353 if (__comp(__f1->__next_->__value_, __f1->__value_))
1354 {
1355 __node_pointer __t = __f1->__next_;
1356 __t->__next_ = __f1;
1357 __f1->__next_ = nullptr;
1358 __f1 = __t;
1359 }
1360 return __f1;
1361 }
1362 difference_type __sz1 = __sz / 2;
1363 difference_type __sz2 = __sz - __sz1;
1364 __node_pointer __t = next(iterator(__f1), __sz1 - 1).__ptr_;
1365 __node_pointer __f2 = __t->__next_;
1366 __t->__next_ = nullptr;
1367 return __merge(__sort(__f1, __sz1, __comp),
1368 __sort(__f2, __sz2, __comp), __comp);
1369}
1370
1371template <class _Tp, class _Alloc>
1372void
1373forward_list<_Tp, _Alloc>::reverse()
1374{
1375 __node_pointer __p = base::__before_begin()->__next_;
1376 if (__p != nullptr)
1377 {
1378 __node_pointer __f = __p->__next_;
1379 __p->__next_ = nullptr;
1380 while (__f != nullptr)
1381 {
1382 __node_pointer __t = __f->__next_;
1383 __f->__next_ = __p;
1384 __p = __f;
1385 __f = __t;
1386 }
1387 base::__before_begin()->__next_ = __p;
1388 }
1389}
1390
1391template <class _Tp, class _Alloc>
1392bool operator==(const forward_list<_Tp, _Alloc>& __x,
1393 const forward_list<_Tp, _Alloc>& __y)
1394{
1395 typedef forward_list<_Tp, _Alloc> _C;
1396 typedef typename _C::const_iterator _I;
1397 _I __ix = __x.begin();
1398 _I __ex = __x.end();
1399 _I __iy = __y.begin();
1400 _I __ey = __y.end();
1401 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1402 if (!(*__ix == *__iy))
1403 return false;
1404 return (__ix == __ex) == (__iy == __ey);
1405}
1406
1407template <class _Tp, class _Alloc>
1408inline
1409bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1410 const forward_list<_Tp, _Alloc>& __y)
1411{
1412 return !(__x == __y);
1413}
1414
1415template <class _Tp, class _Alloc>
1416inline
1417bool operator< (const forward_list<_Tp, _Alloc>& __x,
1418 const forward_list<_Tp, _Alloc>& __y)
1419{
1420 return _STD::lexicographical_compare(__x.begin(), __x.end(),
1421 __y.begin(), __y.end());
1422}
1423
1424template <class _Tp, class _Alloc>
1425inline
1426bool operator> (const forward_list<_Tp, _Alloc>& __x,
1427 const forward_list<_Tp, _Alloc>& __y)
1428{
1429 return __y < __x;
1430}
1431
1432template <class _Tp, class _Alloc>
1433inline
1434bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1435 const forward_list<_Tp, _Alloc>& __y)
1436{
1437 return !(__x < __y);
1438}
1439
1440template <class _Tp, class _Alloc>
1441inline
1442bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1443 const forward_list<_Tp, _Alloc>& __y)
1444{
1445 return !(__y < __x);
1446}
1447
1448template <class _Tp, class _Alloc>
1449inline
1450void
1451swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1452{
1453 __x.swap(__y);
1454}
1455
1456_LIBCPP_END_NAMESPACE_STD
1457
1458#endif // _LIBCPP_FORWARD_LIST