williamr@2: /* williamr@2: * williamr@2: * Copyright (c) 1996,1997 williamr@2: * Silicon Graphics Computer Systems, Inc. williamr@2: * williamr@4: * Copyright (c) 1999 williamr@2: * Boris Fomitchev williamr@2: * williamr@2: * This material is provided "as is", with absolutely no warranty expressed williamr@2: * or implied. Any use is at your own risk. williamr@2: * williamr@4: * Permission to use or copy this software for any purpose is hereby granted williamr@2: * without fee, provided the above notices are retained on all copies. williamr@2: * Permission to modify the code and to distribute modified code is granted, williamr@2: * provided the above notices are retained, and a notice that the code was williamr@2: * modified is included with the above copyright notice. williamr@2: * williamr@2: */ williamr@2: #ifndef _STLP_SLIST_C williamr@2: #define _STLP_SLIST_C williamr@2: williamr@2: #ifndef _STLP_INTERNAL_SLIST_H williamr@4: # include williamr@2: #endif williamr@2: williamr@4: #ifndef _STLP_CARRAY_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #ifndef _STLP_RANGE_ERRORS_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #if defined (_STLP_NESTED_TYPE_PARAM_BUG) williamr@4: # define size_type size_t williamr@4: #endif williamr@2: williamr@2: _STLP_BEGIN_NAMESPACE williamr@2: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@2: _Slist_node_base* williamr@2: _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, williamr@2: _Slist_node_base* __last_node) { williamr@4: _Slist_node_base* __cur = __before_first->_M_next; williamr@2: while (__cur != __last_node) { williamr@4: _Node* __tmp = __STATIC_CAST(_Node*, __cur); williamr@4: __cur = __cur->_M_next; williamr@2: _STLP_STD::_Destroy(&__tmp->_M_data); williamr@2: _M_head.deallocate(__tmp,1); williamr@2: } williamr@2: __before_first->_M_next = __last_node; williamr@2: return __last_node; williamr@2: } williamr@2: williamr@4: #if defined (_STLP_USE_PTR_SPECIALIZATIONS) williamr@4: # define slist _STLP_PTR_IMPL_NAME(slist) williamr@4: #elif defined (_STLP_DEBUG) williamr@4: # define slist _STLP_NON_DBG_NAME(slist) williamr@4: #else williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: #endif williamr@4: williamr@4: /* When building STLport lib Digital Mars Compiler complains on the _M_data assignment williamr@4: * problem which would be perfertly right if we were using it. Hiding it during build williamr@4: * fix this issue. williamr@4: */ williamr@2: template williamr@4: slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) { williamr@2: if (&__x != this) { williamr@2: _Node_base* __p1 = &this->_M_head._M_data; williamr@4: _Node_base* __n1 = this->_M_head._M_data._M_next; williamr@4: const _Node_base* __n2 = __x._M_head._M_data._M_next; williamr@2: while (__n1 && __n2) { williamr@4: __STATIC_CAST(_Node*, __n1)->_M_data = __STATIC_CAST(const _Node*, __n2)->_M_data; williamr@2: __p1 = __n1; williamr@4: __n1 = __n1->_M_next; williamr@4: __n2 = __n2->_M_next; williamr@2: } williamr@2: if (__n2 == 0) williamr@2: this->_M_erase_after(__p1, 0); williamr@2: else williamr@4: _M_insert_after_range(__p1, const_iterator(__CONST_CAST(_Node_base*, __n2)), williamr@2: const_iterator(0)); williamr@2: } williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template williamr@2: void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { williamr@2: _Node_base* __prev = &this->_M_head._M_data; williamr@4: _Node_base* __node = this->_M_head._M_data._M_next; williamr@2: for ( ; __node != 0 && __n > 0 ; --__n) { williamr@4: __STATIC_CAST(_Node*, __node)->_M_data = __val; williamr@2: __prev = __node; williamr@4: __node = __node->_M_next; williamr@2: } williamr@2: if (__n > 0) williamr@2: _M_insert_after_fill(__prev, __n, __val); williamr@2: else williamr@2: this->_M_erase_after(__prev, 0); williamr@2: } williamr@2: williamr@2: template williamr@4: void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) { williamr@2: _Node_base* __cur = &this->_M_head._M_data; williamr@2: while (__cur->_M_next != 0 && __len > 0) { williamr@2: --__len; williamr@2: __cur = __cur->_M_next; williamr@2: } williamr@4: if (__cur->_M_next) williamr@2: this->_M_erase_after(__cur, 0); williamr@2: else williamr@2: _M_insert_after_fill(__cur, __len, __x); williamr@2: } williamr@2: williamr@2: template williamr@4: void slist<_Tp,_Alloc>::remove(const _Tp& __val) { williamr@2: _Node_base* __cur = &this->_M_head._M_data; williamr@2: while (__cur && __cur->_M_next) { williamr@4: if (__STATIC_CAST(_Node*, __cur->_M_next)->_M_data == __val) williamr@2: this->_M_erase_after(__cur); williamr@2: else williamr@2: __cur = __cur->_M_next; williamr@2: } williamr@2: } williamr@2: williamr@4: #if !defined (slist) williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: #endif williamr@4: williamr@4: template williamr@4: void _Slist_unique(slist<_Tp, _Alloc>& __that, _BinaryPredicate __pred) { williamr@4: typedef _Slist_node<_Tp> _Node; williamr@4: typename slist<_Tp, _Alloc>::iterator __ite(__that.begin()); williamr@4: if (__ite != __that.end()) { williamr@4: while (__ite._M_node->_M_next) { williamr@4: if (__pred(*__ite, __STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data)) williamr@4: __that.erase_after(__ite); williamr@2: else williamr@4: ++__ite; williamr@2: } williamr@2: } williamr@2: } williamr@2: williamr@4: template williamr@4: void _Slist_merge(slist<_Tp, _Alloc>& __that, slist<_Tp, _Alloc>& __x, williamr@4: _StrictWeakOrdering __comp) { williamr@4: typedef _Slist_node<_Tp> _Node; williamr@4: typedef _STLP_PRIV _Slist_node_base _Node_base; williamr@4: if (__that.get_allocator() == __x.get_allocator()) { williamr@4: typename slist<_Tp, _Alloc>::iterator __ite(__that.before_begin()); williamr@4: while (__ite._M_node->_M_next && !__x.empty()) { williamr@4: if (__comp(__x.front(), __STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data, __x.front()), williamr@4: _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __that.splice_after(__ite, __x, __x.before_begin()); williamr@4: } williamr@4: ++__ite; williamr@4: } williamr@4: if (!__x.empty()) { williamr@4: __that.splice_after(__ite, __x); williamr@4: } williamr@2: } williamr@4: else { williamr@4: typename slist<_Tp, _Alloc>::iterator __i1(__that.before_begin()), __i2(__x.begin()); williamr@4: while (__i1._M_node->_M_next && __i2._M_node) { williamr@4: if (__comp(__STATIC_CAST(_Node*, __i1._M_node->_M_next)->_M_data, *__i2)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__i2, __STATIC_CAST(_Node*, __i1._M_node->_M_next)->_M_data), williamr@4: _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: ++__i1; williamr@4: } williamr@4: else { williamr@4: __i1 = __that.insert_after(__i1, *(__i2++)); williamr@4: } williamr@4: } williamr@4: __that.insert_after(__i1, __i2, __x.end()); williamr@4: __x.clear(); williamr@2: } williamr@2: } williamr@2: williamr@4: template williamr@4: void _Slist_sort(slist<_Tp, _Alloc>& __that, _StrictWeakOrdering __comp) { williamr@4: if (!__that.begin()._M_node || !__that.begin()._M_node->_M_next) williamr@4: return; williamr@4: williamr@4: slist<_Tp, _Alloc> __carry(__that.get_allocator()); williamr@4: const int NB = 64; williamr@4: _STLP_PRIV _CArray, NB> __counter(__carry); williamr@4: int __fill = 0; williamr@4: while (!__that.empty()) { williamr@4: __carry.splice_after(__carry.before_begin(), __that, __that.before_begin()); williamr@4: int __i = 0; williamr@4: while (__i < __fill && !__counter[__i].empty()) { williamr@4: _STLP_PRIV _Slist_merge(__counter[__i], __carry, __comp); williamr@4: __carry.swap(__counter[__i]); williamr@4: ++__i; williamr@4: } williamr@4: __carry.swap(__counter[__i]); williamr@4: if (__i == __fill) { williamr@4: ++__fill; williamr@4: if (__fill >= NB) { williamr@4: //Looks like the slist has too many elements to be sorted with this algorithm: williamr@4: __stl_throw_overflow_error("slist::sort"); williamr@2: } williamr@2: } williamr@4: } williamr@2: williamr@4: for (int __i = 1; __i < __fill; ++__i) williamr@4: _STLP_PRIV _Slist_merge(__counter[__i], __counter[__i - 1], __comp); williamr@4: __that.swap(__counter[__fill-1]); williamr@2: } williamr@2: williamr@4: #if defined (slist) williamr@4: # undef slist williamr@4: #endif williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@2: williamr@2: _STLP_END_NAMESPACE williamr@2: williamr@4: #if defined (_STLP_NESTED_TYPE_PARAM_BUG) williamr@4: # undef size_type williamr@4: #endif williamr@4: williamr@2: #endif /* _STLP_SLIST_C */ williamr@2: williamr@2: // Local Variables: williamr@2: // mode:C++ williamr@2: // End: