williamr@2: /* williamr@2: * williamr@2: * williamr@2: * Copyright (c) 1994 williamr@2: * Hewlett-Packard Company williamr@2: * williamr@2: * Copyright (c) 1996,1997 williamr@2: * Silicon Graphics Computer Systems, Inc. williamr@2: * williamr@2: * Copyright (c) 1997 williamr@2: * Moscow Center for SPARC Technology 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_VECTOR_C williamr@2: #define _STLP_VECTOR_C williamr@2: williamr@4: #if !defined (_STLP_INTERNAL_VECTOR_H) williamr@2: # include williamr@4: #endif williamr@2: williamr@4: #include williamr@2: williamr@2: _STLP_BEGIN_NAMESPACE williamr@2: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@2: template williamr@4: void _Vector_base<_Tp,_Alloc>::_M_throw_length_error() const { williamr@4: __stl_throw_length_error("vector"); williamr@4: } williamr@4: williamr@4: template williamr@4: void _Vector_base<_Tp, _Alloc>::_M_throw_out_of_range() const { williamr@4: __stl_throw_out_of_range("vector"); williamr@4: } williamr@4: williamr@4: #if defined (_STLP_USE_PTR_SPECIALIZATIONS) williamr@4: # define vector _STLP_PTR_IMPL_NAME(vector) williamr@4: #elif defined (_STLP_DEBUG) williamr@4: # define vector _STLP_NON_DBG_NAME(vector) williamr@4: #else williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: #endif williamr@4: williamr@4: #if defined (_STLP_NESTED_TYPE_PARAM_BUG) williamr@4: # define __iterator__ _Tp* williamr@4: #else williamr@4: # define __iterator__ _STLP_TYPENAME_ON_RETURN_TYPE vector<_Tp, _Alloc>::iterator williamr@4: #endif williamr@4: williamr@4: template williamr@4: void vector<_Tp, _Alloc>::reserve(size_type __n) { williamr@2: if (capacity() < __n) { williamr@4: if (max_size() < __n) { williamr@4: this->_M_throw_length_error(); williamr@4: } williamr@4: williamr@2: const size_type __old_size = size(); williamr@2: pointer __tmp; williamr@2: if (this->_M_start) { williamr@2: __tmp = _M_allocate_and_copy(__n, this->_M_start, this->_M_finish); williamr@2: _M_clear(); williamr@2: } else { williamr@4: __tmp = this->_M_end_of_storage.allocate(__n, __n); williamr@2: } williamr@2: _M_set(__tmp, __tmp + __old_size, __tmp + __n); williamr@2: } williamr@2: } williamr@2: williamr@2: template williamr@4: void vector<_Tp, _Alloc>::_M_insert_overflow_aux(pointer __pos, const _Tp& __x, const __false_type& /*DO NOT USE!!*/, williamr@4: size_type __fill_len, bool __atend ) { williamr@4: const size_type __old_size = size(); williamr@4: size_type __len = __old_size + (max)(__old_size, __fill_len); williamr@4: williamr@4: pointer __new_start = this->_M_end_of_storage.allocate(__len, __len); williamr@4: pointer __new_finish = __new_start; williamr@4: _STLP_TRY { williamr@4: __new_finish = _STLP_PRIV __uninitialized_move(this->_M_start, __pos, __new_start, _TrivialUCopy(), _Movable()); williamr@4: // handle insertion williamr@4: if (__fill_len == 1) { williamr@4: _Copy_Construct(__new_finish, __x); williamr@4: ++__new_finish; williamr@4: } else williamr@4: __new_finish = _STLP_PRIV __uninitialized_fill_n(__new_finish, __fill_len, __x); williamr@4: if (!__atend) williamr@4: __new_finish = _STLP_PRIV __uninitialized_move(__pos, this->_M_finish, __new_finish, _TrivialUCopy(), _Movable()); // copy remainder williamr@4: } williamr@4: _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), williamr@4: this->_M_end_of_storage.deallocate(__new_start,__len))) williamr@4: _M_clear_after_move(); williamr@4: _M_set(__new_start, __new_finish, __new_start + __len); williamr@4: } williamr@4: williamr@4: template williamr@4: void vector<_Tp, _Alloc>::_M_insert_overflow(pointer __pos, const _Tp& __x, const __true_type& /*_TrivialCopy*/, williamr@4: size_type __fill_len, bool __atend ) { williamr@4: const size_type __old_size = size(); williamr@4: size_type __len = __old_size + (max)(__old_size, __fill_len); williamr@4: williamr@4: pointer __new_start = this->_M_end_of_storage.allocate(__len, __len); williamr@4: pointer __new_finish = __STATIC_CAST(pointer, _STLP_PRIV __copy_trivial(this->_M_start, __pos, __new_start)); williamr@4: // handle insertion williamr@4: __new_finish = _STLP_PRIV __fill_n(__new_finish, __fill_len, __x); williamr@4: if (!__atend) williamr@4: __new_finish = __STATIC_CAST(pointer, _STLP_PRIV __copy_trivial(__pos, this->_M_finish, __new_finish)); // copy remainder williamr@4: _M_clear(); williamr@4: _M_set(__new_start, __new_finish, __new_start + __len); williamr@4: } williamr@4: williamr@4: template williamr@4: void vector<_Tp, _Alloc>::_M_fill_insert_aux(iterator __pos, size_type __n, williamr@4: const _Tp& __x, const __true_type& /*_Movable*/) { williamr@4: if (_M_is_inside(__x)) { williamr@4: _Tp __x_copy = __x; williamr@4: _M_fill_insert_aux(__pos, __n, __x_copy, __true_type()); williamr@4: return; williamr@4: } williamr@4: iterator __src = this->_M_finish - 1; williamr@4: iterator __dst = __src + __n; williamr@4: for (; __src >= __pos; --__dst, --__src) { williamr@4: _STLP_STD::_Move_Construct(__dst, *__src); williamr@4: _STLP_STD::_Destroy_Moved(__src); williamr@4: } williamr@4: _STLP_PRIV __uninitialized_fill_n(__pos, __n, __x); williamr@4: this->_M_finish += __n; williamr@4: } williamr@4: williamr@4: template williamr@4: void vector<_Tp, _Alloc>::_M_fill_insert_aux (iterator __pos, size_type __n, williamr@4: const _Tp& __x, const __false_type& /*_Movable*/) { williamr@4: //Here self referencing needs to be checked even for non movable types. williamr@4: if (_M_is_inside(__x)) { williamr@4: _Tp __x_copy = __x; williamr@4: _M_fill_insert_aux(__pos, __n, __x_copy, __false_type()); williamr@4: return; williamr@4: } williamr@4: const size_type __elems_after = this->_M_finish - __pos; williamr@4: pointer __old_finish = this->_M_finish; williamr@4: if (__elems_after > __n) { williamr@4: _STLP_PRIV __ucopy_ptrs(this->_M_finish - __n, this->_M_finish, this->_M_finish, _TrivialUCopy()); williamr@4: this->_M_finish += __n; williamr@4: _STLP_PRIV __copy_backward_ptrs(__pos, __old_finish - __n, __old_finish, _TrivialCopy()); williamr@4: _STLP_STD::fill(__pos, __pos + __n, __x); williamr@4: } else { williamr@4: this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_finish, __n - __elems_after, __x); williamr@4: _STLP_PRIV __ucopy_ptrs(__pos, __old_finish, this->_M_finish, _TrivialUCopy()); williamr@4: this->_M_finish += __elems_after; williamr@4: _STLP_STD::fill(__pos, __old_finish, __x); williamr@2: } williamr@2: } williamr@2: williamr@2: template williamr@4: void vector<_Tp, _Alloc>::_M_fill_insert(iterator __pos, williamr@4: size_type __n, const _Tp& __x) { williamr@4: if (__n != 0) { williamr@4: if (size_type(this->_M_end_of_storage._M_data - this->_M_finish) >= __n) { williamr@4: _M_fill_insert_aux(__pos, __n, __x, _Movable()); williamr@4: } else williamr@4: _M_insert_overflow(__pos, __x, _TrivialCopy(), __n); williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: vector<_Tp, _Alloc>& vector<_Tp, _Alloc>::operator = (const vector<_Tp, _Alloc>& __x) { williamr@2: if (&__x != this) { williamr@2: const size_type __xlen = __x.size(); williamr@2: if (__xlen > capacity()) { williamr@4: size_type __len = __xlen; williamr@4: pointer __tmp = _M_allocate_and_copy(__len, __CONST_CAST(const_pointer, __x._M_start) + 0, williamr@4: __CONST_CAST(const_pointer, __x._M_finish) + 0); williamr@2: _M_clear(); williamr@2: this->_M_start = __tmp; williamr@4: this->_M_end_of_storage._M_data = this->_M_start + __len; williamr@4: } else if (size() >= __xlen) { williamr@4: pointer __i = _STLP_PRIV __copy_ptrs(__CONST_CAST(const_pointer, __x._M_start) + 0, williamr@4: __CONST_CAST(const_pointer, __x._M_finish) + 0, this->_M_start, _TrivialCopy()); williamr@4: _STLP_STD::_Destroy_Range(__i, this->_M_finish); williamr@4: } else { williamr@4: _STLP_PRIV __copy_ptrs(__CONST_CAST(const_pointer, __x._M_start), williamr@4: __CONST_CAST(const_pointer, __x._M_start) + size(), this->_M_start, _TrivialCopy()); williamr@4: _STLP_PRIV __ucopy_ptrs(__CONST_CAST(const_pointer, __x._M_start) + size(), williamr@4: __CONST_CAST(const_pointer, __x._M_finish) + 0, this->_M_finish, _TrivialUCopy()); williamr@2: } williamr@2: this->_M_finish = this->_M_start + __xlen; williamr@2: } williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template williamr@4: void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const _Tp& __val) { williamr@2: if (__n > capacity()) { williamr@4: vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator()); williamr@2: __tmp.swap(*this); williamr@4: } else if (__n > size()) { williamr@2: fill(begin(), end(), __val); williamr@4: this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_finish, __n - size(), __val); williamr@4: } else williamr@4: erase(_STLP_PRIV __fill_n(begin(), __n, __val), end()); williamr@2: } williamr@2: williamr@4: template williamr@4: __iterator__ williamr@4: vector<_Tp, _Alloc>::insert(iterator __pos, const _Tp& __x) { williamr@4: size_type __n = __pos - begin(); williamr@4: _M_fill_insert(__pos, 1, __x); williamr@4: return begin() + __n; williamr@4: } williamr@4: williamr@4: #undef __iterator__ williamr@4: williamr@4: #if defined (vector) williamr@4: # undef vector williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: #endif williamr@4: williamr@2: _STLP_END_NAMESPACE williamr@2: williamr@2: #endif /* _STLP_VECTOR_C */ williamr@2: williamr@4: // Local Variables: williamr@4: // mode:C++ williamr@4: // End: