/home/ntakagi/work/STLport-5.1.5/stlport/stl/_vector.c

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Copyright (c) 1994
00005  * Hewlett-Packard Company
00006  *
00007  * Copyright (c) 1996,1997
00008  * Silicon Graphics Computer Systems, Inc.
00009  *
00010  * Copyright (c) 1997
00011  * Moscow Center for SPARC Technology
00012  *
00013  * Copyright (c) 1999
00014  * Boris Fomitchev
00015  *
00016  * This material is provided "as is", with absolutely no warranty expressed
00017  * or implied. Any use is at your own risk.
00018  *
00019  * Permission to use or copy this software for any purpose is hereby granted
00020  * without fee, provided the above notices are retained on all copies.
00021  * Permission to modify the code and to distribute modified code is granted,
00022  * provided the above notices are retained, and a notice that the code was
00023  * modified is included with the above copyright notice.
00024  *
00025  */
00026 #ifndef _STLP_VECTOR_C
00027 #define _STLP_VECTOR_C
00028 
00029 #if !defined (_STLP_INTERNAL_VECTOR_H)
00030 #  include <stl/_vector.h>
00031 #endif
00032 
00033 #include <stl/_range_errors.h>
00034 
00035 _STLP_BEGIN_NAMESPACE
00036 
00037 _STLP_MOVE_TO_PRIV_NAMESPACE
00038 
00039 template <class _Tp, class _Alloc>
00040 void _Vector_base<_Tp,_Alloc>::_M_throw_length_error() const {
00041   __stl_throw_length_error("vector");
00042 }
00043 
00044 template <class _Tp, class _Alloc>
00045 void _Vector_base<_Tp, _Alloc>::_M_throw_out_of_range() const {
00046   __stl_throw_out_of_range("vector");
00047 }
00048 
00049 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00050 #  define vector _STLP_PTR_IMPL_NAME(vector)
00051 #elif defined (_STLP_DEBUG)
00052 #  define vector _STLP_NON_DBG_NAME(vector)
00053 #else
00054 _STLP_MOVE_TO_STD_NAMESPACE
00055 #endif
00056 
00057 #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
00058 #  define __iterator__  _Tp*
00059 #else
00060 #  define __iterator__  _STLP_TYPENAME_ON_RETURN_TYPE vector<_Tp, _Alloc>::iterator
00061 #endif
00062 
00063 template <class _Tp, class _Alloc>
00064 void vector<_Tp, _Alloc>::reserve(size_type __n) {
00065   if (capacity() < __n) {
00066     if (max_size() < __n) {
00067       this->_M_throw_length_error();
00068     }
00069 
00070     const size_type __old_size = size();
00071     pointer __tmp;
00072     if (this->_M_start) {
00073       __tmp = _M_allocate_and_copy(__n, this->_M_start, this->_M_finish);
00074       _M_clear();
00075     } else {
00076       __tmp = this->_M_end_of_storage.allocate(__n, __n);
00077     }
00078     _M_set(__tmp, __tmp + __old_size, __tmp + __n);
00079   }
00080 }
00081 
00082 template <class _Tp, class _Alloc>
00083 void vector<_Tp, _Alloc>::_M_insert_overflow_aux(pointer __pos, const _Tp& __x, const __false_type& /*DO NOT USE!!*/,
00084                                                  size_type __fill_len, bool __atend ) {
00085   const size_type __old_size = size();
00086   size_type __len = __old_size + (max)(__old_size, __fill_len);
00087 
00088   pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
00089   pointer __new_finish = __new_start;
00090   _STLP_TRY {
00091     __new_finish = _STLP_PRIV __uninitialized_move(this->_M_start, __pos, __new_start, _TrivialUCopy(), _Movable());
00092     // handle insertion
00093     if (__fill_len == 1) {
00094       _Copy_Construct(__new_finish, __x);
00095       ++__new_finish;
00096     } else
00097       __new_finish = _STLP_PRIV __uninitialized_fill_n(__new_finish, __fill_len, __x);
00098     if (!__atend)
00099       __new_finish = _STLP_PRIV __uninitialized_move(__pos, this->_M_finish, __new_finish, _TrivialUCopy(), _Movable()); // copy remainder
00100   }
00101   _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
00102                this->_M_end_of_storage.deallocate(__new_start,__len)))
00103   _M_clear_after_move();
00104   _M_set(__new_start, __new_finish, __new_start + __len);
00105 }
00106 
00107 template <class _Tp, class _Alloc>
00108 void vector<_Tp, _Alloc>::_M_insert_overflow(pointer __pos, const _Tp& __x, const __true_type& /*_TrivialCopy*/,
00109                                              size_type __fill_len, bool __atend ) {
00110   const size_type __old_size = size();
00111   size_type __len = __old_size + (max)(__old_size, __fill_len);
00112 
00113   pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
00114   pointer __new_finish = __STATIC_CAST(pointer, _STLP_PRIV __copy_trivial(this->_M_start, __pos, __new_start));
00115   // handle insertion
00116   __new_finish = _STLP_PRIV __fill_n(__new_finish, __fill_len, __x);
00117   if (!__atend)
00118     __new_finish = __STATIC_CAST(pointer, _STLP_PRIV __copy_trivial(__pos, this->_M_finish, __new_finish)); // copy remainder
00119   _M_clear();
00120   _M_set(__new_start, __new_finish, __new_start + __len);
00121 }
00122 
00123 template <class _Tp, class _Alloc>
00124 void vector<_Tp, _Alloc>::_M_fill_insert_aux(iterator __pos, size_type __n,
00125                                              const _Tp& __x, const __true_type& /*_Movable*/) {
00126   if (_M_is_inside(__x)) {
00127     _Tp __x_copy = __x;
00128     _M_fill_insert_aux(__pos, __n, __x_copy, __true_type());
00129     return;
00130   }
00131   iterator __src = this->_M_finish - 1;
00132   iterator __dst = __src + __n;
00133   for (; __src >= __pos; --__dst, --__src) {
00134     _STLP_STD::_Move_Construct(__dst, *__src);
00135     _STLP_STD::_Destroy_Moved(__src);
00136   }
00137   _STLP_PRIV __uninitialized_fill_n(__pos, __n, __x);
00138   this->_M_finish += __n;
00139 }
00140 
00141 template <class _Tp, class _Alloc>
00142 void vector<_Tp, _Alloc>::_M_fill_insert_aux (iterator __pos, size_type __n,
00143                                               const _Tp& __x, const __false_type& /*_Movable*/) {
00144   //Here self referencing needs to be checked even for non movable types.
00145   if (_M_is_inside(__x)) {
00146     _Tp __x_copy = __x;
00147     _M_fill_insert_aux(__pos, __n, __x_copy, __false_type());
00148     return;
00149   }
00150   const size_type __elems_after = this->_M_finish - __pos;
00151   pointer __old_finish = this->_M_finish;
00152   if (__elems_after > __n) {
00153     _STLP_PRIV __ucopy_ptrs(this->_M_finish - __n, this->_M_finish, this->_M_finish, _TrivialUCopy());
00154     this->_M_finish += __n;
00155     _STLP_PRIV __copy_backward_ptrs(__pos, __old_finish - __n, __old_finish, _TrivialCopy());
00156     _STLP_STD::fill(__pos, __pos + __n, __x);
00157   } else {
00158     this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_finish, __n - __elems_after, __x);
00159     _STLP_PRIV __ucopy_ptrs(__pos, __old_finish, this->_M_finish, _TrivialUCopy());
00160     this->_M_finish += __elems_after;
00161     _STLP_STD::fill(__pos, __old_finish, __x);
00162   }
00163 }
00164 
00165 template <class _Tp, class _Alloc>
00166 void vector<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
00167                                          size_type __n, const _Tp& __x) {
00168   if (__n != 0) {
00169     if (size_type(this->_M_end_of_storage._M_data - this->_M_finish) >= __n) {
00170       _M_fill_insert_aux(__pos, __n, __x, _Movable());
00171     } else
00172       _M_insert_overflow(__pos, __x, _TrivialCopy(), __n);
00173   }
00174 }
00175 
00176 template <class _Tp, class _Alloc>
00177 vector<_Tp, _Alloc>& vector<_Tp, _Alloc>::operator = (const vector<_Tp, _Alloc>& __x) {
00178   if (&__x != this) {
00179     const size_type __xlen = __x.size();
00180     if (__xlen > capacity()) {
00181       size_type __len = __xlen;
00182       pointer __tmp = _M_allocate_and_copy(__len, __CONST_CAST(const_pointer, __x._M_start) + 0,
00183                                                   __CONST_CAST(const_pointer, __x._M_finish) + 0);
00184       _M_clear();
00185       this->_M_start = __tmp;
00186       this->_M_end_of_storage._M_data = this->_M_start + __len;
00187     } else if (size() >= __xlen) {
00188       pointer __i = _STLP_PRIV __copy_ptrs(__CONST_CAST(const_pointer, __x._M_start) + 0,
00189                                            __CONST_CAST(const_pointer, __x._M_finish) + 0, this->_M_start, _TrivialCopy());
00190       _STLP_STD::_Destroy_Range(__i, this->_M_finish);
00191     } else {
00192       _STLP_PRIV __copy_ptrs(__CONST_CAST(const_pointer, __x._M_start),
00193                              __CONST_CAST(const_pointer, __x._M_start) + size(), this->_M_start, _TrivialCopy());
00194       _STLP_PRIV __ucopy_ptrs(__CONST_CAST(const_pointer, __x._M_start) + size(),
00195                               __CONST_CAST(const_pointer, __x._M_finish) + 0, this->_M_finish, _TrivialUCopy());
00196     }
00197     this->_M_finish = this->_M_start + __xlen;
00198   }
00199   return *this;
00200 }
00201 
00202 template <class _Tp, class _Alloc>
00203 void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const _Tp& __val) {
00204   if (__n > capacity()) {
00205     vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
00206     __tmp.swap(*this);
00207   } else if (__n > size()) {
00208     fill(begin(), end(), __val);
00209     this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_finish, __n - size(), __val);
00210   } else
00211     erase(_STLP_PRIV __fill_n(begin(), __n, __val), end());
00212 }
00213 
00214 template <class _Tp, class _Alloc>
00215 __iterator__
00216 vector<_Tp, _Alloc>::insert(iterator __pos, const _Tp& __x) {
00217   size_type __n = __pos - begin();
00218   _M_fill_insert(__pos, 1, __x);
00219   return begin() + __n;
00220 }
00221 
00222 #undef __iterator__
00223 
00224 #if defined (vector)
00225 #  undef vector
00226 _STLP_MOVE_TO_STD_NAMESPACE
00227 #endif
00228 
00229 _STLP_END_NAMESPACE
00230 
00231 #endif /*  _STLP_VECTOR_C */
00232 
00233 // Local Variables:
00234 // mode:C++
00235 // End:



Generated on Mon Mar 10 15:32:44 2008 by  doxygen 1.5.1