// -*- C++ -*- //===----------------------- forward_list ---------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_FORWARD_LIST #define _LIBCPP_FORWARD_LIST /* forward_list synopsis namespace std { template > class forward_list { public: typedef T value_type; typedef Allocator allocator_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename allocator_traits::pointer pointer; typedef typename allocator_traits::const_pointer const_pointer; typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::difference_type difference_type; typedef
iterator; typedef
const_iterator; forward_list(); explicit forward_list(const allocator_type& a); explicit forward_list(size_type n); forward_list(size_type n, const value_type& v); forward_list(size_type n, const value_type& v, const allocator_type& a); template forward_list(InputIterator first, InputIterator last); template forward_list(InputIterator first, InputIterator last, const allocator_type& a); forward_list(const forward_list& x); forward_list(const forward_list& x, const allocator_type& a); forward_list(forward_list&& x); forward_list(forward_list&& x, const allocator_type& a); forward_list(initializer_list il); forward_list(initializer_list il, const allocator_type& a); ~forward_list(); forward_list& operator=(const forward_list& x); forward_list& operator=(forward_list&& x); forward_list& operator=(initializer_list il); template void assign(InputIterator first, InputIterator last); void assign(size_type n, const value_type& v); void assign(initializer_list il); allocator_type get_allocator() const; iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; const_iterator cbegin() const; const_iterator cend() const; iterator before_begin(); const_iterator before_begin() const; const_iterator cbefore_begin() const; bool empty() const; size_type max_size() const; reference front(); const_reference front() const; template void emplace_front(Args&&... args); void push_front(const value_type& v); void push_front(value_type&& v); void pop_front(); template iterator emplace_after(const_iterator p, Args&&... args); iterator insert_after(const_iterator p, const value_type& v); iterator insert_after(const_iterator p, value_type&& v); iterator insert_after(const_iterator p, size_type n, const value_type& v); template iterator insert_after(const_iterator p, InputIterator first, InputIterator last); iterator insert_after(const_iterator p, initializer_list il); void erase_after(const_iterator p); void erase_after(const_iterator first, const_iterator last); void swap(forward_list& x); void resize(size_type n); void resize(size_type n, const value_type& v); void clear(); void splice_after(const_iterator p, forward_list&& x); void splice_after(const_iterator p, forward_list&& x, const_iterator i); void splice_after(const_iterator p, forward_list&& x, const_iterator first, const_iterator last); void remove(const value_type& v); template void remove_if(Predicate pred); void unique(); template void unique(BinaryPredicate binary_pred); void merge(forward_list&& x); template void merge(forward_list&& x, Compare comp); void sort(); template void sort(Compare comp); void reverse(); }; template bool operator==(const forward_list& x, const forward_list& y); template bool operator< (const forward_list& x, const forward_list& y); template bool operator!=(const forward_list& x, const forward_list& y); template bool operator> (const forward_list& x, const forward_list& y); template bool operator>=(const forward_list& x, const forward_list& y); template bool operator<=(const forward_list& x, const forward_list& y); template void swap(forward_list& x, forward_list& y); } // std */ #include <__config> #include #include #include #include #include #pragma GCC system_header _LIBCPP_BEGIN_NAMESPACE_STD template struct __forward_list_node; template struct __forward_begin_node { typedef __forward_begin_node __self; typedef _NodePtr pointer; pointer __next_; __forward_begin_node() : __next_(nullptr) {} }; template struct __forward_list_node : public __forward_begin_node < typename pointer_traits<_VoidPtr>::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES rebind<__forward_list_node<_Tp, _VoidPtr> > #else rebind<__forward_list_node<_Tp, _VoidPtr> >::other #endif > { typedef _Tp value_type; value_type __value_; }; template class forward_list; template class __forward_list_const_iterator; template class __forward_list_iterator { typedef _NodePtr __node_pointer; __node_pointer __ptr_; explicit __forward_list_iterator(__node_pointer __p) : __ptr_(__p) {} template friend class forward_list; template friend class __forward_list_const_iterator; public: typedef forward_iterator_tag iterator_category; typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type; typedef value_type& reference; typedef typename pointer_traits<__node_pointer>::difference_type difference_type; typedef typename pointer_traits<__node_pointer>::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES rebind #else rebind::other #endif pointer; __forward_list_iterator() : __ptr_(nullptr) {} reference operator*() const {return __ptr_->__value_;} pointer operator->() const {return &__ptr_->__value_;} __forward_list_iterator& operator++() { __ptr_ = __ptr_->__next_; return *this; } __forward_list_iterator operator++(int) { __forward_list_iterator __t(*this); ++(*this); return __t; } friend bool operator==(const __forward_list_iterator& __x, const __forward_list_iterator& __y) {return __x.__ptr_ == __y.__ptr_;} friend bool operator!=(const __forward_list_iterator& __x, const __forward_list_iterator& __y) {return !(__x == __y);} }; template class __forward_list_const_iterator { typedef _NodeConstPtr __node_const_pointer; __node_const_pointer __ptr_; explicit __forward_list_const_iterator(__node_const_pointer __p) : __ptr_(__p) {} typedef typename remove_const < typename pointer_traits<__node_const_pointer>::element_type >::type __node; typedef typename pointer_traits<__node_const_pointer>::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES rebind<__node> #else rebind<__node>::other #endif __node_pointer; template friend class forward_list; public: typedef forward_iterator_tag iterator_category; typedef typename __node::value_type value_type; typedef const value_type& reference; typedef typename pointer_traits<__node_const_pointer>::difference_type difference_type; typedef typename pointer_traits<__node_const_pointer>::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES rebind #else rebind::other #endif pointer; __forward_list_const_iterator() : __ptr_(nullptr) {} __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) : __ptr_(__p.__ptr_) {} reference operator*() const {return __ptr_->__value_;} pointer operator->() const {return &__ptr_->__value_;} __forward_list_const_iterator& operator++() { __ptr_ = __ptr_->__next_; return *this; } __forward_list_const_iterator operator++(int) { __forward_list_const_iterator __t(*this); ++(*this); return __t; } friend bool operator==(const __forward_list_const_iterator& __x, const __forward_list_const_iterator& __y) {return __x.__ptr_ == __y.__ptr_;} friend bool operator!=(const __forward_list_const_iterator& __x, const __forward_list_const_iterator& __y) {return !(__x == __y);} }; template class __forward_list_base { protected: typedef _Tp value_type; typedef _Alloc allocator_type; typedef typename allocator_traits::void_pointer void_pointer; typedef __forward_list_node __node; typedef typename __node::__self __begin_node; typedef typename allocator_traits::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES rebind_alloc<__node> #else rebind_alloc<__node>::other #endif __node_allocator; typedef allocator_traits<__node_allocator> __node_traits; typedef typename __node_traits::pointer __node_pointer; typedef typename __node_traits::const_pointer __node_const_pointer; __compressed_pair<__begin_node, __node_allocator> __before_begin_; __node_pointer __before_begin() {return pointer_traits<__node_pointer>::pointer_to( static_cast<__node&>(__before_begin_.first()));} __node_const_pointer __before_begin() const {return pointer_traits<__node_const_pointer>::pointer_to( static_cast(__before_begin_.first()));} __node_allocator& __alloc() {return __before_begin_.second();} const __node_allocator& __alloc() const {return __before_begin_.second();} typedef __forward_list_iterator<__node_pointer> iterator; typedef __forward_list_const_iterator<__node_const_pointer> const_iterator; __forward_list_base() : __before_begin_(__begin_node()) {} __forward_list_base(const allocator_type& __a) : __before_begin_(__begin_node(), __node_allocator(__a)) {} #ifdef _LIBCPP_MOVE __forward_list_base(__forward_list_base&& __x); __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); #endif private: __forward_list_base(const __forward_list_base&); __forward_list_base& operator=(const __forward_list_base&); protected: ~__forward_list_base(); void __copy_assign_alloc(const __forward_list_base& __x) {__copy_assign_alloc(__x, integral_constant());} void __move_assign_alloc(__forward_list_base& __x) {__move_assign_alloc(__x, integral_constant());} void swap(__forward_list_base& __x); void clear(); private: void __copy_assign_alloc(const __forward_list_base&, false_type) {} void __copy_assign_alloc(const __forward_list_base& __x, true_type) { if (__alloc() != __x.__alloc()) clear(); __alloc() = __x.__alloc(); } void __move_assign_alloc(__forward_list_base& __x, false_type) {} void __move_assign_alloc(__forward_list_base& __x, true_type) {__alloc() = _STD::move(__x.__alloc());} static void __swap_alloc(__node_allocator& __x, __node_allocator& __y) {__swap_alloc(__x, __y, integral_constant());} static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type) {} static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type) { using _STD::swap; swap(__x, __y); } }; #ifdef _LIBCPP_MOVE template inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) : __before_begin_(_STD::move(__x.__before_begin_)) { __x.__before_begin()->__next_ = nullptr; } template inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, const allocator_type& __a) : __before_begin_(__begin_node(), __node_allocator(__a)) { if (__alloc() == __x.__alloc()) { __before_begin()->__next_ = __x.__before_begin()->__next_; __x.__before_begin()->__next_ = nullptr; } } #endif template __forward_list_base<_Tp, _Alloc>::~__forward_list_base() { clear(); } template inline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) { __swap_alloc(__alloc(), __x.__alloc()); using _STD::swap; swap(__before_begin()->__next_, __x.__before_begin()->__next_); } template void __forward_list_base<_Tp, _Alloc>::clear() { __node_allocator& __a = __alloc(); for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;) { __node_pointer __next = __p->__next_; __node_traits::destroy(__a, addressof(__p->__value_)); __node_traits::deallocate(__a, __p, 1); __p = __next; } __before_begin()->__next_ = nullptr; } template > class forward_list : private __forward_list_base<_Tp, _Alloc> { typedef __forward_list_base<_Tp, _Alloc> base; public: typedef _Tp value_type; typedef _Alloc allocator_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename allocator_traits::pointer pointer; typedef typename allocator_traits::const_pointer const_pointer; typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::difference_type difference_type; typedef typename base::iterator iterator; typedef typename base::const_iterator const_iterator; forward_list() {} // = default; explicit forward_list(const allocator_type& __a); explicit forward_list(size_type __n); forward_list(size_type __n, const value_type& __v); forward_list(size_type __n, const value_type& __v, const allocator_type& __a); template forward_list(_InputIterator __f, _InputIterator __l, typename enable_if< __is_input_iterator<_InputIterator>::value >::type* = nullptr); template forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a, typename enable_if< __is_input_iterator<_InputIterator>::value >::type* = nullptr); forward_list(const forward_list& __x); forward_list(const forward_list& __x, const allocator_type& __a); #ifdef _LIBCPP_MOVE forward_list(forward_list&& __x) : base(_STD::move(__x)) {} forward_list(forward_list&& __x, const allocator_type& __a); #endif forward_list(initializer_list __il); forward_list(initializer_list __il, const allocator_type& __a); // ~forward_list() = default; forward_list& operator=(const forward_list& __x); #ifdef _LIBCPP_MOVE forward_list& operator=(forward_list&& __x); #endif forward_list& operator=(initializer_list __il); template typename enable_if < __is_input_iterator<_InputIterator>::value, void >::type assign(_InputIterator __f, _InputIterator __l); void assign(size_type __n, const value_type& __v); void assign(initializer_list __il); allocator_type get_allocator() const {return allocator_type(base::__alloc());} iterator begin() {return iterator(base::__before_begin()->__next_);} const_iterator begin() const {return const_iterator(base::__before_begin()->__next_);} iterator end() {return iterator(nullptr);} const_iterator end() const {return const_iterator(nullptr);} const_iterator cbegin() const {return const_iterator(base::__before_begin()->__next_);} const_iterator cend() const {return const_iterator(nullptr);} iterator before_begin() {return iterator(base::__before_begin());} const_iterator before_begin() const {return const_iterator(base::__before_begin());} const_iterator cbefore_begin() const {return const_iterator(base::__before_begin());} bool empty() const {return base::__before_begin()->__next_ == nullptr;} size_type max_size() const {return numeric_limits::max();} reference front() {return base::__before_begin()->__next_->__value_;} const_reference front() const {return base::__before_begin()->__next_->__value_;} #ifdef _LIBCPP_MOVE template void emplace_front(_Args&&... __args); void push_front(value_type&& __v); #endif void push_front(const value_type& __v); void pop_front(); #ifdef _LIBCPP_MOVE template iterator emplace_after(const_iterator __p, _Args&&... __args); iterator insert_after(const_iterator __p, value_type&& __v); #endif iterator insert_after(const_iterator __p, const value_type& __v); iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); template typename enable_if < __is_input_iterator<_InputIterator>::value, iterator >::type insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); iterator insert_after(const_iterator __p, initializer_list __il) {return insert_after(__p, __il.begin(), __il.end());} void erase_after(const_iterator __p); void erase_after(const_iterator __f, const_iterator __l); void swap(forward_list& __x) {base::swap(__x);} void resize(size_type __n); void resize(size_type __n, const value_type& __v); void clear() {base::clear();} #ifdef _LIBCPP_MOVE void splice_after(const_iterator __p, forward_list&& __x); void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i); void splice_after(const_iterator __p, forward_list&& __x, const_iterator __f, const_iterator __l); #else void splice_after(const_iterator __p, forward_list& __x); void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); void splice_after(const_iterator __p, forward_list& __x, const_iterator __f, const_iterator __l); #endif void remove(const value_type& __v); template void remove_if(_Predicate __pred); void unique() {unique(__equal_to());} template void unique(_BinaryPredicate __binary_pred); #ifdef _LIBCPP_MOVE void merge(forward_list&& __x) {merge(_STD::move(__x), __less());} template void merge(forward_list&& __x, _Compare __comp); #else void merge(forward_list& __x) {merge(__x, __less());} template void merge(forward_list& __x, _Compare __comp); #endif void sort() {sort(__less());} template void sort(_Compare __comp); void reverse(); private: typedef typename base::__node_allocator __node_allocator; typedef typename base::__node __node; typedef typename base::__node_traits __node_traits; typedef typename base::__node_pointer __node_pointer; #ifdef _LIBCPP_MOVE void __move_assign(forward_list& __x, true_type); void __move_assign(forward_list& __x, false_type); #endif template static __node_pointer __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp); template static __node_pointer __sort(__node_pointer __f, difference_type __sz, _Compare& __comp); }; template inline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : base(__a) { } template forward_list<_Tp, _Alloc>::forward_list(size_type __n) { if (__n > 0) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(nullptr, _D(__a, 1)); for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_)); __h->__next_ = nullptr; __p->__next_ = __h.release(); } } } template forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) { insert_after(cbefore_begin(), __n, __v); } template forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) { insert_after(cbefore_begin(), __n, __v); } template template forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, typename enable_if< __is_input_iterator<_InputIterator>::value >::type*) { insert_after(cbefore_begin(), __f, __l); } template template forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a, typename enable_if< __is_input_iterator<_InputIterator>::value >::type*) : base(__a) { insert_after(cbefore_begin(), __f, __l); } template forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x) : base(allocator_type( __node_traits::select_on_container_copy_construction(__x.__alloc()) ) ) { insert_after(cbefore_begin(), __x.begin(), __x.end()); } template forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, const allocator_type& __a) : base(__a) { insert_after(cbefore_begin(), __x.begin(), __x.end()); } #ifdef _LIBCPP_MOVE template forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, const allocator_type& __a) : base(_STD::move(__x), __a) { if (base::__alloc() != __x.__alloc()) { typedef move_iterator _I; insert_after(cbefore_begin(), _I(__x.begin()), _I(__x.end())); } } #endif template forward_list<_Tp, _Alloc>::forward_list(initializer_list __il) { insert_after(cbefore_begin(), __il.begin(), __il.end()); } template forward_list<_Tp, _Alloc>::forward_list(initializer_list __il, const allocator_type& __a) : base(__a) { insert_after(cbefore_begin(), __il.begin(), __il.end()); } template forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) { if (this != &__x) { base::__copy_assign_alloc(__x); assign(__x.begin(), __x.end()); } return *this; } #ifdef _LIBCPP_MOVE template void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type) { clear(); base::__move_assign_alloc(__x); base::__before_begin()->__next_ = __x.__before_begin()->__next_; __x.__before_begin()->__next_ = nullptr; } template void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) { if (base::__alloc() == __x.__alloc()) __move_assign(__x, true_type()); else { typedef move_iterator _I; assign(_I(__x.begin()), _I(__x.end())); } } template inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) { __move_assign(__x, integral_constant()); return *this; } #endif template inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(initializer_list __il) { assign(__il.begin(), __il.end()); return *this; } template template typename enable_if < __is_input_iterator<_InputIterator>::value, void >::type forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) { iterator __i = before_begin(); iterator __j = next(__i); iterator __e = end(); for (; __j != __e && __f != __l; ++__i, ++__j, ++__f) *__j = *__f; if (__j == __e) insert_after(__i, __f, __l); else erase_after(__i, __e); } template void forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) { iterator __i = before_begin(); iterator __j = next(__i); iterator __e = end(); for (; __j != __e && __n > 0; --__n, ++__i, ++__j) *__j = __v; if (__j == __e) insert_after(__i, __n, __v); else erase_after(__i, __e); } template inline void forward_list<_Tp, _Alloc>::assign(initializer_list __il) { assign(__il.begin(), __il.end()); } #ifdef _LIBCPP_MOVE template template void forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), _STD::forward<_Args>(__args)...); __h->__next_ = base::__before_begin()->__next_; base::__before_begin()->__next_ = __h.release(); } template void forward_list<_Tp, _Alloc>::push_front(value_type&& __v) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), _STD::move(__v)); __h->__next_ = base::__before_begin()->__next_; base::__before_begin()->__next_ = __h.release(); } #endif template void forward_list<_Tp, _Alloc>::push_front(const value_type& __v) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), __v); __h->__next_ = base::__before_begin()->__next_; base::__before_begin()->__next_ = __h.release(); } template void forward_list<_Tp, _Alloc>::pop_front() { __node_allocator& __a = base::__alloc(); __node_pointer __p = base::__before_begin()->__next_; base::__before_begin()->__next_ = __p->__next_; __node_traits::destroy(__a, addressof(__p->__value_)); __node_traits::deallocate(__a, __p, 1); } #ifdef _LIBCPP_MOVE template template typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) { __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), _STD::forward<_Args>(__args)...); __h->__next_ = __r->__next_; __r->__next_ = __h.release(); return iterator(__r->__next_); } template typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) { __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), _STD::move(__v)); __h->__next_ = __r->__next_; __r->__next_ = __h.release(); return iterator(__r->__next_); } #endif template typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) { __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), __v); __h->__next_ = __r->__next_; __r->__next_ = __h.release(); return iterator(__r->__next_); } template typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, const value_type& __v) { __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_); if (__n > 0) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), __v); __node_pointer __first = __h.release(); __node_pointer __last = __first; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif for (--__n; __n != 0; --__n, __last = __last->__next_) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), __v); __last->__next_ = __h.release(); } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { while (__first != nullptr) { __node_pointer __next = __first->__next_; __node_traits::destroy(__a, addressof(__first->__value_)); __node_traits::deallocate(__a, __first, 1); __first = __next; } throw; } #endif __last->__next_ = __r->__next_; __r->__next_ = __first; __r = __last; } return iterator(__r); } template template typename enable_if < __is_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator >::type forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l) { __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_); if (__f != __l) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(__node_traits::allocate(__a, 1), _D(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), *__f); __node_pointer __first = __h.release(); __node_pointer __last = __first; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif for (++__f; __f != __l; ++__f, __last = __last->__next_) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), *__f); __last->__next_ = __h.release(); } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { while (__first != nullptr) { __node_pointer __next = __first->__next_; __node_traits::destroy(__a, addressof(__first->__value_)); __node_traits::deallocate(__a, __first, 1); __first = __next; } throw; } #endif __last->__next_ = __r->__next_; __r->__next_ = __first; __r = __last; } return iterator(__r); } template void forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) { __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_); __node_pointer __n = __p->__next_; __p->__next_ = __n->__next_; __node_allocator& __a = base::__alloc(); __node_traits::destroy(__a, addressof(__n->__value_)); __node_traits::deallocate(__a, __n, 1); } template void forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) { if (__f != __l) { __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_); __node_pointer __n = __p->__next_; __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_); if (__n != __e) { __p->__next_ = __e; __node_allocator& __a = base::__alloc(); do { __p = __n->__next_; __node_traits::destroy(__a, addressof(__n->__value_)); __node_traits::deallocate(__a, __n, 1); __n = __p; } while (__n != __e); } } } template void forward_list<_Tp, _Alloc>::resize(size_type __n) { size_type __sz = 0; iterator __p = before_begin(); iterator __i = begin(); iterator __e = end(); for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) ; if (__i != __e) erase_after(__p, __e); else { __n -= __sz; if (__n > 0) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(nullptr, _D(__a, 1)); for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, __ptr = __ptr->__next_) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_)); __h->__next_ = nullptr; __ptr->__next_ = __h.release(); } } } } template void forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) { size_type __sz = 0; iterator __p = before_begin(); iterator __i = begin(); iterator __e = end(); for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz) ; if (__i != __e) erase_after(__p, __e); else { __n -= __sz; if (__n > 0) { __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _D; unique_ptr<__node, _D> __h(nullptr, _D(__a, 1)); for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, __ptr = __ptr->__next_) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, addressof(__h->__value_), __v); __h->__next_ = nullptr; __ptr->__next_ = __h.release(); } } } } template void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, #ifdef _LIBCPP_MOVE forward_list&& __x) #else forward_list& __x) #endif { if (!__x.empty()) { if (__p.__ptr_->__next_ != nullptr) { const_iterator __lm1 = __x.before_begin(); while (__lm1.__ptr_->__next_ != nullptr) ++__lm1; const_cast<__node_pointer>(__lm1.__ptr_)->__next_ = const_cast<__node_pointer>(__p.__ptr_)->__next_; } const_cast<__node_pointer>(__p.__ptr_)->__next_ = const_cast<__node_pointer>(__x.__before_begin())->__next_; const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr; } } template void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, #ifdef _LIBCPP_MOVE forward_list&& __x, #else forward_list& __x, #endif const_iterator __i) { const_iterator __lm1 = next(__i); if (__p != __i && __p != __lm1) { const_cast<__node_pointer>(__i.__ptr_)->__next_ = const_cast<__node_pointer>(__lm1.__ptr_)->__next_; const_cast<__node_pointer>(__lm1.__ptr_)->__next_ = const_cast<__node_pointer>(__p.__ptr_)->__next_; const_cast<__node_pointer>(__p.__ptr_)->__next_ = const_cast<__node_pointer>(__lm1.__ptr_); } } template void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, #ifdef _LIBCPP_MOVE forward_list&& __x, #else forward_list& __x, #endif const_iterator __f, const_iterator __l) { if (__f != __l && __p != __f) { const_iterator __lm1 = __f; while (__lm1.__ptr_->__next_ != __l.__ptr_) ++__lm1; if (__f != __lm1) { const_cast<__node_pointer>(__lm1.__ptr_)->__next_ = const_cast<__node_pointer>(__p.__ptr_)->__next_; const_cast<__node_pointer>(__p.__ptr_)->__next_ = const_cast<__node_pointer>(__f.__ptr_)->__next_; const_cast<__node_pointer>(__f.__ptr_)->__next_ = const_cast<__node_pointer>(__l.__ptr_); } } } template void forward_list<_Tp, _Alloc>::remove(const value_type& __v) { iterator __e = end(); for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) { if (__i.__ptr_->__next_->__value_ == __v) { iterator __j = next(__i, 2); for (; __j != __e && *__j == __v; ++__j) ; erase_after(__i, __j); if (__j == __e) break; __i = __j; } else ++__i; } } template template void forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) { iterator __e = end(); for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) { if (__pred(__i.__ptr_->__next_->__value_)) { iterator __j = next(__i, 2); for (; __j != __e && __pred(*__j); ++__j) ; erase_after(__i, __j); if (__j == __e) break; __i = __j; } else ++__i; } } template template void forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) { for (iterator __i = begin(), __e = end(); __i != __e;) { iterator __j = next(__i); for (; __j != __e && __binary_pred(*__i, *__j); ++__j) ; if (__i.__ptr_->__next_ != __j.__ptr_) erase_after(__i, __j); __i = __j; } } template template void #ifdef _LIBCPP_MOVE forward_list<_Tp, _Alloc>::merge(forward_list&& __x, _Compare __comp) #else forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp) #endif { if (this != &__x) { base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_, __x.__before_begin()->__next_, __comp); __x.__before_begin()->__next_ = nullptr; } } template template typename forward_list<_Tp, _Alloc>::__node_pointer forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp) { if (__f1 == nullptr) return __f2; if (__f2 == nullptr) return __f1; __node_pointer __r; if (__comp(__f2->__value_, __f1->__value_)) { __node_pointer __t = __f2; while (__t->__next_ != nullptr && __comp(__t->__next_->__value_, __f1->__value_)) __t = __t->__next_; __r = __f2; __f2 = __t->__next_; __t->__next_ = __f1; } else __r = __f1; __node_pointer __p = __f1; __f1 = __f1->__next_; while (__f1 != nullptr && __f2 != nullptr) { if (__comp(__f2->__value_, __f1->__value_)) { __node_pointer __t = __f2; while (__t->__next_ != nullptr && __comp(__t->__next_->__value_, __f1->__value_)) __t = __t->__next_; __p->__next_ = __f2; __f2 = __t->__next_; __t->__next_ = __f1; } __p = __f1; __f1 = __f1->__next_; } if (__f2 != nullptr) __p->__next_ = __f2; return __r; } template template inline void forward_list<_Tp, _Alloc>::sort(_Compare __comp) { base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_, _STD::distance(begin(), end()), __comp); } template template typename forward_list<_Tp, _Alloc>::__node_pointer forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, _Compare& __comp) { switch (__sz) { case 0: case 1: return __f1; case 2: if (__comp(__f1->__next_->__value_, __f1->__value_)) { __node_pointer __t = __f1->__next_; __t->__next_ = __f1; __f1->__next_ = nullptr; __f1 = __t; } return __f1; } difference_type __sz1 = __sz / 2; difference_type __sz2 = __sz - __sz1; __node_pointer __t = next(iterator(__f1), __sz1 - 1).__ptr_; __node_pointer __f2 = __t->__next_; __t->__next_ = nullptr; return __merge(__sort(__f1, __sz1, __comp), __sort(__f2, __sz2, __comp), __comp); } template void forward_list<_Tp, _Alloc>::reverse() { __node_pointer __p = base::__before_begin()->__next_; if (__p != nullptr) { __node_pointer __f = __p->__next_; __p->__next_ = nullptr; while (__f != nullptr) { __node_pointer __t = __f->__next_; __f->__next_ = __p; __p = __f; __f = __t; } base::__before_begin()->__next_ = __p; } } template bool operator==(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) { typedef forward_list<_Tp, _Alloc> _C; typedef typename _C::const_iterator _I; _I __ix = __x.begin(); _I __ex = __x.end(); _I __iy = __y.begin(); _I __ey = __y.end(); for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy) if (!(*__ix == *__iy)) return false; return (__ix == __ex) == (__iy == __ey); } template inline bool operator!=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) { return !(__x == __y); } template inline bool operator< (const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) { return _STD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template inline bool operator> (const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) { return __y < __x; } template inline bool operator>=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) { return !(__x < __y); } template inline bool operator<=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) { return !(__y < __x); } template inline void swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) { __x.swap(__y); } _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FORWARD_LIST