2 //===----------------------- forward_list ---------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_FORWARD_LIST
11 #define _LIBCPP_FORWARD_LIST
19 template <class T, class Allocator = allocator<T>>
24 typedef Allocator allocator_type;
26 typedef value_type& reference;
27 typedef const value_type& const_reference;
28 typedef typename allocator_traits<allocator_type>::pointer pointer;
29 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
30 typedef typename allocator_traits<allocator_type>::size_type size_type;
31 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
33 typedef <details> iterator;
34 typedef <details> const_iterator;
37 noexcept(is_nothrow_default_constructible<allocator_type>::value);
38 explicit forward_list(const allocator_type& a);
39 explicit forward_list(size_type n);
40 explicit forward_list(size_type n, const allocator_type& a); // C++14
41 forward_list(size_type n, const value_type& v);
42 forward_list(size_type n, const value_type& v, const allocator_type& a);
43 template <class InputIterator>
44 forward_list(InputIterator first, InputIterator last);
45 template <class InputIterator>
46 forward_list(InputIterator first, InputIterator last, const allocator_type& a);
47 forward_list(const forward_list& x);
48 forward_list(const forward_list& x, const allocator_type& a);
49 forward_list(forward_list&& x)
50 noexcept(is_nothrow_move_constructible<allocator_type>::value);
51 forward_list(forward_list&& x, const allocator_type& a);
52 forward_list(initializer_list<value_type> il);
53 forward_list(initializer_list<value_type> il, const allocator_type& a);
57 forward_list& operator=(const forward_list& x);
58 forward_list& operator=(forward_list&& x)
60 allocator_type::propagate_on_container_move_assignment::value &&
61 is_nothrow_move_assignable<allocator_type>::value);
62 forward_list& operator=(initializer_list<value_type> il);
64 template <class InputIterator>
65 void assign(InputIterator first, InputIterator last);
66 void assign(size_type n, const value_type& v);
67 void assign(initializer_list<value_type> il);
69 allocator_type get_allocator() const noexcept;
71 iterator begin() noexcept;
72 const_iterator begin() const noexcept;
73 iterator end() noexcept;
74 const_iterator end() const noexcept;
76 const_iterator cbegin() const noexcept;
77 const_iterator cend() const noexcept;
79 iterator before_begin() noexcept;
80 const_iterator before_begin() const noexcept;
81 const_iterator cbefore_begin() const noexcept;
83 bool empty() const noexcept;
84 size_type max_size() const noexcept;
87 const_reference front() const;
89 template <class... Args> reference emplace_front(Args&&... args); // reference in C++17
90 void push_front(const value_type& v);
91 void push_front(value_type&& v);
95 template <class... Args>
96 iterator emplace_after(const_iterator p, Args&&... args);
97 iterator insert_after(const_iterator p, const value_type& v);
98 iterator insert_after(const_iterator p, value_type&& v);
99 iterator insert_after(const_iterator p, size_type n, const value_type& v);
100 template <class InputIterator>
101 iterator insert_after(const_iterator p,
102 InputIterator first, InputIterator last);
103 iterator insert_after(const_iterator p, initializer_list<value_type> il);
105 iterator erase_after(const_iterator p);
106 iterator erase_after(const_iterator first, const_iterator last);
108 void swap(forward_list& x)
109 noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
111 void resize(size_type n);
112 void resize(size_type n, const value_type& v);
113 void clear() noexcept;
115 void splice_after(const_iterator p, forward_list& x);
116 void splice_after(const_iterator p, forward_list&& x);
117 void splice_after(const_iterator p, forward_list& x, const_iterator i);
118 void splice_after(const_iterator p, forward_list&& x, const_iterator i);
119 void splice_after(const_iterator p, forward_list& x,
120 const_iterator first, const_iterator last);
121 void splice_after(const_iterator p, forward_list&& x,
122 const_iterator first, const_iterator last);
123 size_type remove(const value_type& v); // void before C++20
124 template <class Predicate>
125 size_type remove_if(Predicate pred); // void before C++20
126 size_type unique(); // void before C++20
127 template <class BinaryPredicate>
128 size_type unique(BinaryPredicate binary_pred); // void before C++20
129 void merge(forward_list& x);
130 void merge(forward_list&& x);
131 template <class Compare> void merge(forward_list& x, Compare comp);
132 template <class Compare> void merge(forward_list&& x, Compare comp);
134 template <class Compare> void sort(Compare comp);
135 void reverse() noexcept;
139 template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
140 forward_list(InputIterator, InputIterator, Allocator = Allocator())
141 -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17
143 template <class T, class Allocator>
144 bool operator==(const forward_list<T, Allocator>& x,
145 const forward_list<T, Allocator>& y);
147 template <class T, class Allocator>
148 bool operator< (const forward_list<T, Allocator>& x,
149 const forward_list<T, Allocator>& y);
151 template <class T, class Allocator>
152 bool operator!=(const forward_list<T, Allocator>& x,
153 const forward_list<T, Allocator>& y);
155 template <class T, class Allocator>
156 bool operator> (const forward_list<T, Allocator>& x,
157 const forward_list<T, Allocator>& y);
159 template <class T, class Allocator>
160 bool operator>=(const forward_list<T, Allocator>& x,
161 const forward_list<T, Allocator>& y);
163 template <class T, class Allocator>
164 bool operator<=(const forward_list<T, Allocator>& x,
165 const forward_list<T, Allocator>& y);
167 template <class T, class Allocator>
168 void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
169 noexcept(noexcept(x.swap(y)));
171 template <class T, class Allocator, class U>
172 void erase(forward_list<T, Allocator>& c, const U& value); // C++20
173 template <class T, class Allocator, class Predicate>
174 void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
181 #include <initializer_list>
188 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
189 #pragma GCC system_header
193 #include <__undef_macros>
196 _LIBCPP_BEGIN_NAMESPACE_STD
198 template <class _Tp, class _VoidPtr> struct __forward_list_node;
199 template <class _NodePtr> struct __forward_begin_node;
203 struct __forward_list_node_value_type;
205 template <class _Tp, class _VoidPtr>
206 struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > {
210 template <class _NodePtr>
211 struct __forward_node_traits {
213 typedef typename remove_cv<
214 typename pointer_traits<_NodePtr>::element_type>::type __node;
215 typedef typename __forward_list_node_value_type<__node>::type __node_value_type;
216 typedef _NodePtr __node_pointer;
217 typedef __forward_begin_node<_NodePtr> __begin_node;
218 typedef typename __rebind_pointer<_NodePtr, __begin_node>::type
219 __begin_node_pointer;
220 typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer;
222 #if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
223 typedef __begin_node_pointer __iter_node_pointer;
225 typedef typename conditional<
226 is_pointer<__void_pointer>::value,
227 __begin_node_pointer,
229 >::type __iter_node_pointer;
232 typedef typename conditional<
233 is_same<__iter_node_pointer, __node_pointer>::value,
234 __begin_node_pointer,
236 >::type __non_iter_node_pointer;
238 _LIBCPP_INLINE_VISIBILITY
239 static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) {
242 _LIBCPP_INLINE_VISIBILITY
243 static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
244 return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
248 template <class _NodePtr>
249 struct __forward_begin_node
251 typedef _NodePtr pointer;
252 typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer;
256 _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
258 _LIBCPP_INLINE_VISIBILITY
259 __begin_node_pointer __next_as_begin() const {
260 return static_cast<__begin_node_pointer>(__next_);
264 template <class _Tp, class _VoidPtr>
265 struct _LIBCPP_HIDDEN __begin_node_of
267 typedef __forward_begin_node<
268 typename __rebind_pointer<_VoidPtr, __forward_list_node<_Tp, _VoidPtr> >::type
272 template <class _Tp, class _VoidPtr>
273 struct __forward_list_node
274 : public __begin_node_of<_Tp, _VoidPtr>::type
276 typedef _Tp value_type;
282 template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS forward_list;
283 template<class _NodeConstPtr> class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
285 template <class _NodePtr>
286 class _LIBCPP_TEMPLATE_VIS __forward_list_iterator
288 typedef __forward_node_traits<_NodePtr> __traits;
289 typedef typename __traits::__node_pointer __node_pointer;
290 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
291 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
292 typedef typename __traits::__void_pointer __void_pointer;
294 __iter_node_pointer __ptr_;
296 _LIBCPP_INLINE_VISIBILITY
297 __begin_node_pointer __get_begin() const {
298 return static_cast<__begin_node_pointer>(
299 static_cast<__void_pointer>(__ptr_));
301 _LIBCPP_INLINE_VISIBILITY
302 __node_pointer __get_unsafe_node_pointer() const {
303 return static_cast<__node_pointer>(
304 static_cast<__void_pointer>(__ptr_));
307 _LIBCPP_INLINE_VISIBILITY
308 explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {}
310 _LIBCPP_INLINE_VISIBILITY
311 explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT
312 : __ptr_(__traits::__as_iter_node(__p)) {}
314 _LIBCPP_INLINE_VISIBILITY
315 explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT
316 : __ptr_(__traits::__as_iter_node(__p)) {}
318 template<class, class> friend class _LIBCPP_TEMPLATE_VIS forward_list;
319 template<class> friend class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator;
322 typedef forward_iterator_tag iterator_category;
323 typedef typename __traits::__node_value_type value_type;
324 typedef value_type& reference;
325 typedef typename pointer_traits<__node_pointer>::difference_type
327 typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer;
329 _LIBCPP_INLINE_VISIBILITY
330 __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
332 _LIBCPP_INLINE_VISIBILITY
333 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
334 _LIBCPP_INLINE_VISIBILITY
335 pointer operator->() const {
336 return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_);
339 _LIBCPP_INLINE_VISIBILITY
340 __forward_list_iterator& operator++()
342 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
345 _LIBCPP_INLINE_VISIBILITY
346 __forward_list_iterator operator++(int)
348 __forward_list_iterator __t(*this);
353 friend _LIBCPP_INLINE_VISIBILITY
354 bool operator==(const __forward_list_iterator& __x,
355 const __forward_list_iterator& __y)
356 {return __x.__ptr_ == __y.__ptr_;}
357 friend _LIBCPP_INLINE_VISIBILITY
358 bool operator!=(const __forward_list_iterator& __x,
359 const __forward_list_iterator& __y)
360 {return !(__x == __y);}
363 template <class _NodeConstPtr>
364 class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator
366 static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), "");
367 typedef _NodeConstPtr _NodePtr;
369 typedef __forward_node_traits<_NodePtr> __traits;
370 typedef typename __traits::__node __node;
371 typedef typename __traits::__node_pointer __node_pointer;
372 typedef typename __traits::__begin_node_pointer __begin_node_pointer;
373 typedef typename __traits::__iter_node_pointer __iter_node_pointer;
374 typedef typename __traits::__void_pointer __void_pointer;
376 __iter_node_pointer __ptr_;
378 __begin_node_pointer __get_begin() const {
379 return static_cast<__begin_node_pointer>(
380 static_cast<__void_pointer>(__ptr_));
382 __node_pointer __get_unsafe_node_pointer() const {
383 return static_cast<__node_pointer>(
384 static_cast<__void_pointer>(__ptr_));
387 _LIBCPP_INLINE_VISIBILITY
388 explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
391 _LIBCPP_INLINE_VISIBILITY
392 explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT
393 : __ptr_(__traits::__as_iter_node(__p)) {}
395 _LIBCPP_INLINE_VISIBILITY
396 explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT
397 : __ptr_(__traits::__as_iter_node(__p)) {}
400 template<class, class> friend class forward_list;
403 typedef forward_iterator_tag iterator_category;
404 typedef typename __traits::__node_value_type value_type;
405 typedef const value_type& reference;
406 typedef typename pointer_traits<__node_pointer>::difference_type
408 typedef typename __rebind_pointer<__node_pointer, const value_type>::type
411 _LIBCPP_INLINE_VISIBILITY
412 __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
413 _LIBCPP_INLINE_VISIBILITY
414 __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
415 : __ptr_(__p.__ptr_) {}
417 _LIBCPP_INLINE_VISIBILITY
418 reference operator*() const {return __get_unsafe_node_pointer()->__value_;}
419 _LIBCPP_INLINE_VISIBILITY
420 pointer operator->() const {return pointer_traits<pointer>::pointer_to(
421 __get_unsafe_node_pointer()->__value_);}
423 _LIBCPP_INLINE_VISIBILITY
424 __forward_list_const_iterator& operator++()
426 __ptr_ = __traits::__as_iter_node(__ptr_->__next_);
429 _LIBCPP_INLINE_VISIBILITY
430 __forward_list_const_iterator operator++(int)
432 __forward_list_const_iterator __t(*this);
437 friend _LIBCPP_INLINE_VISIBILITY
438 bool operator==(const __forward_list_const_iterator& __x,
439 const __forward_list_const_iterator& __y)
440 {return __x.__ptr_ == __y.__ptr_;}
441 friend _LIBCPP_INLINE_VISIBILITY
442 bool operator!=(const __forward_list_const_iterator& __x,
443 const __forward_list_const_iterator& __y)
444 {return !(__x == __y);}
447 template <class _Tp, class _Alloc>
448 class __forward_list_base
451 typedef _Tp value_type;
452 typedef _Alloc allocator_type;
454 typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
455 typedef __forward_list_node<value_type, void_pointer> __node;
456 typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
457 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
458 typedef allocator_traits<__node_allocator> __node_traits;
459 typedef typename __node_traits::pointer __node_pointer;
461 typedef typename __rebind_alloc_helper<
462 allocator_traits<allocator_type>, __begin_node
463 >::type __begin_node_allocator;
464 typedef typename allocator_traits<__begin_node_allocator>::pointer
465 __begin_node_pointer;
467 static_assert((!is_same<allocator_type, __node_allocator>::value),
468 "internal allocator type must differ from user-specified "
469 "type; otherwise overload resolution breaks");
471 __compressed_pair<__begin_node, __node_allocator> __before_begin_;
473 _LIBCPP_INLINE_VISIBILITY
474 __begin_node_pointer __before_begin() _NOEXCEPT
475 {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());}
476 _LIBCPP_INLINE_VISIBILITY
477 __begin_node_pointer __before_begin() const _NOEXCEPT
478 {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));}
480 _LIBCPP_INLINE_VISIBILITY
481 __node_allocator& __alloc() _NOEXCEPT
482 {return __before_begin_.second();}
483 _LIBCPP_INLINE_VISIBILITY
484 const __node_allocator& __alloc() const _NOEXCEPT
485 {return __before_begin_.second();}
487 typedef __forward_list_iterator<__node_pointer> iterator;
488 typedef __forward_list_const_iterator<__node_pointer> const_iterator;
490 _LIBCPP_INLINE_VISIBILITY
491 __forward_list_base()
492 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
493 : __before_begin_(__begin_node()) {}
494 _LIBCPP_INLINE_VISIBILITY
495 explicit __forward_list_base(const allocator_type& __a)
496 : __before_begin_(__begin_node(), __node_allocator(__a)) {}
497 _LIBCPP_INLINE_VISIBILITY
498 explicit __forward_list_base(const __node_allocator& __a)
499 : __before_begin_(__begin_node(), __a) {}
500 #ifndef _LIBCPP_CXX03_LANG
502 _LIBCPP_INLINE_VISIBILITY
503 __forward_list_base(__forward_list_base&& __x)
504 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
505 _LIBCPP_INLINE_VISIBILITY
506 __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
507 #endif // _LIBCPP_CXX03_LANG
510 __forward_list_base(const __forward_list_base&);
511 __forward_list_base& operator=(const __forward_list_base&);
514 ~__forward_list_base();
517 _LIBCPP_INLINE_VISIBILITY
518 void __copy_assign_alloc(const __forward_list_base& __x)
519 {__copy_assign_alloc(__x, integral_constant<bool,
520 __node_traits::propagate_on_container_copy_assignment::value>());}
522 _LIBCPP_INLINE_VISIBILITY
523 void __move_assign_alloc(__forward_list_base& __x)
524 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
525 is_nothrow_move_assignable<__node_allocator>::value)
526 {__move_assign_alloc(__x, integral_constant<bool,
527 __node_traits::propagate_on_container_move_assignment::value>());}
530 _LIBCPP_INLINE_VISIBILITY
531 void swap(__forward_list_base& __x)
532 #if _LIBCPP_STD_VER >= 14
535 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
536 __is_nothrow_swappable<__node_allocator>::value);
539 void clear() _NOEXCEPT;
542 _LIBCPP_INLINE_VISIBILITY
543 void __copy_assign_alloc(const __forward_list_base&, false_type) {}
544 _LIBCPP_INLINE_VISIBILITY
545 void __copy_assign_alloc(const __forward_list_base& __x, true_type)
547 if (__alloc() != __x.__alloc())
549 __alloc() = __x.__alloc();
552 _LIBCPP_INLINE_VISIBILITY
553 void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT
555 _LIBCPP_INLINE_VISIBILITY
556 void __move_assign_alloc(__forward_list_base& __x, true_type)
557 _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
558 {__alloc() = _VSTD::move(__x.__alloc());}
561 #ifndef _LIBCPP_CXX03_LANG
563 template <class _Tp, class _Alloc>
565 __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
566 _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
567 : __before_begin_(_VSTD::move(__x.__before_begin_))
569 __x.__before_begin()->__next_ = nullptr;
572 template <class _Tp, class _Alloc>
574 __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
575 const allocator_type& __a)
576 : __before_begin_(__begin_node(), __node_allocator(__a))
578 if (__alloc() == __x.__alloc())
580 __before_begin()->__next_ = __x.__before_begin()->__next_;
581 __x.__before_begin()->__next_ = nullptr;
585 #endif // _LIBCPP_CXX03_LANG
587 template <class _Tp, class _Alloc>
588 __forward_list_base<_Tp, _Alloc>::~__forward_list_base()
593 template <class _Tp, class _Alloc>
596 __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
597 #if _LIBCPP_STD_VER >= 14
600 _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
601 __is_nothrow_swappable<__node_allocator>::value)
604 __swap_allocator(__alloc(), __x.__alloc(),
605 integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
607 swap(__before_begin()->__next_, __x.__before_begin()->__next_);
610 template <class _Tp, class _Alloc>
612 __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
614 __node_allocator& __a = __alloc();
615 for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
617 __node_pointer __next = __p->__next_;
618 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
619 __node_traits::deallocate(__a, __p, 1);
622 __before_begin()->__next_ = nullptr;
625 template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
626 class _LIBCPP_TEMPLATE_VIS forward_list
627 : private __forward_list_base<_Tp, _Alloc>
629 typedef __forward_list_base<_Tp, _Alloc> base;
630 typedef typename base::__node_allocator __node_allocator;
631 typedef typename base::__node __node;
632 typedef typename base::__node_traits __node_traits;
633 typedef typename base::__node_pointer __node_pointer;
634 typedef typename base::__begin_node_pointer __begin_node_pointer;
637 typedef _Tp value_type;
638 typedef _Alloc allocator_type;
640 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
641 "Allocator::value_type must be same type as value_type");
643 typedef value_type& reference;
644 typedef const value_type& const_reference;
645 typedef typename allocator_traits<allocator_type>::pointer pointer;
646 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
647 typedef typename allocator_traits<allocator_type>::size_type size_type;
648 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
650 typedef typename base::iterator iterator;
651 typedef typename base::const_iterator const_iterator;
652 #if _LIBCPP_STD_VER > 17
653 typedef size_type __remove_return_type;
655 typedef void __remove_return_type;
658 _LIBCPP_INLINE_VISIBILITY
660 _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
662 _LIBCPP_INLINE_VISIBILITY
663 explicit forward_list(const allocator_type& __a);
664 explicit forward_list(size_type __n);
665 #if _LIBCPP_STD_VER > 11
666 explicit forward_list(size_type __n, const allocator_type& __a);
668 forward_list(size_type __n, const value_type& __v);
669 forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
670 template <class _InputIterator>
671 forward_list(_InputIterator __f, _InputIterator __l,
673 __is_input_iterator<_InputIterator>::value
675 template <class _InputIterator>
676 forward_list(_InputIterator __f, _InputIterator __l,
677 const allocator_type& __a,
679 __is_input_iterator<_InputIterator>::value
681 forward_list(const forward_list& __x);
682 forward_list(const forward_list& __x, const allocator_type& __a);
684 forward_list& operator=(const forward_list& __x);
686 #ifndef _LIBCPP_CXX03_LANG
687 _LIBCPP_INLINE_VISIBILITY
688 forward_list(forward_list&& __x)
689 _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
690 : base(_VSTD::move(__x)) {}
691 forward_list(forward_list&& __x, const allocator_type& __a);
693 forward_list(initializer_list<value_type> __il);
694 forward_list(initializer_list<value_type> __il, const allocator_type& __a);
696 _LIBCPP_INLINE_VISIBILITY
697 forward_list& operator=(forward_list&& __x)
699 __node_traits::propagate_on_container_move_assignment::value &&
700 is_nothrow_move_assignable<allocator_type>::value);
702 _LIBCPP_INLINE_VISIBILITY
703 forward_list& operator=(initializer_list<value_type> __il);
705 _LIBCPP_INLINE_VISIBILITY
706 void assign(initializer_list<value_type> __il);
707 #endif // _LIBCPP_CXX03_LANG
709 // ~forward_list() = default;
711 template <class _InputIterator>
714 __is_input_iterator<_InputIterator>::value,
717 assign(_InputIterator __f, _InputIterator __l);
718 void assign(size_type __n, const value_type& __v);
720 _LIBCPP_INLINE_VISIBILITY
721 allocator_type get_allocator() const _NOEXCEPT
722 {return allocator_type(base::__alloc());}
724 _LIBCPP_INLINE_VISIBILITY
725 iterator begin() _NOEXCEPT
726 {return iterator(base::__before_begin()->__next_);}
727 _LIBCPP_INLINE_VISIBILITY
728 const_iterator begin() const _NOEXCEPT
729 {return const_iterator(base::__before_begin()->__next_);}
730 _LIBCPP_INLINE_VISIBILITY
731 iterator end() _NOEXCEPT
732 {return iterator(nullptr);}
733 _LIBCPP_INLINE_VISIBILITY
734 const_iterator end() const _NOEXCEPT
735 {return const_iterator(nullptr);}
737 _LIBCPP_INLINE_VISIBILITY
738 const_iterator cbegin() const _NOEXCEPT
739 {return const_iterator(base::__before_begin()->__next_);}
740 _LIBCPP_INLINE_VISIBILITY
741 const_iterator cend() const _NOEXCEPT
742 {return const_iterator(nullptr);}
744 _LIBCPP_INLINE_VISIBILITY
745 iterator before_begin() _NOEXCEPT
746 {return iterator(base::__before_begin());}
747 _LIBCPP_INLINE_VISIBILITY
748 const_iterator before_begin() const _NOEXCEPT
749 {return const_iterator(base::__before_begin());}
750 _LIBCPP_INLINE_VISIBILITY
751 const_iterator cbefore_begin() const _NOEXCEPT
752 {return const_iterator(base::__before_begin());}
754 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
755 bool empty() const _NOEXCEPT
756 {return base::__before_begin()->__next_ == nullptr;}
757 _LIBCPP_INLINE_VISIBILITY
758 size_type max_size() const _NOEXCEPT {
759 return std::min<size_type>(
760 __node_traits::max_size(base::__alloc()),
761 numeric_limits<difference_type>::max());
764 _LIBCPP_INLINE_VISIBILITY
765 reference front() {return base::__before_begin()->__next_->__value_;}
766 _LIBCPP_INLINE_VISIBILITY
767 const_reference front() const {return base::__before_begin()->__next_->__value_;}
769 #ifndef _LIBCPP_CXX03_LANG
770 #if _LIBCPP_STD_VER > 14
771 template <class... _Args> reference emplace_front(_Args&&... __args);
773 template <class... _Args> void emplace_front(_Args&&... __args);
775 void push_front(value_type&& __v);
776 #endif // _LIBCPP_CXX03_LANG
777 void push_front(const value_type& __v);
781 #ifndef _LIBCPP_CXX03_LANG
782 template <class... _Args>
783 iterator emplace_after(const_iterator __p, _Args&&... __args);
785 iterator insert_after(const_iterator __p, value_type&& __v);
786 iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
787 {return insert_after(__p, __il.begin(), __il.end());}
788 #endif // _LIBCPP_CXX03_LANG
789 iterator insert_after(const_iterator __p, const value_type& __v);
790 iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
791 template <class _InputIterator>
792 _LIBCPP_INLINE_VISIBILITY
795 __is_input_iterator<_InputIterator>::value,
798 insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
800 iterator erase_after(const_iterator __p);
801 iterator erase_after(const_iterator __f, const_iterator __l);
803 _LIBCPP_INLINE_VISIBILITY
804 void swap(forward_list& __x)
805 #if _LIBCPP_STD_VER >= 14
808 _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
809 __is_nothrow_swappable<__node_allocator>::value)
813 void resize(size_type __n);
814 void resize(size_type __n, const value_type& __v);
815 _LIBCPP_INLINE_VISIBILITY
816 void clear() _NOEXCEPT {base::clear();}
818 _LIBCPP_INLINE_VISIBILITY
819 void splice_after(const_iterator __p, forward_list&& __x);
820 _LIBCPP_INLINE_VISIBILITY
821 void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
822 _LIBCPP_INLINE_VISIBILITY
823 void splice_after(const_iterator __p, forward_list&& __x,
824 const_iterator __f, const_iterator __l);
825 void splice_after(const_iterator __p, forward_list& __x);
826 void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
827 void splice_after(const_iterator __p, forward_list& __x,
828 const_iterator __f, const_iterator __l);
829 __remove_return_type remove(const value_type& __v);
830 template <class _Predicate> __remove_return_type remove_if(_Predicate __pred);
831 _LIBCPP_INLINE_VISIBILITY
832 __remove_return_type unique() {return unique(__equal_to<value_type>());}
833 template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred);
834 #ifndef _LIBCPP_CXX03_LANG
835 _LIBCPP_INLINE_VISIBILITY
836 void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
837 template <class _Compare>
838 _LIBCPP_INLINE_VISIBILITY
839 void merge(forward_list&& __x, _Compare __comp)
840 {merge(__x, _VSTD::move(__comp));}
841 #endif // _LIBCPP_CXX03_LANG
842 _LIBCPP_INLINE_VISIBILITY
843 void merge(forward_list& __x) {merge(__x, __less<value_type>());}
844 template <class _Compare> void merge(forward_list& __x, _Compare __comp);
845 _LIBCPP_INLINE_VISIBILITY
846 void sort() {sort(__less<value_type>());}
847 template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
848 void reverse() _NOEXCEPT;
852 #ifndef _LIBCPP_CXX03_LANG
853 void __move_assign(forward_list& __x, true_type)
854 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
855 void __move_assign(forward_list& __x, false_type);
856 #endif // _LIBCPP_CXX03_LANG
858 template <class _Compare>
861 __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
863 template <class _Compare>
866 __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
870 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
871 template<class _InputIterator,
872 class _Alloc = typename std::allocator<typename iterator_traits<_InputIterator>::value_type>,
873 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
875 forward_list(_InputIterator, _InputIterator)
876 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
878 template<class _InputIterator,
880 class = typename enable_if<__is_allocator<_Alloc>::value, void>::type
882 forward_list(_InputIterator, _InputIterator, _Alloc)
883 -> forward_list<typename iterator_traits<_InputIterator>::value_type, _Alloc>;
886 template <class _Tp, class _Alloc>
888 forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
893 template <class _Tp, class _Alloc>
894 forward_list<_Tp, _Alloc>::forward_list(size_type __n)
898 __node_allocator& __a = base::__alloc();
899 typedef __allocator_destructor<__node_allocator> _Dp;
900 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
901 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
902 __p = __p->__next_as_begin())
904 __h.reset(__node_traits::allocate(__a, 1));
905 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
906 __h->__next_ = nullptr;
907 __p->__next_ = __h.release();
912 #if _LIBCPP_STD_VER > 11
913 template <class _Tp, class _Alloc>
914 forward_list<_Tp, _Alloc>::forward_list(size_type __n,
915 const allocator_type& __base_alloc)
916 : base ( __base_alloc )
920 __node_allocator& __a = base::__alloc();
921 typedef __allocator_destructor<__node_allocator> _Dp;
922 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
923 for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n,
924 __p = __p->__next_as_begin())
926 __h.reset(__node_traits::allocate(__a, 1));
927 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
928 __h->__next_ = nullptr;
929 __p->__next_ = __h.release();
935 template <class _Tp, class _Alloc>
936 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
938 insert_after(cbefore_begin(), __n, __v);
941 template <class _Tp, class _Alloc>
942 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
943 const allocator_type& __a)
946 insert_after(cbefore_begin(), __n, __v);
949 template <class _Tp, class _Alloc>
950 template <class _InputIterator>
951 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
953 __is_input_iterator<_InputIterator>::value
956 insert_after(cbefore_begin(), __f, __l);
959 template <class _Tp, class _Alloc>
960 template <class _InputIterator>
961 forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
962 const allocator_type& __a,
964 __is_input_iterator<_InputIterator>::value
968 insert_after(cbefore_begin(), __f, __l);
971 template <class _Tp, class _Alloc>
972 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
974 __node_traits::select_on_container_copy_construction(__x.__alloc())) {
975 insert_after(cbefore_begin(), __x.begin(), __x.end());
978 template <class _Tp, class _Alloc>
979 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
980 const allocator_type& __a)
983 insert_after(cbefore_begin(), __x.begin(), __x.end());
986 template <class _Tp, class _Alloc>
987 forward_list<_Tp, _Alloc>&
988 forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
992 base::__copy_assign_alloc(__x);
993 assign(__x.begin(), __x.end());
998 #ifndef _LIBCPP_CXX03_LANG
999 template <class _Tp, class _Alloc>
1000 forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
1001 const allocator_type& __a)
1002 : base(_VSTD::move(__x), __a)
1004 if (base::__alloc() != __x.__alloc())
1006 typedef move_iterator<iterator> _Ip;
1007 insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
1011 template <class _Tp, class _Alloc>
1012 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
1014 insert_after(cbefore_begin(), __il.begin(), __il.end());
1017 template <class _Tp, class _Alloc>
1018 forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
1019 const allocator_type& __a)
1022 insert_after(cbefore_begin(), __il.begin(), __il.end());
1025 template <class _Tp, class _Alloc>
1027 forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
1028 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
1031 base::__move_assign_alloc(__x);
1032 base::__before_begin()->__next_ = __x.__before_begin()->__next_;
1033 __x.__before_begin()->__next_ = nullptr;
1036 template <class _Tp, class _Alloc>
1038 forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
1040 if (base::__alloc() == __x.__alloc())
1041 __move_assign(__x, true_type());
1044 typedef move_iterator<iterator> _Ip;
1045 assign(_Ip(__x.begin()), _Ip(__x.end()));
1049 template <class _Tp, class _Alloc>
1051 forward_list<_Tp, _Alloc>&
1052 forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
1054 __node_traits::propagate_on_container_move_assignment::value &&
1055 is_nothrow_move_assignable<allocator_type>::value)
1057 __move_assign(__x, integral_constant<bool,
1058 __node_traits::propagate_on_container_move_assignment::value>());
1062 template <class _Tp, class _Alloc>
1064 forward_list<_Tp, _Alloc>&
1065 forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
1067 assign(__il.begin(), __il.end());
1071 #endif // _LIBCPP_CXX03_LANG
1073 template <class _Tp, class _Alloc>
1074 template <class _InputIterator>
1077 __is_input_iterator<_InputIterator>::value,
1080 forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
1082 iterator __i = before_begin();
1083 iterator __j = _VSTD::next(__i);
1084 iterator __e = end();
1085 for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
1088 insert_after(__i, __f, __l);
1090 erase_after(__i, __e);
1093 template <class _Tp, class _Alloc>
1095 forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
1097 iterator __i = before_begin();
1098 iterator __j = _VSTD::next(__i);
1099 iterator __e = end();
1100 for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
1103 insert_after(__i, __n, __v);
1105 erase_after(__i, __e);
1108 #ifndef _LIBCPP_CXX03_LANG
1110 template <class _Tp, class _Alloc>
1113 forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
1115 assign(__il.begin(), __il.end());
1118 template <class _Tp, class _Alloc>
1119 template <class... _Args>
1120 #if _LIBCPP_STD_VER > 14
1121 typename forward_list<_Tp, _Alloc>::reference
1125 forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
1127 __node_allocator& __a = base::__alloc();
1128 typedef __allocator_destructor<__node_allocator> _Dp;
1129 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1130 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1131 _VSTD::forward<_Args>(__args)...);
1132 __h->__next_ = base::__before_begin()->__next_;
1133 base::__before_begin()->__next_ = __h.release();
1134 #if _LIBCPP_STD_VER > 14
1135 return base::__before_begin()->__next_->__value_;
1139 template <class _Tp, class _Alloc>
1141 forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
1143 __node_allocator& __a = base::__alloc();
1144 typedef __allocator_destructor<__node_allocator> _Dp;
1145 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1146 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1147 __h->__next_ = base::__before_begin()->__next_;
1148 base::__before_begin()->__next_ = __h.release();
1151 #endif // _LIBCPP_CXX03_LANG
1153 template <class _Tp, class _Alloc>
1155 forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
1157 __node_allocator& __a = base::__alloc();
1158 typedef __allocator_destructor<__node_allocator> _Dp;
1159 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1160 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1161 __h->__next_ = base::__before_begin()->__next_;
1162 base::__before_begin()->__next_ = __h.release();
1165 template <class _Tp, class _Alloc>
1167 forward_list<_Tp, _Alloc>::pop_front()
1169 __node_allocator& __a = base::__alloc();
1170 __node_pointer __p = base::__before_begin()->__next_;
1171 base::__before_begin()->__next_ = __p->__next_;
1172 __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
1173 __node_traits::deallocate(__a, __p, 1);
1176 #ifndef _LIBCPP_CXX03_LANG
1178 template <class _Tp, class _Alloc>
1179 template <class... _Args>
1180 typename forward_list<_Tp, _Alloc>::iterator
1181 forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
1183 __begin_node_pointer const __r = __p.__get_begin();
1184 __node_allocator& __a = base::__alloc();
1185 typedef __allocator_destructor<__node_allocator> _Dp;
1186 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1187 __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
1188 _VSTD::forward<_Args>(__args)...);
1189 __h->__next_ = __r->__next_;
1190 __r->__next_ = __h.release();
1191 return iterator(__r->__next_);
1194 template <class _Tp, class _Alloc>
1195 typename forward_list<_Tp, _Alloc>::iterator
1196 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
1198 __begin_node_pointer const __r = __p.__get_begin();
1199 __node_allocator& __a = base::__alloc();
1200 typedef __allocator_destructor<__node_allocator> _Dp;
1201 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1202 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
1203 __h->__next_ = __r->__next_;
1204 __r->__next_ = __h.release();
1205 return iterator(__r->__next_);
1208 #endif // _LIBCPP_CXX03_LANG
1210 template <class _Tp, class _Alloc>
1211 typename forward_list<_Tp, _Alloc>::iterator
1212 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
1214 __begin_node_pointer const __r = __p.__get_begin();
1215 __node_allocator& __a = base::__alloc();
1216 typedef __allocator_destructor<__node_allocator> _Dp;
1217 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1218 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1219 __h->__next_ = __r->__next_;
1220 __r->__next_ = __h.release();
1221 return iterator(__r->__next_);
1224 template <class _Tp, class _Alloc>
1225 typename forward_list<_Tp, _Alloc>::iterator
1226 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
1227 const value_type& __v)
1229 __begin_node_pointer __r = __p.__get_begin();
1232 __node_allocator& __a = base::__alloc();
1233 typedef __allocator_destructor<__node_allocator> _Dp;
1234 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1235 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1236 __node_pointer __first = __h.release();
1237 __node_pointer __last = __first;
1238 #ifndef _LIBCPP_NO_EXCEPTIONS
1241 #endif // _LIBCPP_NO_EXCEPTIONS
1242 for (--__n; __n != 0; --__n, __last = __last->__next_)
1244 __h.reset(__node_traits::allocate(__a, 1));
1245 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1246 __last->__next_ = __h.release();
1248 #ifndef _LIBCPP_NO_EXCEPTIONS
1252 while (__first != nullptr)
1254 __node_pointer __next = __first->__next_;
1255 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1256 __node_traits::deallocate(__a, __first, 1);
1261 #endif // _LIBCPP_NO_EXCEPTIONS
1262 __last->__next_ = __r->__next_;
1263 __r->__next_ = __first;
1264 __r = static_cast<__begin_node_pointer>(__last);
1266 return iterator(__r);
1269 template <class _Tp, class _Alloc>
1270 template <class _InputIterator>
1273 __is_input_iterator<_InputIterator>::value,
1274 typename forward_list<_Tp, _Alloc>::iterator
1276 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
1277 _InputIterator __f, _InputIterator __l)
1279 __begin_node_pointer __r = __p.__get_begin();
1282 __node_allocator& __a = base::__alloc();
1283 typedef __allocator_destructor<__node_allocator> _Dp;
1284 unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
1285 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1286 __node_pointer __first = __h.release();
1287 __node_pointer __last = __first;
1288 #ifndef _LIBCPP_NO_EXCEPTIONS
1291 #endif // _LIBCPP_NO_EXCEPTIONS
1292 for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
1294 __h.reset(__node_traits::allocate(__a, 1));
1295 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
1296 __last->__next_ = __h.release();
1298 #ifndef _LIBCPP_NO_EXCEPTIONS
1302 while (__first != nullptr)
1304 __node_pointer __next = __first->__next_;
1305 __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
1306 __node_traits::deallocate(__a, __first, 1);
1311 #endif // _LIBCPP_NO_EXCEPTIONS
1312 __last->__next_ = __r->__next_;
1313 __r->__next_ = __first;
1314 __r = static_cast<__begin_node_pointer>(__last);
1316 return iterator(__r);
1319 template <class _Tp, class _Alloc>
1320 typename forward_list<_Tp, _Alloc>::iterator
1321 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
1323 __begin_node_pointer __p = __f.__get_begin();
1324 __node_pointer __n = __p->__next_;
1325 __p->__next_ = __n->__next_;
1326 __node_allocator& __a = base::__alloc();
1327 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1328 __node_traits::deallocate(__a, __n, 1);
1329 return iterator(__p->__next_);
1332 template <class _Tp, class _Alloc>
1333 typename forward_list<_Tp, _Alloc>::iterator
1334 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
1336 __node_pointer __e = __l.__get_unsafe_node_pointer();
1339 __begin_node_pointer __bp = __f.__get_begin();
1341 __node_pointer __n = __bp->__next_;
1344 __bp->__next_ = __e;
1345 __node_allocator& __a = base::__alloc();
1348 __node_pointer __tmp = __n->__next_;
1349 __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
1350 __node_traits::deallocate(__a, __n, 1);
1352 } while (__n != __e);
1355 return iterator(__e);
1358 template <class _Tp, class _Alloc>
1360 forward_list<_Tp, _Alloc>::resize(size_type __n)
1363 iterator __p = before_begin();
1364 iterator __i = begin();
1365 iterator __e = end();
1366 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1369 erase_after(__p, __e);
1375 __node_allocator& __a = base::__alloc();
1376 typedef __allocator_destructor<__node_allocator> _Dp;
1377 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
1378 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1379 __ptr = __ptr->__next_as_begin())
1381 __h.reset(__node_traits::allocate(__a, 1));
1382 __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
1383 __h->__next_ = nullptr;
1384 __ptr->__next_ = __h.release();
1390 template <class _Tp, class _Alloc>
1392 forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
1395 iterator __p = before_begin();
1396 iterator __i = begin();
1397 iterator __e = end();
1398 for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
1401 erase_after(__p, __e);
1407 __node_allocator& __a = base::__alloc();
1408 typedef __allocator_destructor<__node_allocator> _Dp;
1409 unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
1410 for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n,
1411 __ptr = __ptr->__next_as_begin())
1413 __h.reset(__node_traits::allocate(__a, 1));
1414 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
1415 __h->__next_ = nullptr;
1416 __ptr->__next_ = __h.release();
1422 template <class _Tp, class _Alloc>
1424 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1429 if (__p.__get_begin()->__next_ != nullptr)
1431 const_iterator __lm1 = __x.before_begin();
1432 while (__lm1.__get_begin()->__next_ != nullptr)
1434 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1436 __p.__get_begin()->__next_ = __x.__before_begin()->__next_;
1437 __x.__before_begin()->__next_ = nullptr;
1441 template <class _Tp, class _Alloc>
1443 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1444 forward_list& /*__other*/,
1447 const_iterator __lm1 = _VSTD::next(__i);
1448 if (__p != __i && __p != __lm1)
1450 __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_;
1451 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1452 __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer();
1456 template <class _Tp, class _Alloc>
1458 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1459 forward_list& /*__other*/,
1460 const_iterator __f, const_iterator __l)
1462 if (__f != __l && __p != __f)
1464 const_iterator __lm1 = __f;
1465 while (__lm1.__get_begin()->__next_ != __l.__get_begin())
1469 __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_;
1470 __p.__get_begin()->__next_ = __f.__get_begin()->__next_;
1471 __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer();
1476 template <class _Tp, class _Alloc>
1477 inline _LIBCPP_INLINE_VISIBILITY
1479 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1482 splice_after(__p, __x);
1485 template <class _Tp, class _Alloc>
1486 inline _LIBCPP_INLINE_VISIBILITY
1488 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1492 splice_after(__p, __x, __i);
1495 template <class _Tp, class _Alloc>
1496 inline _LIBCPP_INLINE_VISIBILITY
1498 forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
1500 const_iterator __f, const_iterator __l)
1502 splice_after(__p, __x, __f, __l);
1505 template <class _Tp, class _Alloc>
1506 typename forward_list<_Tp, _Alloc>::__remove_return_type
1507 forward_list<_Tp, _Alloc>::remove(const value_type& __v)
1509 forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
1510 typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1511 const iterator __e = end();
1512 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
1514 if (__i.__get_begin()->__next_->__value_ == __v)
1517 iterator __j = _VSTD::next(__i, 2);
1518 for (; __j != __e && *__j == __v; ++__j)
1520 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1529 return (__remove_return_type) __count_removed;
1532 template <class _Tp, class _Alloc>
1533 template <class _Predicate>
1534 typename forward_list<_Tp, _Alloc>::__remove_return_type
1535 forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
1537 forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
1538 typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1539 const iterator __e = end();
1540 for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
1542 if (__pred(__i.__get_begin()->__next_->__value_))
1545 iterator __j = _VSTD::next(__i, 2);
1546 for (; __j != __e && __pred(*__j); ++__j)
1548 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1557 return (__remove_return_type) __count_removed;
1560 template <class _Tp, class _Alloc>
1561 template <class _BinaryPredicate>
1562 typename forward_list<_Tp, _Alloc>::__remove_return_type
1563 forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
1565 forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
1566 typename forward_list<_Tp, _Alloc>::size_type __count_removed = 0;
1567 for (iterator __i = begin(), __e = end(); __i != __e;)
1569 iterator __j = _VSTD::next(__i);
1570 for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
1572 if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
1573 __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
1577 return (__remove_return_type) __count_removed;
1580 template <class _Tp, class _Alloc>
1581 template <class _Compare>
1583 forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
1587 base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
1588 __x.__before_begin()->__next_,
1590 __x.__before_begin()->__next_ = nullptr;
1594 template <class _Tp, class _Alloc>
1595 template <class _Compare>
1596 typename forward_list<_Tp, _Alloc>::__node_pointer
1597 forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
1600 if (__f1 == nullptr)
1602 if (__f2 == nullptr)
1605 if (__comp(__f2->__value_, __f1->__value_))
1607 __node_pointer __t = __f2;
1608 while (__t->__next_ != nullptr &&
1609 __comp(__t->__next_->__value_, __f1->__value_))
1612 __f2 = __t->__next_;
1613 __t->__next_ = __f1;
1617 __node_pointer __p = __f1;
1618 __f1 = __f1->__next_;
1619 while (__f1 != nullptr && __f2 != nullptr)
1621 if (__comp(__f2->__value_, __f1->__value_))
1623 __node_pointer __t = __f2;
1624 while (__t->__next_ != nullptr &&
1625 __comp(__t->__next_->__value_, __f1->__value_))
1627 __p->__next_ = __f2;
1628 __f2 = __t->__next_;
1629 __t->__next_ = __f1;
1632 __f1 = __f1->__next_;
1634 if (__f2 != nullptr)
1635 __p->__next_ = __f2;
1639 template <class _Tp, class _Alloc>
1640 template <class _Compare>
1643 forward_list<_Tp, _Alloc>::sort(_Compare __comp)
1645 base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
1646 _VSTD::distance(begin(), end()), __comp);
1649 template <class _Tp, class _Alloc>
1650 template <class _Compare>
1651 typename forward_list<_Tp, _Alloc>::__node_pointer
1652 forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
1661 if (__comp(__f1->__next_->__value_, __f1->__value_))
1663 __node_pointer __t = __f1->__next_;
1664 __t->__next_ = __f1;
1665 __f1->__next_ = nullptr;
1670 difference_type __sz1 = __sz / 2;
1671 difference_type __sz2 = __sz - __sz1;
1672 __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer();
1673 __node_pointer __f2 = __t->__next_;
1674 __t->__next_ = nullptr;
1675 return __merge(__sort(__f1, __sz1, __comp),
1676 __sort(__f2, __sz2, __comp), __comp);
1679 template <class _Tp, class _Alloc>
1681 forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
1683 __node_pointer __p = base::__before_begin()->__next_;
1686 __node_pointer __f = __p->__next_;
1687 __p->__next_ = nullptr;
1688 while (__f != nullptr)
1690 __node_pointer __t = __f->__next_;
1695 base::__before_begin()->__next_ = __p;
1699 template <class _Tp, class _Alloc>
1700 bool operator==(const forward_list<_Tp, _Alloc>& __x,
1701 const forward_list<_Tp, _Alloc>& __y)
1703 typedef forward_list<_Tp, _Alloc> _Cp;
1704 typedef typename _Cp::const_iterator _Ip;
1705 _Ip __ix = __x.begin();
1706 _Ip __ex = __x.end();
1707 _Ip __iy = __y.begin();
1708 _Ip __ey = __y.end();
1709 for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
1710 if (!(*__ix == *__iy))
1712 return (__ix == __ex) == (__iy == __ey);
1715 template <class _Tp, class _Alloc>
1716 inline _LIBCPP_INLINE_VISIBILITY
1717 bool operator!=(const forward_list<_Tp, _Alloc>& __x,
1718 const forward_list<_Tp, _Alloc>& __y)
1720 return !(__x == __y);
1723 template <class _Tp, class _Alloc>
1724 inline _LIBCPP_INLINE_VISIBILITY
1725 bool operator< (const forward_list<_Tp, _Alloc>& __x,
1726 const forward_list<_Tp, _Alloc>& __y)
1728 return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
1729 __y.begin(), __y.end());
1732 template <class _Tp, class _Alloc>
1733 inline _LIBCPP_INLINE_VISIBILITY
1734 bool operator> (const forward_list<_Tp, _Alloc>& __x,
1735 const forward_list<_Tp, _Alloc>& __y)
1740 template <class _Tp, class _Alloc>
1741 inline _LIBCPP_INLINE_VISIBILITY
1742 bool operator>=(const forward_list<_Tp, _Alloc>& __x,
1743 const forward_list<_Tp, _Alloc>& __y)
1745 return !(__x < __y);
1748 template <class _Tp, class _Alloc>
1749 inline _LIBCPP_INLINE_VISIBILITY
1750 bool operator<=(const forward_list<_Tp, _Alloc>& __x,
1751 const forward_list<_Tp, _Alloc>& __y)
1753 return !(__y < __x);
1756 template <class _Tp, class _Alloc>
1757 inline _LIBCPP_INLINE_VISIBILITY
1759 swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
1760 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1765 #if _LIBCPP_STD_VER > 17
1766 template <class _Tp, class _Allocator, class _Predicate>
1767 inline _LIBCPP_INLINE_VISIBILITY
1768 void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred)
1769 { __c.remove_if(__pred); }
1771 template <class _Tp, class _Allocator, class _Up>
1772 inline _LIBCPP_INLINE_VISIBILITY
1773 void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v)
1774 { _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
1777 _LIBCPP_END_NAMESPACE_STD
1781 #endif // _LIBCPP_FORWARD_LIST