00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _STLP_INTERNAL_VECTOR_H
00031 #define _STLP_INTERNAL_VECTOR_H
00032
00033
00034
00035 # ifndef _STLP_INTERNAL_ALGOBASE_H
00036 # include <stl/_algobase.h>
00037 # endif
00038
00039 # ifndef _STLP_INTERNAL_ALLOC_H
00040 # include <stl/_alloc.h>
00041 # endif
00042
00043 # ifndef _STLP_INTERNAL_ITERATOR_H
00044 # include <stl/_iterator.h>
00045 # endif
00046
00047 # ifndef _STLP_INTERNAL_UNINITIALIZED_H
00048 # include <stl/_uninitialized.h>
00049 # endif
00050
00051 # ifndef _STLP_RANGE_ERRORS_H
00052 # include <stl/_range_errors.h>
00053 # endif
00054
00055 # undef vector
00056 # define vector __WORKAROUND_DBG_RENAME(vector)
00057
00058 _STLP_BEGIN_NAMESPACE
00059
00060
00061
00062
00063
00064 template <class _Tp, class _Alloc>
00065 class _Vector_base {
00066 public:
00067
00068 _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00069 typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
00070
00071 _Vector_base(const _Alloc& __a)
00072 : _M_start(0), _M_finish(0), _M_end_of_storage(__a, 0) {
00073 }
00074 _Vector_base(size_t __n, const _Alloc& __a)
00075 : _M_start(0), _M_finish(0), _M_end_of_storage(__a, 0)
00076 {
00077 _M_start = _M_end_of_storage.allocate(__n);
00078 _M_finish = _M_start;
00079 _M_end_of_storage._M_data = _M_start + __n;
00080 _STLP_MPWFIX_TRY _STLP_MPWFIX_CATCH
00081 }
00082
00083 ~_Vector_base() {
00084 if (_M_start !=0)
00085 _M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start);
00086 }
00087
00088 protected:
00089 _Tp* _M_start;
00090 _Tp* _M_finish;
00091 _STLP_alloc_proxy<_Tp*, _Tp, allocator_type> _M_end_of_storage;
00092 };
00093
00094 template <class _Tp, _STLP_DEFAULT_ALLOCATOR_SELECT(_Tp) >
00095 class vector : public _Vector_base<_Tp, _Alloc>
00096 {
00097 private:
00098 typedef _Vector_base<_Tp, _Alloc> _Base;
00099 public:
00100 typedef _Tp value_type;
00101 typedef value_type* pointer;
00102 typedef const value_type* const_pointer;
00103 typedef value_type* iterator;
00104 typedef const value_type* const_iterator;
00105
00106 public:
00107 typedef value_type& reference;
00108 typedef const value_type& const_reference;
00109 typedef size_t size_type;
00110 typedef ptrdiff_t difference_type;
00111 typedef random_access_iterator_tag _Iterator_category;
00112
00113 _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
00114 _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00115 typedef typename _Vector_base<_Tp, _Alloc>::allocator_type allocator_type;
00116
00117 allocator_type get_allocator() const {
00118 return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_end_of_storage, _Tp);
00119 }
00120 protected:
00121 typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _TrivialAss;
00122 typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _IsPODType;
00123
00124
00125 void _M_insert_overflow(pointer __position, const _Tp& __x, const __false_type&,
00126 size_type __fill_len, bool __atend = false) {
00127 const size_type __old_size = size();
00128 const size_type __len = __old_size + (max)(__old_size, __fill_len);
00129
00130 pointer __new_start = this->_M_end_of_storage.allocate(__len);
00131 pointer __new_finish = __new_start;
00132 _STLP_TRY {
00133 __new_finish = __uninitialized_copy(this->_M_start, __position, __new_start, __false_type());
00134
00135 if (__fill_len == 1) {
00136 _Construct(__new_finish, __x);
00137 ++__new_finish;
00138 } else
00139 __new_finish = __uninitialized_fill_n(__new_finish, __fill_len, __x, __false_type());
00140 if (!__atend)
00141
00142 __new_finish = __uninitialized_copy(__position, this->_M_finish, __new_finish, __false_type());
00143 }
00144 _STLP_UNWIND((_Destroy(__new_start,__new_finish),
00145 this->_M_end_of_storage.deallocate(__new_start,__len)));
00146 _M_clear();
00147 _M_set(__new_start, __new_finish, __new_start + __len);
00148 }
00149
00150 void _M_insert_overflow(pointer __position, const _Tp& __x, const __true_type&,
00151 size_type __fill_len, bool __atend = false) {
00152 const size_type __old_size = size();
00153 const size_type __len = __old_size + (max)(__old_size, __fill_len);
00154
00155 pointer __new_start = this->_M_end_of_storage.allocate(__len);
00156 pointer __new_finish = (pointer)__copy_trivial(this->_M_start, __position, __new_start);
00157
00158 __new_finish = fill_n(__new_finish, __fill_len, __x);
00159 if (!__atend)
00160
00161 __new_finish = (pointer)__copy_trivial(__position, this->_M_finish, __new_finish);
00162 _M_clear();
00163 _M_set(__new_start, __new_finish, __new_start + __len);
00164 }
00165
00166 void _M_range_check(size_type __n) const {
00167 if (__n >= size_type(this->_M_finish-this->_M_start))
00168 __stl_throw_out_of_range("vector");
00169 }
00170
00171 public:
00172 iterator begin() { return this->_M_start; }
00173 const_iterator begin() const { return this->_M_start; }
00174 iterator end() { return this->_M_finish; }
00175 const_iterator end() const { return this->_M_finish; }
00176
00177 reverse_iterator rbegin() { return reverse_iterator(end()); }
00178 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00179 reverse_iterator rend() { return reverse_iterator(begin()); }
00180 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00181
00182 size_type size() const { return size_type(this->_M_finish - this->_M_start); }
00183 size_type max_size() const { return size_type(-1) / sizeof(_Tp); }
00184 size_type capacity() const { return size_type(this->_M_end_of_storage._M_data - this->_M_start); }
00185 bool empty() const { return this->_M_start == this->_M_finish; }
00186
00187 reference operator[](size_type __n) { return *(begin() + __n); }
00188 const_reference operator[](size_type __n) const { return *(begin() + __n); }
00189
00190 reference front() { return *begin(); }
00191 const_reference front() const { return *begin(); }
00192 reference back() { return *(end() - 1); }
00193 const_reference back() const { return *(end() - 1); }
00194
00195 reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
00196 const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
00197
00198 explicit vector(const allocator_type& __a = allocator_type()) :
00199 _Vector_base<_Tp, _Alloc>(__a) {}
00200
00201 vector(size_type __n, const _Tp& __value,
00202 const allocator_type& __a = allocator_type())
00203 : _Vector_base<_Tp, _Alloc>(__n, __a) {
00204 this->_M_finish = uninitialized_fill_n(this->_M_start, __n, __value);
00205 }
00206
00207 explicit vector(size_type __n)
00208 : _Vector_base<_Tp, _Alloc>(__n, allocator_type() ) {
00209 this->_M_finish = uninitialized_fill_n(this->_M_start, __n, _Tp());
00210 }
00211
00212 vector(const vector<_Tp, _Alloc>& __x)
00213 : _Vector_base<_Tp, _Alloc>(__x.size(), __x.get_allocator()) {
00214 this->_M_finish = __uninitialized_copy((const_pointer)__x._M_start,
00215 (const_pointer)__x._M_finish, this->_M_start, _IsPODType());
00216 }
00217
00218 #if defined (_STLP_MEMBER_TEMPLATES)
00219
00220 template <class _Integer>
00221 void _M_initialize_aux(_Integer __n, _Integer __value, const __true_type&) {
00222 this->_M_start = this->_M_end_of_storage.allocate(__n);
00223 this->_M_end_of_storage._M_data = this->_M_start + __n;
00224 this->_M_finish = uninitialized_fill_n(this->_M_start, __n, __value);
00225 }
00226
00227 template <class _InputIterator>
00228 void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
00229 const __false_type&) {
00230 _M_range_initialize(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));
00231 }
00232
00233
00234 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
00235 template <class _InputIterator>
00236 vector(_InputIterator __first, _InputIterator __last) :
00237 _Vector_base<_Tp, _Alloc>(allocator_type()) {
00238 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00239 _M_initialize_aux(__first, __last, _Integral());
00240 }
00241 # endif
00242 template <class _InputIterator>
00243 vector(_InputIterator __first, _InputIterator __last,
00244 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL ) :
00245 _Vector_base<_Tp, _Alloc>(__a) {
00246 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00247 _M_initialize_aux(__first, __last, _Integral());
00248 }
00249
00250 #else
00251 vector(const _Tp* __first, const _Tp* __last,
00252 const allocator_type& __a = allocator_type())
00253 : _Vector_base<_Tp, _Alloc>(__last - __first, __a) {
00254 this->_M_finish = __uninitialized_copy(__first, __last, this->_M_start, _IsPODType());
00255 }
00256 #endif
00257
00258 ~vector() { _Destroy(this->_M_start, this->_M_finish); }
00259
00260 vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
00261
00262 void reserve(size_type __n);
00263
00264
00265
00266
00267
00268
00269 void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00270 void _M_fill_assign(size_type __n, const _Tp& __val);
00271
00272 #ifdef _STLP_MEMBER_TEMPLATES
00273 template <class _ForwardIter>
00274 void _M_assign_aux(_ForwardIter __first, _ForwardIter __last, const forward_iterator_tag &)
00275 #else
00276 void assign(const_iterator __first, const_iterator __last)
00277 #endif
00278 {
00279 size_type __len = distance(__first, __last);
00280
00281 if (__len > capacity()) {
00282 iterator __tmp = _M_allocate_and_copy(__len, __first, __last);
00283 _M_clear();
00284 _M_set(__tmp, __tmp + __len, __tmp + __len);
00285 }
00286 else if (size() >= __len) {
00287 iterator __new_finish = copy(__first, __last, this->_M_start);
00288 _Destroy(__new_finish, this->_M_finish);
00289 this->_M_finish = __new_finish;
00290 }
00291 else {
00292 # if defined ( _STLP_MEMBER_TEMPLATES )
00293 _ForwardIter __mid = __first;
00294 advance(__mid, size());
00295 # else
00296 const_iterator __mid = __first + size() ;
00297 # endif
00298 copy(__first, __mid, this->_M_start);
00299 this->_M_finish = __uninitialized_copy(__mid, __last, this->_M_finish, _IsPODType());
00300 }
00301 }
00302
00303 #ifdef _STLP_MEMBER_TEMPLATES
00304 template <class _InputIter>
00305 void _M_assign_aux(_InputIter __first, _InputIter __last,
00306 const input_iterator_tag &) {
00307 iterator __cur = begin();
00308 for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00309 *__cur = *__first;
00310 if (__first == __last)
00311 erase(__cur, end());
00312 else
00313 insert(end(), __first, __last);
00314 }
00315
00316 template <class _Integer>
00317 void _M_assign_dispatch(_Integer __n, _Integer __val, const __true_type&)
00318 { assign((size_type) __n, (_Tp) __val); }
00319
00320 template <class _InputIter>
00321 void _M_assign_dispatch(_InputIter __first, _InputIter __last, const __false_type&)
00322 { _M_assign_aux(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); }
00323
00324 template <class _InputIterator>
00325 void assign(_InputIterator __first, _InputIterator __last) {
00326 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00327 _M_assign_dispatch(__first, __last, _Integral());
00328 }
00329 #endif
00330
00331 void push_back(const _Tp& __x) {
00332 if (this->_M_finish != this->_M_end_of_storage._M_data) {
00333 _Construct(this->_M_finish, __x);
00334 ++this->_M_finish;
00335 }
00336 else
00337 _M_insert_overflow(this->_M_finish, __x, _IsPODType(), 1UL, true);
00338 }
00339
00340 void swap(vector<_Tp, _Alloc>& __x) {
00341 _STLP_STD::swap(this->_M_start, __x._M_start);
00342 _STLP_STD::swap(this->_M_finish, __x._M_finish);
00343 _STLP_STD::swap(this->_M_end_of_storage._M_data, __x._M_end_of_storage._M_data);
00344 }
00345
00346 iterator insert(iterator __position, const _Tp& __x) {
00347 size_type __n = __position - begin();
00348 if (this->_M_finish != this->_M_end_of_storage._M_data) {
00349 if (__position == end()) {
00350 _Construct(this->_M_finish, __x);
00351 ++this->_M_finish;
00352 } else {
00353 _Construct(this->_M_finish, *(this->_M_finish - 1));
00354 ++this->_M_finish;
00355 _Tp __x_copy = __x;
00356 __copy_backward_ptrs(__position, this->_M_finish - 2, this->_M_finish - 1, _TrivialAss());
00357 *__position = __x_copy;
00358 }
00359 }
00360 else
00361 _M_insert_overflow(__position, __x, _IsPODType(), 1UL);
00362 return begin() + __n;
00363 }
00364
00365 # ifndef _STLP_NO_ANACHRONISMS
00366 void push_back() { push_back(_Tp()); }
00367 iterator insert(iterator __position) { return insert(__position, _Tp()); }
00368 # endif
00369
00370 void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
00371
00372 #if defined ( _STLP_MEMBER_TEMPLATES)
00373
00374 template <class _Integer>
00375 void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
00376 const __true_type&) {
00377 _M_fill_insert(__pos, (size_type) __n, (_Tp) __val);
00378 }
00379
00380 template <class _InputIterator>
00381 void _M_insert_dispatch(iterator __pos,
00382 _InputIterator __first, _InputIterator __last,
00383 const __false_type&) {
00384 _M_range_insert(__pos, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));
00385 }
00386
00387
00388 template <class _InputIterator>
00389 void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00390 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00391 _M_insert_dispatch(__pos, __first, __last, _Integral());
00392 }
00393
00394 template <class _InputIterator>
00395 void _M_range_insert(iterator __pos,
00396 _InputIterator __first,
00397 _InputIterator __last,
00398 const input_iterator_tag &) {
00399 for ( ; __first != __last; ++__first) {
00400 __pos = insert(__pos, *__first);
00401 ++__pos;
00402 }
00403 }
00404
00405 template <class _ForwardIterator>
00406 void _M_range_insert(iterator __position,
00407 _ForwardIterator __first,
00408 _ForwardIterator __last,
00409 const forward_iterator_tag &)
00410 #else
00411 void insert(iterator __position,
00412 const_iterator __first, const_iterator __last)
00413 #endif
00414
00415 {
00416 if (__first != __last) {
00417 size_type __n = distance(__first, __last);
00418
00419 if (size_type(this->_M_end_of_storage._M_data - this->_M_finish) >= __n) {
00420 const size_type __elems_after = this->_M_finish - __position;
00421 pointer __old_finish = this->_M_finish;
00422 if (__elems_after > __n) {
00423 __uninitialized_copy(this->_M_finish - __n, this->_M_finish, this->_M_finish, _IsPODType());
00424 this->_M_finish += __n;
00425 __copy_backward_ptrs(__position, __old_finish - __n, __old_finish, _TrivialAss());
00426 copy(__first, __last, __position);
00427 }
00428 else {
00429 # if defined ( _STLP_MEMBER_TEMPLATES )
00430 _ForwardIterator __mid = __first;
00431 advance(__mid, __elems_after);
00432 # else
00433 const_pointer __mid = __first + __elems_after;
00434 # endif
00435 __uninitialized_copy(__mid, __last, this->_M_finish, _IsPODType());
00436 this->_M_finish += __n - __elems_after;
00437 __uninitialized_copy(__position, __old_finish, this->_M_finish, _IsPODType());
00438 this->_M_finish += __elems_after;
00439 copy(__first, __mid, __position);
00440 }
00441 }
00442 else {
00443 const size_type __old_size = size();
00444 const size_type __len = __old_size + (max)(__old_size, __n);
00445 pointer __new_start = this->_M_end_of_storage.allocate(__len);
00446 pointer __new_finish = __new_start;
00447 _STLP_TRY {
00448 __new_finish = __uninitialized_copy(this->_M_start, __position, __new_start, _IsPODType());
00449 __new_finish = __uninitialized_copy(__first, __last, __new_finish, _IsPODType());
00450 __new_finish = __uninitialized_copy(__position, this->_M_finish, __new_finish, _IsPODType());
00451 }
00452 _STLP_UNWIND((_Destroy(__new_start,__new_finish),
00453 this->_M_end_of_storage.deallocate(__new_start,__len)));
00454 _M_clear();
00455 _M_set(__new_start, __new_finish, __new_start + __len);
00456 }
00457 }
00458 }
00459 void insert (iterator __pos, size_type __n, const _Tp& __x)
00460 { _M_fill_insert(__pos, __n, __x); }
00461
00462 void pop_back() {
00463 --this->_M_finish;
00464 _Destroy(this->_M_finish);
00465 }
00466 iterator erase(iterator __position) {
00467 if (__position + 1 != end())
00468 __copy_ptrs(__position + 1, this->_M_finish, __position, _TrivialAss());
00469 --this->_M_finish;
00470 _Destroy(this->_M_finish);
00471 return __position;
00472 }
00473 iterator erase(iterator __first, iterator __last) {
00474 pointer __i = __copy_ptrs(__last, this->_M_finish, __first, _TrivialAss());
00475 _Destroy(__i, this->_M_finish);
00476 this->_M_finish = __i;
00477 return __first;
00478 }
00479
00480 void resize(size_type __new_size, const _Tp& __x) {
00481 if (__new_size < size())
00482 erase(begin() + __new_size, end());
00483 else
00484 insert(end(), __new_size - size(), __x);
00485 }
00486 void resize(size_type __new_size) { resize(__new_size, _Tp()); }
00487 void clear() {
00488 erase(begin(), end());
00489 }
00490
00491 protected:
00492
00493 void _M_clear() {
00494
00495 _Destroy(this->_M_start, this->_M_finish);
00496 this->_M_end_of_storage.deallocate(this->_M_start, this->_M_end_of_storage._M_data - this->_M_start);
00497
00498 }
00499
00500 void _M_set(pointer __s, pointer __f, pointer __e) {
00501 this->_M_start = __s;
00502 this->_M_finish = __f;
00503 this->_M_end_of_storage._M_data = __e;
00504 }
00505
00506 #ifdef _STLP_MEMBER_TEMPLATES
00507 template <class _ForwardIterator>
00508 pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
00509 _ForwardIterator __last)
00510 #else
00511 pointer _M_allocate_and_copy(size_type __n, const_pointer __first,
00512 const_pointer __last)
00513 #endif
00514 {
00515 pointer __result = this->_M_end_of_storage.allocate(__n);
00516 _STLP_TRY {
00517 #if !defined(__MRC__) //*TY 12/17/2000 - added workaround for MrCpp. it confuses on nested try/catch block
00518 __uninitialized_copy(__first, __last, __result, _IsPODType());
00519 #else
00520 uninitialized_copy(__first, __last, __result);
00521 #endif
00522 return __result;
00523 }
00524 _STLP_UNWIND(this->_M_end_of_storage.deallocate(__result, __n));
00525 # ifdef _STLP_THROW_RETURN_BUG
00526 return __result;
00527 # endif
00528 }
00529
00530
00531 #ifdef _STLP_MEMBER_TEMPLATES
00532 template <class _InputIterator>
00533 void _M_range_initialize(_InputIterator __first,
00534 _InputIterator __last, const input_iterator_tag &) {
00535 for ( ; __first != __last; ++__first)
00536 push_back(*__first);
00537 }
00538
00539 template <class _ForwardIterator>
00540 void _M_range_initialize(_ForwardIterator __first,
00541 _ForwardIterator __last, const forward_iterator_tag &) {
00542 size_type __n = distance(__first, __last);
00543 this->_M_start = this->_M_end_of_storage.allocate(__n);
00544 this->_M_end_of_storage._M_data = this->_M_start + __n;
00545 this->_M_finish = __uninitialized_copy(__first, __last, this->_M_start, _IsPODType());
00546 }
00547
00548 #endif
00549 };
00550
00551 # define _STLP_TEMPLATE_CONTAINER vector<_Tp, _Alloc>
00552 # define _STLP_TEMPLATE_HEADER template <class _Tp, class _Alloc>
00553 # include <stl/_relops_cont.h>
00554 # undef _STLP_TEMPLATE_CONTAINER
00555 # undef _STLP_TEMPLATE_HEADER
00556
00557 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00558 _STLP_EXPORT_TEMPLATE_CLASS allocator<void*>;
00559 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<void**, void*, allocator<void*> >;
00560 _STLP_EXPORT_TEMPLATE_CLASS _Vector_base<void*,allocator<void*> >;
00561 _STLP_EXPORT_TEMPLATE_CLASS vector<void*,allocator<void*> >;
00562 # endif
00563
00564 # undef vector
00565 # undef __vector__
00566 # define __vector__ __WORKAROUND_RENAME(vector)
00567
00568 _STLP_END_NAMESPACE
00569
00570 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00571 # include <stl/_vector.c>
00572 # endif
00573
00574 #ifndef _STLP_INTERNAL_BVECTOR_H
00575 # include <stl/_bvector.h>
00576 #endif
00577
00578 # if defined (_STLP_DEBUG)
00579 # include <stl/debug/_vector.h>
00580 # endif
00581
00582 # if defined (_STLP_USE_WRAPPER_FOR_ALLOC_PARAM)
00583 # include <stl/wrappers/_vector.h>
00584 # endif
00585
00586 #endif
00587
00588
00589
00590
00591