X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Fstl%2Fstl%2F_slist.h;fp=include%2Fc%2B%2B%2Fstl%2Fstl%2F_slist.h;h=b0d941a802645b29577470a16d27a80b0f047779;hp=0000000000000000000000000000000000000000;hb=173d8903eb9d51a4ea7d7fa3e52dc86c9bb6d4f1;hpb=b024710fe2b60cd4a42a8993b61333d6cdb56ca3 diff --git a/include/c++/stl/stl/_slist.h b/include/c++/stl/stl/_slist.h new file mode 100644 index 0000000..b0d941a --- /dev/null +++ b/include/c++/stl/stl/_slist.h @@ -0,0 +1,906 @@ +/* + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Copyright (c) 1997 + * Moscow Center for SPARC Technology + * + * Copyright (c) 1999 + * Boris Fomitchev + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef _STLP_INTERNAL_SLIST_H +#define _STLP_INTERNAL_SLIST_H + +#ifndef _STLP_INTERNAL_ALGOBASE_H +# include +#endif + +#ifndef _STLP_INTERNAL_ALLOC_H +# include +#endif + +#ifndef _STLP_INTERNAL_ITERATOR_H +# include +#endif + +#ifndef _STLP_INTERNAL_CONSTRUCT_H +# include +#endif + +#ifndef _STLP_INTERNAL_FUNCTION_BASE_H +# include +#endif + +#ifndef _STLP_INTERNAL_SLIST_BASE_H +# include +#endif + +_STLP_BEGIN_NAMESPACE + +_STLP_MOVE_TO_PRIV_NAMESPACE + +template +class _Slist_node : public _Slist_node_base { +public: + _Tp _M_data; + __TRIVIAL_STUFF(_Slist_node) +}; + +struct _Slist_iterator_base { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef forward_iterator_tag iterator_category; + + _Slist_node_base *_M_node; + + _Slist_iterator_base(_Slist_node_base *__x) : _M_node(__x) {} + + void _M_incr() { + _M_node = _M_node->_M_next; + } +}; + +template +class _Slist_iterator : public _Slist_iterator_base { +public: + typedef typename _Traits::value_type value_type; + typedef typename _Traits::pointer pointer; + typedef typename _Traits::reference reference; + typedef forward_iterator_tag iterator_category; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef _Slist_iterator<_Tp, _Traits> _Self; + typedef typename _Traits::_NonConstTraits _NonConstTraits; + typedef _Slist_iterator<_Tp, _NonConstTraits> iterator; + typedef typename _Traits::_ConstTraits _ConstTraits; + typedef _Slist_iterator<_Tp, _ConstTraits> const_iterator; + + typedef _Slist_node _Node; + + explicit _Slist_iterator(_Slist_node_base *__x) : _Slist_iterator_base(__x) {} + _Slist_iterator() : _Slist_iterator_base(0) {} + //copy constructor for iterator and constructor from iterator for const_iterator + _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {} + + reference operator*() const { return __STATIC_CAST(_Node*, this->_M_node)->_M_data; } + + _STLP_DEFINE_ARROW_OPERATOR + + _Self& operator++() { + _M_incr(); + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + _M_incr(); + return __tmp; + } + + bool operator==(const_iterator __y ) const { + return this->_M_node == __y._M_node; + } + bool operator!=(const_iterator __y ) const { + return this->_M_node != __y._M_node; + } +}; + +#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) +_STLP_MOVE_TO_STD_NAMESPACE +template +struct __type_traits<_STLP_PRIV _Slist_iterator<_Tp, _Traits> > { + typedef __false_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __false_type is_POD_type; +}; +_STLP_MOVE_TO_PRIV_NAMESPACE +#endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ + +#if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES) +_STLP_MOVE_TO_STD_NAMESPACE +template +inline _Tp* _STLP_CALL value_type(const _STLP_PRIV _Slist_iterator<_Tp, _Traits>&) { return __STATIC_CAST(_Tp*, 0); } +inline ptrdiff_t* _STLP_CALL distance_type(const _STLP_PRIV _Slist_iterator_base&) { return 0; } +inline forward_iterator_tag _STLP_CALL iterator_category(const _STLP_PRIV _Slist_iterator_base&) { return forward_iterator_tag(); } +_STLP_MOVE_TO_PRIV_NAMESPACE +#endif /* OLD_QUERIES */ + +// Base class that encapsulates details of allocators and simplifies EH +template +class _Slist_base { +protected: + typedef _Slist_node<_Tp> _Node; + typedef typename _Alloc_traits<_Node,_Alloc>::allocator_type _M_node_allocator_type; + typedef _Slist_base<_Tp, _Alloc> _Self; + +public: + typedef _STLP_alloc_proxy<_Slist_node_base, _Node, _M_node_allocator_type> _AllocProxy; + + _STLP_FORCE_ALLOCATORS(_Tp, _Alloc) + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + + _Slist_base(const allocator_type& __a) : + _M_head(_STLP_CONVERT_ALLOCATOR(__a, _Node), _Slist_node_base() ) { + _M_head._M_data._M_next = 0; + } + _Slist_base(__move_source<_Self> src) : + _M_head(__move_source<_AllocProxy>(src.get()._M_head)) { + src.get()._M_head._M_data._M_next = 0; + } + ~_Slist_base() { _M_erase_after(&_M_head._M_data, 0); } + +protected: + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) { + _Node* __next = __STATIC_CAST(_Node*, __pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + _STLP_STD::_Destroy(&__next->_M_data); + _M_head.deallocate(__next,1); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + +public: + allocator_type get_allocator() const + { return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_head, _Tp); } + _AllocProxy _M_head; +}; + +#if defined (_STLP_USE_PTR_SPECIALIZATIONS) +# define slist _STLP_PTR_IMPL_NAME(slist) +#elif defined (_STLP_DEBUG) +# define slist _STLP_NON_DBG_NAME(slist) +#else +_STLP_MOVE_TO_STD_NAMESPACE +#endif + +template +class slist; + +#if !defined (slist) +_STLP_MOVE_TO_PRIV_NAMESPACE +#endif + +// helper functions to reduce code duplication +template +void _Slist_unique(slist<_Tp, _Alloc>& __that, _BinaryPredicate __binary_pred); + +template +void _Slist_merge(slist<_Tp, _Alloc>& __that, slist<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp); + +template +void _Slist_sort(slist<_Tp, _Alloc>& __that, _StrictWeakOrdering __comp); + +#if !defined (slist) +_STLP_MOVE_TO_STD_NAMESPACE +#endif + +template +class slist : protected _STLP_PRIV _Slist_base<_Tp,_Alloc> +#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (slist) + , public __stlport_class > +#endif +{ +private: + typedef _STLP_PRIV _Slist_base<_Tp,_Alloc> _Base; + typedef slist<_Tp,_Alloc> _Self; +public: + typedef _Tp value_type; + + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef forward_iterator_tag _Iterator_category; + + typedef _STLP_PRIV _Slist_iterator<_Tp, _Nonconst_traits<_Tp> > iterator; + typedef _STLP_PRIV _Slist_iterator<_Tp, _Const_traits<_Tp> > const_iterator; + + _STLP_FORCE_ALLOCATORS(_Tp, _Alloc) + typedef typename _Base::allocator_type allocator_type; + +private: + typedef _STLP_PRIV _Slist_node<_Tp> _Node; + typedef _STLP_PRIV _Slist_node_base _Node_base; + +#if !defined(_STLP_DONT_SUP_DFLT_PARAM) + _Node* _M_create_node(const value_type& __x = _Tp()) { +#else + _Node* _M_create_node(const value_type& __x) { +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + _Node* __node = this->_M_head.allocate(1); + _STLP_TRY { + _Copy_Construct(&__node->_M_data, __x); + __node->_M_next = 0; + } + _STLP_UNWIND(this->_M_head.deallocate(__node, 1)) + return __node; + } + +#if defined(_STLP_DONT_SUP_DFLT_PARAM) + _Node* _M_create_node() { + _Node* __node = this->_M_head.allocate(1); + _STLP_TRY { + _STLP_STD::_Construct(&__node->_M_data); + __node->_M_next = 0; + } + _STLP_UNWIND(this->_M_head.deallocate(__node, 1)) + return __node; + } +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + +public: + + allocator_type get_allocator() const { return _Base::get_allocator(); } + +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) + explicit slist(const allocator_type& __a = allocator_type()) +#else + slist() + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type()) {} + slist(const allocator_type& __a) +#endif + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a) {} + +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) + explicit slist(size_type __n, const value_type& __x = _STLP_DEFAULT_CONSTRUCTED(_Tp), + const allocator_type& __a = allocator_type()) +#else + explicit slist(size_type __n) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type()) + { _M_insert_after_fill(&this->_M_head._M_data, __n, _STLP_DEFAULT_CONSTRUCTED(_Tp)); } + slist(size_type __n, const value_type& __x) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type()) + { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); } + slist(size_type __n, const value_type& __x, const allocator_type& __a) +#endif + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a) + { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); } + +#if defined (_STLP_MEMBER_TEMPLATES) + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a) + { _M_insert_after_range(&this->_M_head._M_data, __first, __last); } +# if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) + // VC++ needs this crazyness + template + slist(_InputIterator __first, _InputIterator __last) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(allocator_type()) + { _M_insert_after_range(&this->_M_head._M_data, __first, __last); } +# endif +#else /* _STLP_MEMBER_TEMPLATES */ + slist(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type() ) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a) + { _M_insert_after_range(&this->_M_head._M_data, __first, __last); } + slist(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__a) + { _M_insert_after_range(&this->_M_head._M_data, __first, __last); } +#endif /* _STLP_MEMBER_TEMPLATES */ + + slist(const _Self& __x) + : _STLP_PRIV _Slist_base<_Tp,_Alloc>(__x.get_allocator()) + { _M_insert_after_range(&this->_M_head._M_data, __x.begin(), __x.end()); } + + slist(__move_source<_Self> src) + : _STLP_PRIV _Slist_base<_Tp, _Alloc>(__move_source<_Base>(src.get())) {} + + _Self& operator= (const _Self& __x); + + ~slist() {} + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } + +private: + void _M_fill_assign(size_type __n, const _Tp& __val); + +#if defined (_STLP_MEMBER_TEMPLATES) +public: + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + +private: + template + void _M_assign_dispatch(_Integer __n, _Integer __val, + const __true_type& /*_IsIntegral*/) { + _M_fill_assign((size_type) __n, (_Tp) __val); + } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, + const __false_type& /*_IsIntegral*/) { +#else +public: + void assign(const_pointer __first, const_pointer __last) { + _Node_base* __prev = &this->_M_head._M_data; + _Node_base* __node = this->_M_head._M_data._M_next; + while (__node != 0 && __first != __last) { + __STATIC_CAST(_Node*, __node)->_M_data = *__first; + __prev = __node; + __node = __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + this->_M_erase_after(__prev, 0); + } + void assign(const_iterator __first, const_iterator __last) { +#endif /* _STLP_MEMBER_TEMPLATES */ + _Node_base* __prev = &this->_M_head._M_data; + _Node_base* __node = this->_M_head._M_data._M_next; + while (__node != 0 && __first != __last) { + __STATIC_CAST(_Node*, __node)->_M_data = *__first; + __prev = __node; + __node = __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + this->_M_erase_after(__prev, 0); + } + +public: + + // Experimental new feature: before_begin() returns a + // non-dereferenceable iterator that, when incremented, yields + // begin(). This iterator may be used as the argument to + // insert_after, erase_after, etc. Note that even for an empty + // slist, before_begin() is not the same iterator as end(). It + // is always necessary to increment before_begin() at least once to + // obtain end(). + iterator before_begin() { return iterator(&this->_M_head._M_data); } + const_iterator before_begin() const + { return const_iterator(__CONST_CAST(_Node_base*, &this->_M_head._M_data)); } + + iterator begin() { return iterator(this->_M_head._M_data._M_next); } + const_iterator begin() const + { return const_iterator(this->_M_head._M_data._M_next);} + + iterator end() { return iterator(); } + const_iterator end() const { return const_iterator(); } + + size_type size() const + { return _STLP_PRIV _Sl_global_inst::size(this->_M_head._M_data._M_next); } + + size_type max_size() const { return size_type(-1); } + + bool empty() const { return this->_M_head._M_data._M_next == 0; } + + void swap(_Self& __x) { + this->_M_head.swap(__x._M_head); + } + +public: + reference front() { return *begin(); } + const_reference front() const { return *begin(); } +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) && !defined (_STLP_NO_ANACHRONISMS) + void push_front(const value_type& __x = _Tp()) { +#else + void push_front(const value_type& __x) { +#endif /*!_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/ + _STLP_PRIV __slist_make_link(&this->_M_head._M_data, _M_create_node(__x)); + } + +#if defined (_STLP_DONT_SUP_DFLT_PARAM) && !defined (_STLP_NO_ANACHRONISMS) + void push_front() { _STLP_PRIV __slist_make_link(&this->_M_head._M_data, _M_create_node());} +#endif /*_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/ + + void pop_front() { + _Node* __node = __STATIC_CAST(_Node*, this->_M_head._M_data._M_next); + this->_M_head._M_data._M_next = __node->_M_next; + _STLP_STD::_Destroy(&__node->_M_data); + this->_M_head.deallocate(__node, 1); + } + + iterator previous(const_iterator __pos) { + return iterator(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node)); + } + const_iterator previous(const_iterator __pos) const { + return const_iterator(__CONST_CAST(_Node_base*, + _STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, + __pos._M_node))); + } + +private: +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) + _Node* _M_insert_after(_Node_base* __pos, const value_type& __x = _Tp()) { +#else + _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + return __STATIC_CAST(_Node*, _STLP_PRIV __slist_make_link(__pos, _M_create_node(__x))); + } + +#if defined (_STLP_DONT_SUP_DFLT_PARAM) + _Node* _M_insert_after(_Node_base* __pos) { + return __STATIC_CAST(_Node*, _STLP_PRIV __slist_make_link(__pos, _M_create_node())); + } +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + + void _M_insert_after_fill(_Node_base* __pos, + size_type __n, const value_type& __x) { + for (size_type __i = 0; __i < __n; ++__i) + __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(__x)); + } + +#if defined (_STLP_MEMBER_TEMPLATES) + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _IsIntegral<_InIter>::_Ret _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + const __true_type&) { + _M_insert_after_fill(__pos, __n, __x); + } + + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last, + const __false_type&) { +#else /* _STLP_MEMBER_TEMPLATES */ + void _M_insert_after_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_insert_after_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { +#endif /* _STLP_MEMBER_TEMPLATES */ + while (__first != __last) { + __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + +#if defined (_STLP_MEMBER_TEMPLATES) + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_splice_after_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _IsIntegral<_InIter>::_Ret _Integral; + _M_splice_after_range(__pos, __first, __last, _Integral()); + } + + template + void _M_splice_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + const __true_type&) { + _M_insert_after_fill(__pos, __n, __x); + } + + template + void _M_splice_after_range(_Node_base* __pos, + _InIter __first, _InIter __last, + const __false_type&) { +#else /* _STLP_MEMBER_TEMPLATES */ + void _M_splice_after_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_splice_after_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { +#endif /* _STLP_MEMBER_TEMPLATES */ + //We use a temporary slist to avoid the auto reference troubles (infinite loop) + _Self __tmp(__first, __last, this->get_allocator()); + splice_after(iterator(__pos), __tmp); + } + +#if defined (_STLP_MEMBER_TEMPLATES) + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_splice_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _IsIntegral<_InIter>::_Ret _Integral; + _M_splice_range(__pos, __first, __last, _Integral()); + } + + template + void _M_splice_range(_Node_base* __pos, _Integer __n, _Integer __x, + const __true_type&) { + _M_insert_after_fill(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos), + __n, __x); + } + + template + void _M_splice_range(_Node_base* __pos, + _InIter __first, _InIter __last, + const __false_type&) { +#else /* _STLP_MEMBER_TEMPLATES */ + void _M_splice_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = _STLP_PRIV __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_splice_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { +#endif /* _STLP_MEMBER_TEMPLATES */ + //We use a temporary slist to avoid the auto reference troubles (infinite loop) + _Self __tmp(__first, __last, this->get_allocator()); + splice(iterator(__pos), __tmp); + } + +public: + +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) + iterator insert_after(iterator __pos, const value_type& __x = _Tp()) { +#else + iterator insert_after(iterator __pos, const value_type& __x) { +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + return iterator(_M_insert_after(__pos._M_node, __x)); + } + +#if defined (_STLP_DONT_SUP_DFLT_PARAM) + iterator insert_after(iterator __pos) { + return insert_after(__pos, _STLP_DEFAULT_CONSTRUCTED(_Tp)); + } +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + + void insert_after(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__pos._M_node, __n, __x); + } + +#if defined (_STLP_MEMBER_TEMPLATES) + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert_after(iterator __pos, _InIter __first, _InIter __last) { +#else /* _STLP_MEMBER_TEMPLATES */ + void insert_after(iterator __pos, + const value_type* __first, const value_type* __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + void insert_after(iterator __pos, + const_iterator __first, const_iterator __last) { +#endif /* _STLP_MEMBER_TEMPLATES */ + _M_splice_after_range(__pos._M_node, __first, __last); + } + +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) + iterator insert(iterator __pos, const value_type& __x = _Tp()) { +#else + iterator insert(iterator __pos, const value_type& __x) { +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + return iterator(_M_insert_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), + __x)); + } + +#if defined (_STLP_DONT_SUP_DFLT_PARAM) + iterator insert(iterator __pos) { + return iterator(_M_insert_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), + _STLP_DEFAULT_CONSTRUCTED(_Tp))); + } +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + + void insert(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), __n, __x); + } + +#if defined (_STLP_MEMBER_TEMPLATES) + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert(iterator __pos, _InIter __first, _InIter __last) { +#else /* _STLP_MEMBER_TEMPLATES */ + void insert(iterator __pos, const value_type* __first, + const value_type* __last) { + _M_insert_after_range(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), + __first, __last); + } + void insert(iterator __pos, const_iterator __first, const_iterator __last) { +#endif /* _STLP_MEMBER_TEMPLATES */ + _M_splice_range(__pos._M_node, __first, __last); + } + +public: + iterator erase_after(iterator __pos) + { return iterator(this->_M_erase_after(__pos._M_node)); } + iterator erase_after(iterator __before_first, iterator __last) + { return iterator(this->_M_erase_after(__before_first._M_node, __last._M_node)); } + + iterator erase(iterator __pos) + { return iterator(this->_M_erase_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node))); } + iterator erase(iterator __first, iterator __last) + { return iterator(this->_M_erase_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __first._M_node), __last._M_node)); } + +#if !defined (_STLP_DONT_SUP_DFLT_PARAM) + void resize(size_type new_size, const value_type& __x = _Tp()); +#else + void resize(size_type new_size, const value_type& __x); +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + +#if defined (_STLP_DONT_SUP_DFLT_PARAM) + void resize(size_type new_size) { resize(new_size, _STLP_DEFAULT_CONSTRUCTED(_Tp)); } +#endif /*_STLP_DONT_SUP_DFLT_PARAM*/ + + void clear() + { this->_M_erase_after(&this->_M_head._M_data, 0); } + +public: + // Moves the range [__before_first + 1, __before_last + 1) to *this, + // inserting it immediately after __pos. This is constant time. + void splice_after(iterator __pos, _Self& __x, + iterator __before_first, iterator __before_last) { + if (__before_first != __before_last) { + if (this->get_allocator() == __x.get_allocator()) { + _STLP_PRIV _Sl_global_inst::__splice_after(__pos._M_node, + __before_first._M_node, __before_last._M_node); + } + else { + this->insert_after(__pos, iterator(__before_first._M_node->_M_next), iterator(__before_last._M_node->_M_next)); + __x.erase_after(__before_first, ++__before_last); + } + } + } + + // Moves the element that follows __prev to *this, inserting it immediately + // after __pos. This is constant time. + void splice_after(iterator __pos, _Self& __x, iterator __prev) { + if (this->get_allocator() == __x.get_allocator()) { + _STLP_PRIV _Sl_global_inst::__splice_after(__pos._M_node, + __prev._M_node, __prev._M_node->_M_next); + } + else { + this->insert_after(__pos, __STATIC_CAST(_Node*, __prev._M_node->_M_next)->_M_data); + __x.erase_after(__prev); + } + } + + // Removes all of the elements from the list __x to *this, inserting + // them immediately after __pos. __x must not be *this. Complexity: + // linear in __x.size(). + void splice_after(iterator __pos, _Self& __x) { + if (this->get_allocator() == __x.get_allocator()) + _STLP_PRIV _Sl_global_inst::__splice_after(__pos._M_node, &__x._M_head._M_data); + else { + this->insert_after(__pos, __x.begin(), __x.end()); + __x.clear(); + } + } + + // Linear in distance(begin(), __pos), and linear in __x.size(). + void splice(iterator __pos, _Self& __x) { + if (__x._M_head._M_data._M_next) { + if (this->get_allocator() == __x.get_allocator()) { + _STLP_PRIV _Sl_global_inst::__splice_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), + &__x._M_head._M_data, + _STLP_PRIV _Sl_global_inst::__previous(&__x._M_head._M_data, 0)); + } + else { + insert(__pos, __x.begin(), __x.end()); + __x.clear(); + } + } + } + + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void splice(iterator __pos, _Self& __x, iterator __i) { + if (this->get_allocator() == __x.get_allocator()) { + _STLP_PRIV _Sl_global_inst::__splice_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), + _STLP_PRIV _Sl_global_inst::__previous(&__x._M_head._M_data, __i._M_node), + __i._M_node); + } + else { + insert(__pos, *__i); + __x.erase(__i); + } + } + + // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), + // and in distance(__first, __last). + void splice(iterator __pos, _Self& __x, iterator __first, iterator __last) { + if (__first != __last) { + if (this->get_allocator() == __x.get_allocator()) { + _STLP_PRIV _Sl_global_inst::__splice_after(_STLP_PRIV _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), + _STLP_PRIV _Sl_global_inst::__previous(&__x._M_head._M_data, __first._M_node), + _STLP_PRIV _Sl_global_inst::__previous(__first._M_node, __last._M_node)); + } + else { + insert(__pos, __first, __last); + __x.erase(__first, __last); + } + } + } + +public: + void reverse() { + if (this->_M_head._M_data._M_next) + this->_M_head._M_data._M_next = _STLP_PRIV _Sl_global_inst::__reverse(this->_M_head._M_data._M_next); + } + + void remove(const _Tp& __val); + + void unique() { _STLP_PRIV _Slist_unique(*this, equal_to()); } + void merge(_Self& __x) { _STLP_PRIV _Slist_merge(*this, __x, less()); } + void sort() { _STLP_PRIV _Slist_sort(*this, less()); } + +#if defined (_STLP_MEMBER_TEMPLATES) + template + void remove_if(_Predicate __pred) { + _Node_base* __cur = &this->_M_head._M_data; + while (__cur->_M_next) { + if (__pred(__STATIC_CAST(_Node*, __cur->_M_next)->_M_data)) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } + + template + void unique(_BinaryPredicate __pred) + { _STLP_PRIV _Slist_unique(*this, __pred); } + + template + void merge(_Self& __x, _StrictWeakOrdering __comp) + { _STLP_PRIV _Slist_merge(*this, __x, __comp); } + + template + void sort(_StrictWeakOrdering __comp) + { _STLP_PRIV _Slist_sort(*this, __comp); } +#endif /* _STLP_MEMBER_TEMPLATES */ +}; + +#if defined (slist) +# undef slist +_STLP_MOVE_TO_STD_NAMESPACE +#endif + +_STLP_END_NAMESPACE + +#if !defined (_STLP_LINK_TIME_INSTANTIATION) +# include +#endif + +#if defined (_STLP_USE_PTR_SPECIALIZATIONS) +# include +#endif + +#if defined (_STLP_DEBUG) +# include +#endif + +_STLP_BEGIN_NAMESPACE + +template +inline bool _STLP_CALL +operator == (const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { + typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = _SL1.end(); + const_iterator __end2 = _SL2.end(); + + const_iterator __i1 = _SL1.begin(); + const_iterator __i2 = _SL2.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; +} + +#define _STLP_EQUAL_OPERATOR_SPECIALIZED +#define _STLP_TEMPLATE_HEADER template +#define _STLP_TEMPLATE_CONTAINER slist<_Tp, _Alloc> +#include +#undef _STLP_TEMPLATE_CONTAINER +#undef _STLP_TEMPLATE_HEADER +#undef _STLP_EQUAL_OPERATOR_SPECIALIZED + +#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) +template +struct __move_traits > { + typedef __stlp_movable implemented; + typedef typename __move_traits<_Alloc>::complete complete; +}; + +// Specialization of insert_iterator so that insertions will be constant +// time rather than linear time. +template +class insert_iterator > { +protected: + typedef slist<_Tp, _Alloc> _Container; + _Container* _M_container; + typename _Container::iterator _M_iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : _M_container(&__x) { + if (__i == __x.begin()) + _M_iter = __x.before_begin(); + else + _M_iter = __x.previous(__i); + } + + insert_iterator<_Container>& + operator = (const typename _Container::value_type& __val) { + _M_iter = _M_container->insert_after(_M_iter, __val); + return *this; + } + + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; +#endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */ + +_STLP_END_NAMESPACE + +#endif /* _STLP_INTERNAL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: