2 //===----------------------- forward_list ---------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_FORWARD_LIST
12 #define _LIBCPP_FORWARD_LIST
20 template <class T, class Allocator = allocator<T>>
25 typedef Allocator allocator_type;
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;
34 typedef <details> iterator;
35 typedef <details> const_iterator;
38 noexcept(is_nothrow_default_constructible<allocator_type>::value);
39 explicit forward_list(const allocator_type& a);
40 explicit forward_list(size_type n);
41 explicit forward_list(size_type n, const allocator_type& a); // C++14
42 forward_list(size_type n, const value_type& v);
43 forward_list(size_type n, const value_type& v, const allocator_type& a);
44 template <class InputIterator>
45 forward_list(InputIterator first, InputIterator last);
46 template <class InputIterator>
47 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
48 forward_list(const forward_list& x);
49 forward_list(const forward_list& x, const allocator_type& a);
50 forward_list(forward_list&& x)
51 noexcept(is_nothrow_move_constructible<allocator_type>::value);
52 forward_list(forward_list&& x, const allocator_type& a);
53 forward_list(initializer_list<value_type> il);
54 forward_list(initializer_list<value_type> il, const allocator_type& a);
58 forward_list& operator=(const forward_list& x);
59 forward_list& operator=(forward_list&& x)
61 allocator_type::propagate_on_container_move_assignment::value &&
62 is_nothrow_move_assignable<allocator_type>::value);
63 forward_list& operator=(initializer_list<value_type> il);
65 template <class InputIterator>
66 void assign(InputIterator first, InputIterator last);
67 void assign(size_type n, const value_type& v);
68 void assign(initializer_list<value_type> il);
70 allocator_type get_allocator() const noexcept;
72 iterator begin() noexcept;
73 const_iterator begin() const noexcept;
74 iterator end() noexcept;
75 const_iterator end() const noexcept;
77 const_iterator cbegin() const noexcept;
78 const_iterator cend() const noexcept;
80 iterator before_begin() noexcept;
81 const_iterator before_begin() const noexcept;
82 const_iterator cbefore_begin() const noexcept;
84 bool empty() const noexcept;
85 size_type max_size() const noexcept;
88 const_reference front() const;
90 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
91 void push_front(const value_type& v);
92 void push_front(value_type&& v);
96 template <class... Args>
97 iterator emplace_after(const_iterator p, Args&&... args);
98 iterator insert_after(const_iterator p, const value_type& v);
99 iterator insert_after(const_iterator p, value_type&& v);
100 iterator insert_after(const_iterator p, size_type n, const value_type& v);
101 template <class InputIterator>
102 iterator insert_after(const_iterator p,
103 InputIterator first, InputIterator last);
104 iterator insert_after(const_iterator p, initializer_list<value_type> il);
106 iterator erase_after(const_iterator p);
107 iterator erase_after(const_iterator first, const_iterator last);
109 void swap(forward_list& x)
110 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
112 void resize(size_type n);
113 void resize(size_type n, const value_type& v);
114 void clear() noexcept;
116 void splice_after(const_iterator p, forward_list& x);
117 void splice_after(const_iterator p, forward_list&& x);
118 void splice_after(const_iterator p, forward_list& x, const_iterator i);
119 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
120 void splice_after(const_iterator p, forward_list& x,
121 const_iterator first, const_iterator last);
122 void splice_after(const_iterator p, forward_list&& x,
123 const_iterator first, const_iterator last);
124 void remove(const value_type& v);
125 template <class Predicate> void remove_if(Predicate pred);
127 template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
128 void merge(forward_list& x);
129 void merge(forward_list&& x);
130 template <class Compare> void merge(forward_list& x, Compare comp);
131 template <class Compare> void merge(forward_list&& x, Compare comp);
133 template <class Compare> void sort(Compare comp);
134 void reverse() noexcept;
138 template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
139 forward_list(InputIterator, InputIterator, Allocator = Allocator())
140 -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
142 template <class T, class Allocator>
143 bool operator==(const forward_list<T, Allocator>& x,
144 const forward_list<T, Allocator>& y);
146 template <class T, class Allocator>
147 bool operator< (const forward_list<T, Allocator>& x,
148 const forward_list<T, Allocator>& y);
150 template <class T, class Allocator>
151 bool operator!=(const forward_list<T, Allocator>& x,
152 const forward_list<T, Allocator>& y);
154 template <class T, class Allocator>
155 bool operator> (const forward_list<T, Allocator>& x,
156 const forward_list<T, Allocator>& y);
158 template <class T, class Allocator>
159 bool operator>=(const forward_list<T, Allocator>& x,
160 const forward_list<T, Allocator>& y);
162 template <class T, class Allocator>
163 bool operator<=(const forward_list<T, Allocator>& x,
164 const forward_list<T, Allocator>& y);
166 template <class T, class Allocator>
167 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
168 noexcept(noexcept(x.swap(y)));
170 template <class T, class Allocator, class U>
171 void erase(forward_list<T, Allocator>& c, const U& value); // C++20
172 template <class T, class Allocator, class Predicate>
173 void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
180 #include <initializer_list>
187 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
188 #pragma GCC system_header
192 #include <__undef_macros>
195 _LIBCPP_BEGIN_NAMESPACE_STD
197 template <class _Tp, class _VoidPtr> struct __forward_list_node;
198 template <class _NodePtr> struct __forward_begin_node;
202 struct __forward_list_node_value_type;
204 template <class _Tp, class _VoidPtr>
205 struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
209 template <class _NodePtr>
210 struct __forward_node_traits {
212 typedef typename remove_cv<
213 typename pointer_traits<_NodePtr>::element_type>::type __node;
214 typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
215 typedef _NodePtr __node_pointer;
216 typedef __forward_begin_node<_NodePtr> __begin_node;
217 typedef typename __rebind_pointer<_NodePtr, __begin_node>::type
218 __begin_node_pointer;
219 typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer;
221 #if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
222 typedef __begin_node_pointer __iter_node_pointer;
224 typedef typename conditional<
225 is_pointer<__void_pointer>::value,
226 __begin_node_pointer,
228 >::type __iter_node_pointer;
231 typedef typename conditional<
232 is_same<__iter_node_pointer, __node_pointer>::value,
233 __begin_node_pointer,
235 >::type __non_iter_node_pointer;
237 _LIBCPP_INLINE_VISIBILITY
238 static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) {
241 _LIBCPP_INLINE_VISIBILITY
242 static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
243 return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
247 template <class _NodePtr>
248 struct __forward_begin_node
250 typedef _NodePtr pointer;
251 typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
255 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
257 _LIBCPP_INLINE_VISIBILITY
258 __begin_node_pointer __next_as_begin() const {
259 return static_cast<__begin_node_pointer>(__next_);
263 template <class _Tp, class _VoidPtr>
264 struct _LIBCPP_HIDDEN __begin_node_of
266 typedef __forward_begin_node<
267 typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
271 template <class _Tp, class _VoidPtr>
272 struct __forward_list_node
273 : public __begin_node_of<_Tp, _VoidPtr>::type
275 typedef _Tp value_type;
281 template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list;
282 template<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
284 template <class _NodePtr>
285 class _LIBCPP_TEMPLATE_VIS __forward_list_iterator
287 typedef __forward_node_traits<_NodePtr> __traits;
288 typedef typename __traits::__node_pointer __node_pointer;
289 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
290 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
291 typedef typename __traits::__void_pointer __void_pointer;
293 __iter_node_pointer __ptr_;
295 _LIBCPP_INLINE_VISIBILITY
296 __begin_node_pointer __get_begin() const {
297 return static_cast<__begin_node_pointer>(
298 static_cast<__void_pointer>(__ptr_));
300 _LIBCPP_INLINE_VISIBILITY
301 __node_pointer __get_unsafe_node_pointer() const {
302 return static_cast<__node_pointer>(
303 static_cast<__void_pointer>(__ptr_));
306 _LIBCPP_INLINE_VISIBILITY
307 explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
309 _LIBCPP_INLINE_VISIBILITY
310 explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
311 : __ptr_(__traits::__as_iter_node(__p)) {}
313 _LIBCPP_INLINE_VISIBILITY
314 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
315 : __ptr_(__traits::__as_iter_node(__p)) {}
317 template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list;
318 template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
321 typedef forward_iterator_tag iterator_category;
322 typedef typename __traits::__node_value_type value_type;
323 typedef value_type& reference;
324 typedef typename pointer_traits<__node_pointer>::difference_type
326 typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
328 _LIBCPP_INLINE_VISIBILITY
329 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
331 _LIBCPP_INLINE_VISIBILITY
332 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
333 _LIBCPP_INLINE_VISIBILITY
334 pointer operator->() const {
335 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
338 _LIBCPP_INLINE_VISIBILITY
339 __forward_list_iterator& operator++()
341 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
344 _LIBCPP_INLINE_VISIBILITY
345 __forward_list_iterator operator++(int)
347 __forward_list_iterator __t(*this);
352 friend _LIBCPP_INLINE_VISIBILITY
353 bool operator==(const __forward_list_iterator& __x,
354 const __forward_list_iterator& __y)
355 {return __x.__ptr_ == __y.__ptr_;}
356 friend _LIBCPP_INLINE_VISIBILITY
357 bool operator!=(const __forward_list_iterator& __x,
358 const __forward_list_iterator& __y)
359 {return !(__x == __y);}
362 template <class _NodeConstPtr>
363 class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
365 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
366 typedef _NodeConstPtr _NodePtr;
368 typedef __forward_node_traits<_NodePtr> __traits;
369 typedef typename __traits::__node __node;
370 typedef typename __traits::__node_pointer __node_pointer;
371 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
372 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
373 typedef typename __traits::__void_pointer __void_pointer;
375 __iter_node_pointer __ptr_;
377 __begin_node_pointer __get_begin() const {
378 return static_cast<__begin_node_pointer>(
379 static_cast<__void_pointer>(__ptr_));
381 __node_pointer __get_unsafe_node_pointer() const {
382 return static_cast<__node_pointer>(
383 static_cast<__void_pointer>(__ptr_));
386 _LIBCPP_INLINE_VISIBILITY
387 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
390 _LIBCPP_INLINE_VISIBILITY
391 explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
392 : __ptr_(__traits::__as_iter_node(__p)) {}
394 _LIBCPP_INLINE_VISIBILITY
395 explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
396 : __ptr_(__traits::__as_iter_node(__p)) {}
399 template<class, class> friend class forward_list;
402 typedef forward_iterator_tag iterator_category;
403 typedef typename __traits::__node_value_type value_type;
404 typedef const value_type& reference;
405 typedef typename pointer_traits<__node_pointer>::difference_type
407 typedef typename __rebind_pointer<__node_pointer, const value_type>::type
410 _LIBCPP_INLINE_VISIBILITY
411 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
412 _LIBCPP_INLINE_VISIBILITY
413 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
414 : __ptr_(__p.__ptr_) {}
416 _LIBCPP_INLINE_VISIBILITY
417 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
418 _LIBCPP_INLINE_VISIBILITY
419 pointer operator->() const {return pointer_traits<pointer>::pointer_to(
420 __get_unsafe_node_pointer()->__value_);}
422 _LIBCPP_INLINE_VISIBILITY
423 __forward_list_const_iterator& operator++()
425 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
428 _LIBCPP_INLINE_VISIBILITY
429 __forward_list_const_iterator operator++(int)
431 __forward_list_const_iterator __t(*this);
436 friend _LIBCPP_INLINE_VISIBILITY
437 bool operator==(const __forward_list_const_iterator& __x,
438 const __forward_list_const_iterator& __y)
439 {return __x.__ptr_ == __y.__ptr_;}
440 friend _LIBCPP_INLINE_VISIBILITY
441 bool operator!=(const __forward_list_const_iterator& __x,
442 const __forward_list_const_iterator& __y)
443 {return !(__x == __y);}
446 template <class _Tp, class _Alloc>
447 class __forward_list_base
450 typedef _Tp value_type;
451 typedef _Alloc allocator_type;
453 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
454 typedef __forward_list_node<value_type, void_pointer> __node;
455 typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
456 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
457 typedef allocator_traits<__node_allocator> __node_traits;
458 typedef typename __node_traits::pointer __node_pointer;
460 typedef typename __rebind_alloc_helper<
461 allocator_traits<allocator_type>, __begin_node
462 >::type __begin_node_allocator;
463 typedef typename allocator_traits<__begin_node_allocator>::pointer
464 __begin_node_pointer;
466 static_assert((!is_same<allocator_type, __node_allocator>::value),
467 "internal allocator type must differ from user-specified "
468 "type; otherwise overload resolution breaks");
470 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
472 _LIBCPP_INLINE_VISIBILITY
473 __begin_node_pointer __before_begin() _NOEXCEPT
474 {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());}
475 _LIBCPP_INLINE_VISIBILITY
476 __begin_node_pointer __before_begin() const _NOEXCEPT
477 {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));}
479 _LIBCPP_INLINE_VISIBILITY
480 __node_allocator& __alloc() _NOEXCEPT
481 {return __before_begin_.second();}
482 _LIBCPP_INLINE_VISIBILITY
483 const __node_allocator& __alloc() const _NOEXCEPT
484 {return __before_begin_.second();}
486 typedef __forward_list_iterator<__node_pointer> iterator;
487 typedef __forward_list_const_iterator<__node_pointer> const_iterator;
489 _LIBCPP_INLINE_VISIBILITY
490 __forward_list_base()
491 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
492 : __before_begin_(__begin_node()) {}
493 _LIBCPP_INLINE_VISIBILITY
494 explicit __forward_list_base(const allocator_type& __a)
495 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
496 _LIBCPP_INLINE_VISIBILITY
497 explicit __forward_list_base(const __node_allocator& __a)
498 : __before_begin_(__begin_node(), __a) {}
499 #ifndef _LIBCPP_CXX03_LANG
501 _LIBCPP_INLINE_VISIBILITY
502 __forward_list_base(__forward_list_base&& __x)
503 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
504 _LIBCPP_INLINE_VISIBILITY
505 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
506 #endif // _LIBCPP_CXX03_LANG
509 __forward_list_base(const __forward_list_base&);
510 __forward_list_base& operator=(const __forward_list_base&);
513 ~__forward_list_base();
516 _LIBCPP_INLINE_VISIBILITY
517 void __copy_assign_alloc(const __forward_list_base& __x)
518 {__copy_assign_alloc(__x, integral_constant<bool,
519 __node_traits::propagate_on_container_copy_assignment::value>());}
521 _LIBCPP_INLINE_VISIBILITY
522 void __move_assign_alloc(__forward_list_base& __x)
523 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
524 is_nothrow_move_assignable<__node_allocator>::value)
525 {__move_assign_alloc(__x, integral_constant<bool,
526 __node_traits::propagate_on_container_move_assignment::value>());}
529 _LIBCPP_INLINE_VISIBILITY
530 void swap(__forward_list_base& __x)
531 #if _LIBCPP_STD_VER >= 14
534 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
535 __is_nothrow_swappable<__node_allocator>::value);
538 void clear() _NOEXCEPT;
541 _LIBCPP_INLINE_VISIBILITY
542 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
543 _LIBCPP_INLINE_VISIBILITY
544 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
546 if (__alloc() != __x.__alloc())
548 __alloc() = __x.__alloc();
551 _LIBCPP_INLINE_VISIBILITY
552 void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT
554 _LIBCPP_INLINE_VISIBILITY
555 void __move_assign_alloc(__forward_list_base& __x, true_type)
556 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
557 {__alloc() = _VSTD::move(__x.__alloc());}
560 #ifndef _LIBCPP_CXX03_LANG
562 template <class _Tp, class _Alloc>
564 __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
565 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
566 : __before_begin_(_VSTD::move(__x.__before_begin_))
568 __x.__before_begin()->__next_ = nullptr;
571 template <class _Tp, class _Alloc>
573 __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
574 const allocator_type& __a)
575 : __before_begin_(__begin_node(), __node_allocator(__a))
577 if (__alloc() == __x.__alloc())
579 __before_begin()->__next_ = __x.__before_begin()->__next_;
580 __x.__before_begin()->__next_ = nullptr;
584 #endif // _LIBCPP_CXX03_LANG
586 template <class _Tp, class _Alloc>
587 __forward_list_base<_Tp, _Alloc>::~__forward_list_base()
592 template <class _Tp, class _Alloc>
595 __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
596 #if _LIBCPP_STD_VER >= 14
599 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
600 __is_nothrow_swappable<__node_allocator>::value)
603 __swap_allocator(__alloc(), __x.__alloc(),
604 integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
606 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
609 template <class _Tp, class _Alloc>
611 __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
613 __node_allocator& __a = __alloc();
614 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
616 __node_pointer __next = __p->__next_;
617 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
618 __node_traits::deallocate(__a, __p, 1);
621 __before_begin()->__next_ = nullptr;
624 template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
625 class _LIBCPP_TEMPLATE_VIS forward_list
626 : private __forward_list_base<_Tp, _Alloc>
628 typedef __forward_list_base<_Tp, _Alloc> base;
629 typedef typename base::__node_allocator __node_allocator;
630 typedef typename base::__node __node;
631 typedef typename base::__node_traits __node_traits;
632 typedef typename base::__node_pointer __node_pointer;
633 typedef typename base::__begin_node_pointer __begin_node_pointer;
636 typedef _Tp value_type;
637 typedef _Alloc allocator_type;
639 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
640 "Allocator::value_type must be same type as value_type");
642 typedef value_type& reference;
643 typedef const value_type& const_reference;
644 typedef typename allocator_traits<allocator_type>::pointer pointer;
645 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
646 typedef typename allocator_traits<allocator_type>::size_type size_type;
647 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
649 typedef typename base::iterator iterator;
650 typedef typename base::const_iterator const_iterator;
652 _LIBCPP_INLINE_VISIBILITY
654 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
656 _LIBCPP_INLINE_VISIBILITY
657 explicit forward_list(const allocator_type& __a);
658 explicit forward_list(size_type __n);
659 #if _LIBCPP_STD_VER > 11
660 explicit forward_list(size_type __n, const allocator_type& __a);
662 forward_list(size_type __n, const value_type& __v);
663 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
664 template <class _InputIterator>
665 forward_list(_InputIterator __f, _InputIterator __l,
667 __is_input_iterator<_InputIterator>::value
669 template <class _InputIterator>
670 forward_list(_InputIterator __f, _InputIterator __l,
671 const allocator_type& __a,
673 __is_input_iterator<_InputIterator>::value
675 forward_list(const forward_list& __x);
676 forward_list(const forward_list& __x, const allocator_type& __a);
678 forward_list& operator=(const forward_list& __x);
680 #ifndef _LIBCPP_CXX03_LANG
681 _LIBCPP_INLINE_VISIBILITY
682 forward_list(forward_list&& __x)
683 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
684 : base(_VSTD::move(__x)) {}
685 forward_list(forward_list&& __x, const allocator_type& __a);
687 forward_list(initializer_list<value_type> __il);
688 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
690 _LIBCPP_INLINE_VISIBILITY
691 forward_list& operator=(forward_list&& __x)
693 __node_traits::propagate_on_container_move_assignment::value &&
694 is_nothrow_move_assignable<allocator_type>::value);
696 _LIBCPP_INLINE_VISIBILITY
697 forward_list& operator=(initializer_list<value_type> __il);
699 _LIBCPP_INLINE_VISIBILITY
700 void assign(initializer_list<value_type> __il);
701 #endif // _LIBCPP_CXX03_LANG
703 // ~forward_list() = default;
705 template <class _InputIterator>
708 __is_input_iterator<_InputIterator>::value,
711 assign(_InputIterator __f, _InputIterator __l);
712 void assign(size_type __n, const value_type& __v);
714 _LIBCPP_INLINE_VISIBILITY
715 allocator_type get_allocator() const _NOEXCEPT
716 {return allocator_type(base::__alloc());}
718 _LIBCPP_INLINE_VISIBILITY
719 iterator begin() _NOEXCEPT
720 {return iterator(base::__before_begin()->__next_);}
721 _LIBCPP_INLINE_VISIBILITY
722 const_iterator begin() const _NOEXCEPT
723 {return const_iterator(base::__before_begin()->__next_);}
724 _LIBCPP_INLINE_VISIBILITY
725 iterator end() _NOEXCEPT
726 {return iterator(nullptr);}
727 _LIBCPP_INLINE_VISIBILITY
728 const_iterator end() const _NOEXCEPT
729 {return const_iterator(nullptr);}
731 _LIBCPP_INLINE_VISIBILITY
732 const_iterator cbegin() const _NOEXCEPT
733 {return const_iterator(base::__before_begin()->__next_);}
734 _LIBCPP_INLINE_VISIBILITY
735 const_iterator cend() const _NOEXCEPT
736 {return const_iterator(nullptr);}
738 _LIBCPP_INLINE_VISIBILITY
739 iterator before_begin() _NOEXCEPT
740 {return iterator(base::__before_begin());}
741 _LIBCPP_INLINE_VISIBILITY
742 const_iterator before_begin() const _NOEXCEPT
743 {return const_iterator(base::__before_begin());}
744 _LIBCPP_INLINE_VISIBILITY
745 const_iterator cbefore_begin() const _NOEXCEPT
746 {return const_iterator(base::__before_begin());}
748 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
749 bool empty() const _NOEXCEPT
750 {return base::__before_begin()->__next_ == nullptr;}
751 _LIBCPP_INLINE_VISIBILITY
752 size_type max_size() const _NOEXCEPT {
753 return std::min<size_type>(
754 __node_traits::max_size(base::__alloc()),
755 numeric_limits<difference_type>::max());
758 _LIBCPP_INLINE_VISIBILITY
759 reference front() {return base::__before_begin()->__next_->__value_;}
760 _LIBCPP_INLINE_VISIBILITY
761 const_reference front() const {return base::__before_begin()->__next_->__value_;}
763 #ifndef _LIBCPP_CXX03_LANG
764 #if _LIBCPP_STD_VER > 14
765 template <class... _Args> reference emplace_front(_Args&&... __args);
767 template <class... _Args> void emplace_front(_Args&&... __args);
769 void push_front(value_type&& __v);
770 #endif // _LIBCPP_CXX03_LANG
771 void push_front(const value_type& __v);
775 #ifndef _LIBCPP_CXX03_LANG
776 template <class... _Args>
777 iterator emplace_after(const_iterator __p, _Args&&... __args);
779 iterator insert_after(const_iterator __p, value_type&& __v);
780 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
781 {return insert_after(__p, __il.begin(), __il.end());}
782 #endif // _LIBCPP_CXX03_LANG
783 iterator insert_after(const_iterator __p, const value_type& __v);
784 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
785 template <class _InputIterator>
786 _LIBCPP_INLINE_VISIBILITY
789 __is_input_iterator<_InputIterator>::value,
792 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
794 iterator erase_after(const_iterator __p);
795 iterator erase_after(const_iterator __f, const_iterator __l);
797 _LIBCPP_INLINE_VISIBILITY
798 void swap(forward_list& __x)
799 #if _LIBCPP_STD_VER >= 14
802 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
803 __is_nothrow_swappable<__node_allocator>::value)
807 void resize(size_type __n);
808 void resize(size_type __n, const value_type& __v);
809 _LIBCPP_INLINE_VISIBILITY
810 void clear() _NOEXCEPT {base::clear();}
812 #ifndef _LIBCPP_CXX03_LANG
813 _LIBCPP_INLINE_VISIBILITY
814 void splice_after(const_iterator __p, forward_list&& __x);
815 _LIBCPP_INLINE_VISIBILITY
816 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
817 _LIBCPP_INLINE_VISIBILITY
818 void splice_after(const_iterator __p, forward_list&& __x,
819 const_iterator __f, const_iterator __l);
820 #endif // _LIBCPP_CXX03_LANG
821 void splice_after(const_iterator __p, forward_list& __x);
822 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
823 void splice_after(const_iterator __p, forward_list& __x,
824 const_iterator __f, const_iterator __l);
825 void remove(const value_type& __v);
826 template <class _Predicate> void remove_if(_Predicate __pred);
827 _LIBCPP_INLINE_VISIBILITY
828 void unique() {unique(__equal_to<value_type>());}
829 template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
830 #ifndef _LIBCPP_CXX03_LANG
831 _LIBCPP_INLINE_VISIBILITY
832 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
833 template <class _Compare>
834 _LIBCPP_INLINE_VISIBILITY
835 void merge(forward_list&& __x, _Compare __comp)
836 {merge(__x, _VSTD::move(__comp));}
837 #endif // _LIBCPP_CXX03_LANG
838 _LIBCPP_INLINE_VISIBILITY
839 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
840 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
841 _LIBCPP_INLINE_VISIBILITY
842 void sort() {sort(__less<value_type>());}
843 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
844 void reverse() _NOEXCEPT;
848 #ifndef _LIBCPP_CXX03_LANG
849 void __move_assign(forward_list& __x, true_type)
850 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
851 void __move_assign(forward_list& __x, false_type);
852 #endif // _LIBCPP_CXX03_LANG
854 template <class _Compare>
857 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
859 template <class _Compare>
862 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
866 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
867 template<class _InputIterator,
868 class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
869 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
871 forward_list(_InputIterator, _InputIterator)
872 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
874 template<class _InputIterator,
876 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
878 forward_list(_InputIterator, _InputIterator, _Alloc)
879 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
882 template <class _Tp, class _Alloc>
884 forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
889 template <class _Tp, class _Alloc>
890 forward_list<_Tp, _Alloc>::forward_list(size_type __n)
894 __node_allocator& __a = base::__alloc();
895 typedef __allocator_destructor<__node_allocator> _Dp;
896 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
897 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
898 __p = __p->__next_as_begin())
900 __h.reset(__node_traits::allocate(__a, 1));
901 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
902 __h->__next_ = nullptr;
903 __p->__next_ = __h.release();
908 #if _LIBCPP_STD_VER > 11
909 template <class _Tp, class _Alloc>
910 forward_list<_Tp, _Alloc>::forward_list(size_type __n,
911 const allocator_type& __base_alloc)
912 : base ( __base_alloc )
916 __node_allocator& __a = base::__alloc();
917 typedef __allocator_destructor<__node_allocator> _Dp;
918 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
919 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
920 __p = __p->__next_as_begin())
922 __h.reset(__node_traits::allocate(__a, 1));
923 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
924 __h->__next_ = nullptr;
925 __p->__next_ = __h.release();
931 template <class _Tp, class _Alloc>
932 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
934 insert_after(cbefore_begin(), __n, __v);
937 template <class _Tp, class _Alloc>
938 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
939 const allocator_type& __a)
942 insert_after(cbefore_begin(), __n, __v);
945 template <class _Tp, class _Alloc>
946 template <class _InputIterator>
947 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
949 __is_input_iterator<_InputIterator>::value
952 insert_after(cbefore_begin(), __f, __l);
955 template <class _Tp, class _Alloc>
956 template <class _InputIterator>
957 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
958 const allocator_type& __a,
960 __is_input_iterator<_InputIterator>::value
964 insert_after(cbefore_begin(), __f, __l);
967 template <class _Tp, class _Alloc>
968 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
970 __node_traits::select_on_container_copy_construction(__x.__alloc())) {
971 insert_after(cbefore_begin(), __x.begin(), __x.end());
974 template <class _Tp, class _Alloc>
975 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
976 const allocator_type& __a)
979 insert_after(cbefore_begin(), __x.begin(), __x.end());
982 template <class _Tp, class _Alloc>
983 forward_list<_Tp, _Alloc>&
984 forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
988 base::__copy_assign_alloc(__x);
989 assign(__x.begin(), __x.end());
994 #ifndef _LIBCPP_CXX03_LANG
995 template <class _Tp, class _Alloc>
996 forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
997 const allocator_type& __a)
998 : base(_VSTD::move(__x), __a)
1000 if (base::__alloc() != __x.__alloc())
1002 typedef move_iterator<iterator> _Ip;
1003 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
1007 template <class _Tp, class _Alloc>
1008 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
1010 insert_after(cbefore_begin(), __il.begin(), __il.end());
1013 template <class _Tp, class _Alloc>
1014 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
1015 const allocator_type& __a)
1018 insert_after(cbefore_begin(), __il.begin(), __il.end());
1021 template <class _Tp, class _Alloc>
1023 forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
1024 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1027 base::__move_assign_alloc(__x);
1028 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
1029 __x.__before_begin()->__next_ = nullptr;
1032 template <class _Tp, class _Alloc>
1034 forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
1036 if (base::__alloc() == __x.__alloc())
1037 __move_assign(__x, true_type());
1040 typedef move_iterator<iterator> _Ip;
1041 assign(_Ip(__x.begin()), _Ip(__x.end()));
1045 template <class _Tp, class _Alloc>
1047 forward_list<_Tp, _Alloc>&
1048 forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
1050 __node_traits::propagate_on_container_move_assignment::value &&
1051 is_nothrow_move_assignable<allocator_type>::value)
1053 __move_assign(__x, integral_constant<bool,
1054 __node_traits::propagate_on_container_move_assignment::value>());
1058 template <class _Tp, class _Alloc>
1060 forward_list<_Tp, _Alloc>&
1061 forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
1063 assign(__il.begin(), __il.end());
1067 #endif // _LIBCPP_CXX03_LANG
1069 template <class _Tp, class _Alloc>
1070 template <class _InputIterator>
1073 __is_input_iterator<_InputIterator>::value,
1076 forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
1078 iterator __i = before_begin();
1079 iterator __j = _VSTD::next(__i);
1080 iterator __e = end();
1081 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
1084 insert_after(__i, __f, __l);
1086 erase_after(__i, __e);
1089 template <class _Tp, class _Alloc>
1091 forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
1093 iterator __i = before_begin();
1094 iterator __j = _VSTD::next(__i);
1095 iterator __e = end();
1096 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1099 insert_after(__i, __n, __v);
1101 erase_after(__i, __e);
1104 #ifndef _LIBCPP_CXX03_LANG
1106 template <class _Tp, class _Alloc>
1109 forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1111 assign(__il.begin(), __il.end());
1114 template <class _Tp, class _Alloc>
1115 template <class... _Args>
1116 #if _LIBCPP_STD_VER > 14
1117 typename forward_list<_Tp, _Alloc>::reference
1121 forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1123 __node_allocator& __a = base::__alloc();
1124 typedef __allocator_destructor<__node_allocator> _Dp;
1125 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1126 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1127 _VSTD::forward<_Args>(__args)...);
1128 __h->__next_ = base::__before_begin()->__next_;
1129 base::__before_begin()->__next_ = __h.release();
1130 #if _LIBCPP_STD_VER > 14
1131 return base::__before_begin()->__next_->__value_;
1135 template <class _Tp, class _Alloc>
1137 forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1139 __node_allocator& __a = base::__alloc();
1140 typedef __allocator_destructor<__node_allocator> _Dp;
1141 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1142 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1143 __h->__next_ = base::__before_begin()->__next_;
1144 base::__before_begin()->__next_ = __h.release();
1147 #endif // _LIBCPP_CXX03_LANG
1149 template <class _Tp, class _Alloc>
1151 forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1153 __node_allocator& __a = base::__alloc();
1154 typedef __allocator_destructor<__node_allocator> _Dp;
1155 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1156 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1157 __h->__next_ = base::__before_begin()->__next_;
1158 base::__before_begin()->__next_ = __h.release();
1161 template <class _Tp, class _Alloc>
1163 forward_list<_Tp, _Alloc>::pop_front()
1165 __node_allocator& __a = base::__alloc();
1166 __node_pointer __p = base::__before_begin()->__next_;
1167 base::__before_begin()->__next_ = __p->__next_;
1168 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
1169 __node_traits::deallocate(__a, __p, 1);
1172 #ifndef _LIBCPP_CXX03_LANG
1174 template <class _Tp, class _Alloc>
1175 template <class... _Args>
1176 typename forward_list<_Tp, _Alloc>::iterator
1177 forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1179 __begin_node_pointer const __r = __p.__get_begin();
1180 __node_allocator& __a = base::__alloc();
1181 typedef __allocator_destructor<__node_allocator> _Dp;
1182 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1183 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1184 _VSTD::forward<_Args>(__args)...);
1185 __h->__next_ = __r->__next_;
1186 __r->__next_ = __h.release();
1187 return iterator(__r->__next_);
1190 template <class _Tp, class _Alloc>
1191 typename forward_list<_Tp, _Alloc>::iterator
1192 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1194 __begin_node_pointer const __r = __p.__get_begin();
1195 __node_allocator& __a = base::__alloc();
1196 typedef __allocator_destructor<__node_allocator> _Dp;
1197 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1198 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1199 __h->__next_ = __r->__next_;
1200 __r->__next_ = __h.release();
1201 return iterator(__r->__next_);
1204 #endif // _LIBCPP_CXX03_LANG
1206 template <class _Tp, class _Alloc>
1207 typename forward_list<_Tp, _Alloc>::iterator
1208 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1210 __begin_node_pointer const __r = __p.__get_begin();
1211 __node_allocator& __a = base::__alloc();
1212 typedef __allocator_destructor<__node_allocator> _Dp;
1213 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1214 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1215 __h->__next_ = __r->__next_;
1216 __r->__next_ = __h.release();
1217 return iterator(__r->__next_);
1220 template <class _Tp, class _Alloc>
1221 typename forward_list<_Tp, _Alloc>::iterator
1222 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1223 const value_type& __v)
1225 __begin_node_pointer __r = __p.__get_begin();
1228 __node_allocator& __a = base::__alloc();
1229 typedef __allocator_destructor<__node_allocator> _Dp;
1230 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1231 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1232 __node_pointer __first = __h.release();
1233 __node_pointer __last = __first;
1234 #ifndef _LIBCPP_NO_EXCEPTIONS
1237 #endif // _LIBCPP_NO_EXCEPTIONS
1238 for (--__n; __n != 0; --__n, __last = __last->__next_)
1240 __h.reset(__node_traits::allocate(__a, 1));
1241 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1242 __last->__next_ = __h.release();
1244 #ifndef _LIBCPP_NO_EXCEPTIONS
1248 while (__first != nullptr)
1250 __node_pointer __next = __first->__next_;
1251 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1252 __node_traits::deallocate(__a, __first, 1);
1257 #endif // _LIBCPP_NO_EXCEPTIONS
1258 __last->__next_ = __r->__next_;
1259 __r->__next_ = __first;
1260 __r = static_cast<__begin_node_pointer>(__last);
1262 return iterator(__r);
1265 template <class _Tp, class _Alloc>
1266 template <class _InputIterator>
1269 __is_input_iterator<_InputIterator>::value,
1270 typename forward_list<_Tp, _Alloc>::iterator
1272 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1273 _InputIterator __f, _InputIterator __l)
1275 __begin_node_pointer __r = __p.__get_begin();
1278 __node_allocator& __a = base::__alloc();
1279 typedef __allocator_destructor<__node_allocator> _Dp;
1280 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1281 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1282 __node_pointer __first = __h.release();
1283 __node_pointer __last = __first;
1284 #ifndef _LIBCPP_NO_EXCEPTIONS
1287 #endif // _LIBCPP_NO_EXCEPTIONS
1288 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
1290 __h.reset(__node_traits::allocate(__a, 1));
1291 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1292 __last->__next_ = __h.release();
1294 #ifndef _LIBCPP_NO_EXCEPTIONS
1298 while (__first != nullptr)
1300 __node_pointer __next = __first->__next_;
1301 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1302 __node_traits::deallocate(__a, __first, 1);
1307 #endif // _LIBCPP_NO_EXCEPTIONS
1308 __last->__next_ = __r->__next_;
1309 __r->__next_ = __first;
1310 __r = static_cast<__begin_node_pointer>(__last);
1312 return iterator(__r);
1315 template <class _Tp, class _Alloc>
1316 typename forward_list<_Tp, _Alloc>::iterator
1317 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1319 __begin_node_pointer __p = __f.__get_begin();
1320 __node_pointer __n = __p->__next_;
1321 __p->__next_ = __n->__next_;
1322 __node_allocator& __a = base::__alloc();
1323 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1324 __node_traits::deallocate(__a, __n, 1);
1325 return iterator(__p->__next_);
1328 template <class _Tp, class _Alloc>
1329 typename forward_list<_Tp, _Alloc>::iterator
1330 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1332 __node_pointer __e = __l.__get_unsafe_node_pointer();
1335 __begin_node_pointer __bp = __f.__get_begin();
1337 __node_pointer __n = __bp->__next_;
1340 __bp->__next_ = __e;
1341 __node_allocator& __a = base::__alloc();
1344 __node_pointer __tmp = __n->__next_;
1345 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1346 __node_traits::deallocate(__a, __n, 1);
1348 } while (__n != __e);
1351 return iterator(__e);
1354 template <class _Tp, class _Alloc>
1356 forward_list<_Tp, _Alloc>::resize(size_type __n)
1359 iterator __p = before_begin();
1360 iterator __i = begin();
1361 iterator __e = end();
1362 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1365 erase_after(__p, __e);
1371 __node_allocator& __a = base::__alloc();
1372 typedef __allocator_destructor<__node_allocator> _Dp;
1373 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
1374 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1375 __ptr = __ptr->__next_as_begin())
1377 __h.reset(__node_traits::allocate(__a, 1));
1378 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
1379 __h->__next_ = nullptr;
1380 __ptr->__next_ = __h.release();
1386 template <class _Tp, class _Alloc>
1388 forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1391 iterator __p = before_begin();
1392 iterator __i = begin();
1393 iterator __e = end();
1394 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1397 erase_after(__p, __e);
1403 __node_allocator& __a = base::__alloc();
1404 typedef __allocator_destructor<__node_allocator> _Dp;
1405 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
1406 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1407 __ptr = __ptr->__next_as_begin())
1409 __h.reset(__node_traits::allocate(__a, 1));
1410 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1411 __h->__next_ = nullptr;
1412 __ptr->__next_ = __h.release();
1418 template <class _Tp, class _Alloc>
1420 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1425 if (__p.__get_begin()->__next_ != nullptr)
1427 const_iterator __lm1 = __x.before_begin();
1428 while (__lm1.__get_begin()->__next_ != nullptr)
1430 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1432 __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
1433 __x.__before_begin()->__next_ = nullptr;
1437 template <class _Tp, class _Alloc>
1439 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1440 forward_list& /*__other*/,
1443 const_iterator __lm1 = _VSTD::next(__i);
1444 if (__p != __i && __p != __lm1)
1446 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
1447 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1448 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
1452 template <class _Tp, class _Alloc>
1454 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1455 forward_list& /*__other*/,
1456 const_iterator __f, const_iterator __l)
1458 if (__f != __l && __p != __f)
1460 const_iterator __lm1 = __f;
1461 while (__lm1.__get_begin()->__next_ != __l.__get_begin())
1465 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1466 __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
1467 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
1472 #ifndef _LIBCPP_CXX03_LANG
1474 template <class _Tp, class _Alloc>
1475 inline _LIBCPP_INLINE_VISIBILITY
1477 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1480 splice_after(__p, __x);
1483 template <class _Tp, class _Alloc>
1484 inline _LIBCPP_INLINE_VISIBILITY
1486 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1490 splice_after(__p, __x, __i);
1493 template <class _Tp, class _Alloc>
1494 inline _LIBCPP_INLINE_VISIBILITY
1496 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1498 const_iterator __f, const_iterator __l)
1500 splice_after(__p, __x, __f, __l);
1503 #endif // _LIBCPP_CXX03_LANG
1505 template <class _Tp, class _Alloc>
1507 forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1509 forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
1510 iterator __e = end();
1511 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
1513 if (__i.__get_begin()->__next_->__value_ == __v)
1515 iterator __j = _VSTD::next(__i, 2);
1516 for (; __j != __e && *__j == __v; ++__j)
1518 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1528 template <class _Tp, class _Alloc>
1529 template <class _Predicate>
1531 forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1533 iterator __e = end();
1534 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
1536 if (__pred(__i.__get_begin()->__next_->__value_))
1538 iterator __j = _VSTD::next(__i, 2);
1539 for (; __j != __e && __pred(*__j); ++__j)
1541 erase_after(__i, __j);
1551 template <class _Tp, class _Alloc>
1552 template <class _BinaryPredicate>
1554 forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1556 for (iterator __i = begin(), __e = end(); __i != __e;)
1558 iterator __j = _VSTD::next(__i);
1559 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1561 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
1562 erase_after(__i, __j);
1567 template <class _Tp, class _Alloc>
1568 template <class _Compare>
1570 forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1574 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1575 __x.__before_begin()->__next_,
1577 __x.__before_begin()->__next_ = nullptr;
1581 template <class _Tp, class _Alloc>
1582 template <class _Compare>
1583 typename forward_list<_Tp, _Alloc>::__node_pointer
1584 forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1587 if (__f1 == nullptr)
1589 if (__f2 == nullptr)
1592 if (__comp(__f2->__value_, __f1->__value_))
1594 __node_pointer __t = __f2;
1595 while (__t->__next_ != nullptr &&
1596 __comp(__t->__next_->__value_, __f1->__value_))
1599 __f2 = __t->__next_;
1600 __t->__next_ = __f1;
1604 __node_pointer __p = __f1;
1605 __f1 = __f1->__next_;
1606 while (__f1 != nullptr && __f2 != nullptr)
1608 if (__comp(__f2->__value_, __f1->__value_))
1610 __node_pointer __t = __f2;
1611 while (__t->__next_ != nullptr &&
1612 __comp(__t->__next_->__value_, __f1->__value_))
1614 __p->__next_ = __f2;
1615 __f2 = __t->__next_;
1616 __t->__next_ = __f1;
1619 __f1 = __f1->__next_;
1621 if (__f2 != nullptr)
1622 __p->__next_ = __f2;
1626 template <class _Tp, class _Alloc>
1627 template <class _Compare>
1630 forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1632 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1633 _VSTD::distance(begin(), end()), __comp);
1636 template <class _Tp, class _Alloc>
1637 template <class _Compare>
1638 typename forward_list<_Tp, _Alloc>::__node_pointer
1639 forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1648 if (__comp(__f1->__next_->__value_, __f1->__value_))
1650 __node_pointer __t = __f1->__next_;
1651 __t->__next_ = __f1;
1652 __f1->__next_ = nullptr;
1657 difference_type __sz1 = __sz / 2;
1658 difference_type __sz2 = __sz - __sz1;
1659 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
1660 __node_pointer __f2 = __t->__next_;
1661 __t->__next_ = nullptr;
1662 return __merge(__sort(__f1, __sz1, __comp),
1663 __sort(__f2, __sz2, __comp), __comp);
1666 template <class _Tp, class _Alloc>
1668 forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
1670 __node_pointer __p = base::__before_begin()->__next_;
1673 __node_pointer __f = __p->__next_;
1674 __p->__next_ = nullptr;
1675 while (__f != nullptr)
1677 __node_pointer __t = __f->__next_;
1682 base::__before_begin()->__next_ = __p;
1686 template <class _Tp, class _Alloc>
1687 bool operator==(const forward_list<_Tp, _Alloc>& __x,
1688 const forward_list<_Tp, _Alloc>& __y)
1690 typedef forward_list<_Tp, _Alloc> _Cp;
1691 typedef typename _Cp::const_iterator _Ip;
1692 _Ip __ix = __x.begin();
1693 _Ip __ex = __x.end();
1694 _Ip __iy = __y.begin();
1695 _Ip __ey = __y.end();
1696 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1697 if (!(*__ix == *__iy))
1699 return (__ix == __ex) == (__iy == __ey);
1702 template <class _Tp, class _Alloc>
1703 inline _LIBCPP_INLINE_VISIBILITY
1704 bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1705 const forward_list<_Tp, _Alloc>& __y)
1707 return !(__x == __y);
1710 template <class _Tp, class _Alloc>
1711 inline _LIBCPP_INLINE_VISIBILITY
1712 bool operator< (const forward_list<_Tp, _Alloc>& __x,
1713 const forward_list<_Tp, _Alloc>& __y)
1715 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
1716 __y.begin(), __y.end());
1719 template <class _Tp, class _Alloc>
1720 inline _LIBCPP_INLINE_VISIBILITY
1721 bool operator> (const forward_list<_Tp, _Alloc>& __x,
1722 const forward_list<_Tp, _Alloc>& __y)
1727 template <class _Tp, class _Alloc>
1728 inline _LIBCPP_INLINE_VISIBILITY
1729 bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1730 const forward_list<_Tp, _Alloc>& __y)
1732 return !(__x < __y);
1735 template <class _Tp, class _Alloc>
1736 inline _LIBCPP_INLINE_VISIBILITY
1737 bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1738 const forward_list<_Tp, _Alloc>& __y)
1740 return !(__y < __x);
1743 template <class _Tp, class _Alloc>
1744 inline _LIBCPP_INLINE_VISIBILITY
1746 swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1747 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1752 #if _LIBCPP_STD_VER > 17
1753 template <class _Tp, class _Allocator, class _Predicate>
1754 inline _LIBCPP_INLINE_VISIBILITY
1755 void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred)
1756 { __c.remove_if(__pred); }
1758 template <class _Tp, class _Allocator, class _Up>
1759 inline _LIBCPP_INLINE_VISIBILITY
1760 void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v)
1761 { _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
1764 _LIBCPP_END_NAMESPACE_STD
1768 #endif // _LIBCPP_FORWARD_LIST