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
00031 #ifndef __SGI_STL_INTERNAL_VECTOR_H
00032 #define __SGI_STL_INTERNAL_VECTOR_H
00033
00034 #include <bits/stl_iterator_base_funcs.h>
00035 #include <bits/functexcept.h>
00036 #include <bits/concept_check.h>
00037
00038 namespace std
00039 {
00040
00041
00042
00043
00044
00045
00046
00047
00048 template <class _Tp, class _Allocator, bool _IsStatic>
00049 class _Vector_alloc_base {
00050 public:
00051 typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00052 allocator_type;
00053 allocator_type get_allocator() const { return _M_data_allocator; }
00054
00055 _Vector_alloc_base(const allocator_type& __a)
00056 : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
00057 {}
00058
00059 protected:
00060 allocator_type _M_data_allocator;
00061 _Tp* _M_start;
00062 _Tp* _M_finish;
00063 _Tp* _M_end_of_storage;
00064
00065 _Tp* _M_allocate(size_t __n)
00066 { return _M_data_allocator.allocate(__n); }
00067 void _M_deallocate(_Tp* __p, size_t __n)
00068 { if (__p) _M_data_allocator.deallocate(__p, __n); }
00069 };
00070
00071
00072
00073 template <class _Tp, class _Allocator>
00074 class _Vector_alloc_base<_Tp, _Allocator, true> {
00075 public:
00076 typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00077 allocator_type;
00078 allocator_type get_allocator() const { return allocator_type(); }
00079
00080 _Vector_alloc_base(const allocator_type&)
00081 : _M_start(0), _M_finish(0), _M_end_of_storage(0)
00082 {}
00083
00084 protected:
00085 _Tp* _M_start;
00086 _Tp* _M_finish;
00087 _Tp* _M_end_of_storage;
00088
00089 typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
00090 _Tp* _M_allocate(size_t __n)
00091 { return _Alloc_type::allocate(__n); }
00092 void _M_deallocate(_Tp* __p, size_t __n)
00093 { _Alloc_type::deallocate(__p, __n);}
00094 };
00095
00096 template <class _Tp, class _Alloc>
00097 struct _Vector_base
00098 : public _Vector_alloc_base<_Tp, _Alloc,
00099 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00100 {
00101 typedef _Vector_alloc_base<_Tp, _Alloc,
00102 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00103 _Base;
00104 typedef typename _Base::allocator_type allocator_type;
00105
00106 _Vector_base(const allocator_type& __a) : _Base(__a) {}
00107 _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
00108 _M_start = _M_allocate(__n);
00109 _M_finish = _M_start;
00110 _M_end_of_storage = _M_start + __n;
00111 }
00112
00113 ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
00114 };
00115
00116
00117 template <class _Tp, class _Alloc = allocator<_Tp> >
00118 class vector : protected _Vector_base<_Tp, _Alloc>
00119 {
00120
00121 __glibcpp_class_requires(_Tp, _SGIAssignableConcept);
00122
00123 private:
00124 typedef _Vector_base<_Tp, _Alloc> _Base;
00125 typedef vector<_Tp, _Alloc> vector_type;
00126 public:
00127 typedef _Tp value_type;
00128 typedef value_type* pointer;
00129 typedef const value_type* const_pointer;
00130 typedef __normal_iterator<pointer, vector_type> iterator;
00131 typedef __normal_iterator<const_pointer, vector_type> const_iterator;
00132 typedef value_type& reference;
00133 typedef const value_type& const_reference;
00134 typedef size_t size_type;
00135 typedef ptrdiff_t difference_type;
00136
00137 typedef typename _Base::allocator_type allocator_type;
00138 allocator_type get_allocator() const { return _Base::get_allocator(); }
00139
00140 typedef reverse_iterator<const_iterator> const_reverse_iterator;
00141 typedef reverse_iterator<iterator> reverse_iterator;
00142
00143 protected:
00144 using _Base::_M_allocate;
00145 using _Base::_M_deallocate;
00146 using _Base::_M_start;
00147 using _Base::_M_finish;
00148 using _Base::_M_end_of_storage;
00149
00150 protected:
00151 void _M_insert_aux(iterator __position, const _Tp& __x);
00152 void _M_insert_aux(iterator __position);
00153
00154 public:
00155 iterator begin() { return iterator (_M_start); }
00156 const_iterator begin() const
00157 { return const_iterator (_M_start); }
00158 iterator end() { return iterator (_M_finish); }
00159 const_iterator end() const { return const_iterator (_M_finish); }
00160
00161 reverse_iterator rbegin()
00162 { return reverse_iterator(end()); }
00163 const_reverse_iterator rbegin() const
00164 { return const_reverse_iterator(end()); }
00165 reverse_iterator rend()
00166 { return reverse_iterator(begin()); }
00167 const_reverse_iterator rend() const
00168 { return const_reverse_iterator(begin()); }
00169
00170 size_type size() const
00171 { return size_type(end() - begin()); }
00172 size_type max_size() const
00173 { return size_type(-1) / sizeof(_Tp); }
00174 size_type capacity() const
00175 { return size_type(const_iterator(_M_end_of_storage) - begin()); }
00176 bool empty() const
00177 { return begin() == end(); }
00178
00179 reference operator[](size_type __n) { return *(begin() + __n); }
00180 const_reference operator[](size_type __n) const { return *(begin() + __n); }
00181
00182 void _M_range_check(size_type __n) const {
00183 if (__n >= this->size())
00184 __throw_out_of_range("vector");
00185 }
00186
00187 reference at(size_type __n)
00188 { _M_range_check(__n); return (*this)[__n]; }
00189 const_reference at(size_type __n) const
00190 { _M_range_check(__n); return (*this)[__n]; }
00191
00192 explicit vector(const allocator_type& __a = allocator_type())
00193 : _Base(__a) {}
00194
00195 vector(size_type __n, const _Tp& __value,
00196 const allocator_type& __a = allocator_type())
00197 : _Base(__n, __a)
00198 { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
00199
00200 explicit vector(size_type __n)
00201 : _Base(__n, allocator_type())
00202 { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
00203
00204 vector(const vector<_Tp, _Alloc>& __x)
00205 : _Base(__x.size(), __x.get_allocator())
00206 { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
00207
00208
00209 template <class _InputIterator>
00210 vector(_InputIterator __first, _InputIterator __last,
00211 const allocator_type& __a = allocator_type()) : _Base(__a) {
00212 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00213 _M_initialize_aux(__first, __last, _Integral());
00214 }
00215
00216 template <class _Integer>
00217 void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
00218 _M_start = _M_allocate(__n);
00219 _M_end_of_storage = _M_start + __n;
00220 _M_finish = uninitialized_fill_n(_M_start, __n, __value);
00221 }
00222
00223 template <class _InputIterator>
00224 void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
00225 __false_type) {
00226 _M_range_initialize(__first, __last, __iterator_category(__first));
00227 }
00228
00229 ~vector() { destroy(_M_start, _M_finish); }
00230
00231 vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
00232 void reserve(size_type __n) {
00233 if (capacity() < __n) {
00234 const size_type __old_size = size();
00235 pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
00236 destroy(_M_start, _M_finish);
00237 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00238 _M_start = __tmp;
00239 _M_finish = __tmp + __old_size;
00240 _M_end_of_storage = _M_start + __n;
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249 void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00250 void _M_fill_assign(size_type __n, const _Tp& __val);
00251
00252 template <class _InputIterator>
00253 void assign(_InputIterator __first, _InputIterator __last) {
00254 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00255 _M_assign_dispatch(__first, __last, _Integral());
00256 }
00257
00258 template <class _Integer>
00259 void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00260 { _M_fill_assign((size_type) __n, (_Tp) __val); }
00261
00262 template <class _InputIter>
00263 void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
00264 { _M_assign_aux(__first, __last, __iterator_category(__first)); }
00265
00266 template <class _InputIterator>
00267 void _M_assign_aux(_InputIterator __first, _InputIterator __last,
00268 input_iterator_tag);
00269
00270 template <class _ForwardIterator>
00271 void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00272 forward_iterator_tag);
00273
00274 reference front() { return *begin(); }
00275 const_reference front() const { return *begin(); }
00276 reference back() { return *(end() - 1); }
00277 const_reference back() const { return *(end() - 1); }
00278
00279 void push_back(const _Tp& __x) {
00280 if (_M_finish != _M_end_of_storage) {
00281 construct(_M_finish, __x);
00282 ++_M_finish;
00283 }
00284 else
00285 _M_insert_aux(end(), __x);
00286 }
00287 void push_back() {
00288 if (_M_finish != _M_end_of_storage) {
00289 construct(_M_finish);
00290 ++_M_finish;
00291 }
00292 else
00293 _M_insert_aux(end());
00294 }
00295 void swap(vector<_Tp, _Alloc>& __x) {
00296 std::swap(_M_start, __x._M_start);
00297 std::swap(_M_finish, __x._M_finish);
00298 std::swap(_M_end_of_storage, __x._M_end_of_storage);
00299 }
00300
00301 iterator insert(iterator __position, const _Tp& __x) {
00302 size_type __n = __position - begin();
00303 if (_M_finish != _M_end_of_storage && __position == end()) {
00304 construct(_M_finish, __x);
00305 ++_M_finish;
00306 }
00307 else
00308 _M_insert_aux(iterator(__position), __x);
00309 return begin() + __n;
00310 }
00311 iterator insert(iterator __position) {
00312 size_type __n = __position - begin();
00313 if (_M_finish != _M_end_of_storage && __position == end()) {
00314 construct(_M_finish);
00315 ++_M_finish;
00316 }
00317 else
00318 _M_insert_aux(iterator(__position));
00319 return begin() + __n;
00320 }
00321
00322 template <class _InputIterator>
00323 void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00324 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00325 _M_insert_dispatch(__pos, __first, __last, _Integral());
00326 }
00327
00328 template <class _Integer>
00329 void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
00330 __true_type)
00331 { _M_fill_insert(__pos, (size_type) __n, (_Tp) __val); }
00332
00333 template <class _InputIterator>
00334 void _M_insert_dispatch(iterator __pos,
00335 _InputIterator __first, _InputIterator __last,
00336 __false_type) {
00337 _M_range_insert(__pos, __first, __last, __iterator_category(__first));
00338 }
00339
00340 void insert (iterator __pos, size_type __n, const _Tp& __x)
00341 { _M_fill_insert(__pos, __n, __x); }
00342
00343 void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
00344
00345 void pop_back() {
00346 --_M_finish;
00347 destroy(_M_finish);
00348 }
00349 iterator erase(iterator __position) {
00350 if (__position + 1 != end())
00351 copy(__position + 1, end(), __position);
00352 --_M_finish;
00353 destroy(_M_finish);
00354 return __position;
00355 }
00356 iterator erase(iterator __first, iterator __last) {
00357 iterator __i(copy(__last, end(), __first));
00358 destroy(__i, end());
00359 _M_finish = _M_finish - (__last - __first);
00360 return __first;
00361 }
00362
00363 void resize(size_type __new_size, const _Tp& __x) {
00364 if (__new_size < size())
00365 erase(begin() + __new_size, end());
00366 else
00367 insert(end(), __new_size - size(), __x);
00368 }
00369 void resize(size_type __new_size) { resize(__new_size, _Tp()); }
00370 void clear() { erase(begin(), end()); }
00371
00372 protected:
00373
00374 template <class _ForwardIterator>
00375 pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
00376 _ForwardIterator __last)
00377 {
00378 pointer __result = _M_allocate(__n);
00379 __STL_TRY {
00380 uninitialized_copy(__first, __last, __result);
00381 return __result;
00382 }
00383 __STL_UNWIND(_M_deallocate(__result, __n));
00384 }
00385
00386 template <class _InputIterator>
00387 void _M_range_initialize(_InputIterator __first,
00388 _InputIterator __last, input_iterator_tag)
00389 {
00390 for ( ; __first != __last; ++__first)
00391 push_back(*__first);
00392 }
00393
00394
00395 template <class _ForwardIterator>
00396 void _M_range_initialize(_ForwardIterator __first,
00397 _ForwardIterator __last, forward_iterator_tag)
00398 {
00399 size_type __n = 0;
00400 distance(__first, __last, __n);
00401 _M_start = _M_allocate(__n);
00402 _M_end_of_storage = _M_start + __n;
00403 _M_finish = uninitialized_copy(__first, __last, _M_start);
00404 }
00405
00406 template <class _InputIterator>
00407 void _M_range_insert(iterator __pos,
00408 _InputIterator __first, _InputIterator __last,
00409 input_iterator_tag);
00410
00411 template <class _ForwardIterator>
00412 void _M_range_insert(iterator __pos,
00413 _ForwardIterator __first, _ForwardIterator __last,
00414 forward_iterator_tag);
00415 };
00416
00417 template <class _Tp, class _Alloc>
00418 inline bool
00419 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00420 {
00421 return __x.size() == __y.size() &&
00422 equal(__x.begin(), __x.end(), __y.begin());
00423 }
00424
00425 template <class _Tp, class _Alloc>
00426 inline bool
00427 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00428 {
00429 return lexicographical_compare(__x.begin(), __x.end(),
00430 __y.begin(), __y.end());
00431 }
00432
00433 template <class _Tp, class _Alloc>
00434 inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
00435 {
00436 __x.swap(__y);
00437 }
00438
00439 template <class _Tp, class _Alloc>
00440 inline bool
00441 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00442 return !(__x == __y);
00443 }
00444
00445 template <class _Tp, class _Alloc>
00446 inline bool
00447 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00448 return __y < __x;
00449 }
00450
00451 template <class _Tp, class _Alloc>
00452 inline bool
00453 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00454 return !(__y < __x);
00455 }
00456
00457 template <class _Tp, class _Alloc>
00458 inline bool
00459 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00460 return !(__x < __y);
00461 }
00462
00463 template <class _Tp, class _Alloc>
00464 vector<_Tp,_Alloc>&
00465 vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
00466 {
00467 if (&__x != this) {
00468 const size_type __xlen = __x.size();
00469 if (__xlen > capacity()) {
00470 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
00471 destroy(_M_start, _M_finish);
00472 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00473 _M_start = __tmp;
00474 _M_end_of_storage = _M_start + __xlen;
00475 }
00476 else if (size() >= __xlen) {
00477 iterator __i(copy(__x.begin(), __x.end(), begin()));
00478 destroy(__i, end());
00479 }
00480 else {
00481 copy(__x.begin(), __x.begin() + size(), _M_start);
00482 uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
00483 }
00484 _M_finish = _M_start + __xlen;
00485 }
00486 return *this;
00487 }
00488
00489 template <class _Tp, class _Alloc>
00490 void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val)
00491 {
00492 if (__n > capacity()) {
00493 vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
00494 __tmp.swap(*this);
00495 }
00496 else if (__n > size()) {
00497 fill(begin(), end(), __val);
00498 _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
00499 }
00500 else
00501 erase(fill_n(begin(), __n, __val), end());
00502 }
00503
00504 template <class _Tp, class _Alloc> template <class _InputIter>
00505 void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
00506 input_iterator_tag) {
00507 iterator __cur(begin());
00508 for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00509 *__cur = *__first;
00510 if (__first == __last)
00511 erase(__cur, end());
00512 else
00513 insert(end(), __first, __last);
00514 }
00515
00516 template <class _Tp, class _Alloc> template <class _ForwardIter>
00517 void
00518 vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
00519 forward_iterator_tag) {
00520 size_type __len = 0;
00521 distance(__first, __last, __len);
00522
00523 if (__len > capacity()) {
00524 pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
00525 destroy(_M_start, _M_finish);
00526 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00527 _M_start = __tmp;
00528 _M_end_of_storage = _M_finish = _M_start + __len;
00529 }
00530 else if (size() >= __len) {
00531 iterator __new_finish(copy(__first, __last, _M_start));
00532 destroy(__new_finish, end());
00533 _M_finish = __new_finish.base();
00534 }
00535 else {
00536 _ForwardIter __mid = __first;
00537 advance(__mid, size());
00538 copy(__first, __mid, _M_start);
00539 _M_finish = uninitialized_copy(__mid, __last, _M_finish);
00540 }
00541 }
00542
00543 template <class _Tp, class _Alloc>
00544 void
00545 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
00546 {
00547 if (_M_finish != _M_end_of_storage) {
00548 construct(_M_finish, *(_M_finish - 1));
00549 ++_M_finish;
00550 _Tp __x_copy = __x;
00551 copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
00552 *__position = __x_copy;
00553 }
00554 else {
00555 const size_type __old_size = size();
00556 const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
00557 iterator __new_start(_M_allocate(__len));
00558 iterator __new_finish(__new_start);
00559 __STL_TRY {
00560 __new_finish = uninitialized_copy(iterator(_M_start), __position,
00561 __new_start);
00562 construct(__new_finish.base(), __x);
00563 ++__new_finish;
00564 __new_finish = uninitialized_copy(__position, iterator(_M_finish),
00565 __new_finish);
00566 }
00567 __STL_UNWIND((destroy(__new_start,__new_finish),
00568 _M_deallocate(__new_start.base(),__len)));
00569 destroy(begin(), end());
00570 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00571 _M_start = __new_start.base();
00572 _M_finish = __new_finish.base();
00573 _M_end_of_storage = __new_start.base() + __len;
00574 }
00575 }
00576
00577 template <class _Tp, class _Alloc>
00578 void
00579 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
00580 {
00581 if (_M_finish != _M_end_of_storage) {
00582 construct(_M_finish, *(_M_finish - 1));
00583 ++_M_finish;
00584 copy_backward(__position, iterator(_M_finish - 2),
00585 iterator(_M_finish - 1));
00586 *__position = _Tp();
00587 }
00588 else {
00589 const size_type __old_size = size();
00590 const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
00591 pointer __new_start = _M_allocate(__len);
00592 pointer __new_finish = __new_start;
00593 __STL_TRY {
00594 __new_finish = uninitialized_copy(iterator(_M_start), __position,
00595 __new_start);
00596 construct(__new_finish);
00597 ++__new_finish;
00598 __new_finish = uninitialized_copy(__position, iterator(_M_finish),
00599 __new_finish);
00600 }
00601 __STL_UNWIND((destroy(__new_start,__new_finish),
00602 _M_deallocate(__new_start,__len)));
00603 destroy(begin(), end());
00604 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00605 _M_start = __new_start;
00606 _M_finish = __new_finish;
00607 _M_end_of_storage = __new_start + __len;
00608 }
00609 }
00610
00611 template <class _Tp, class _Alloc>
00612 void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
00613 const _Tp& __x)
00614 {
00615 if (__n != 0) {
00616 if (size_type(_M_end_of_storage - _M_finish) >= __n) {
00617 _Tp __x_copy = __x;
00618 const size_type __elems_after = end() - __position;
00619 iterator __old_finish(_M_finish);
00620 if (__elems_after > __n) {
00621 uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
00622 _M_finish += __n;
00623 copy_backward(__position, __old_finish - __n, __old_finish);
00624 fill(__position, __position + __n, __x_copy);
00625 }
00626 else {
00627 uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
00628 _M_finish += __n - __elems_after;
00629 uninitialized_copy(__position, __old_finish, _M_finish);
00630 _M_finish += __elems_after;
00631 fill(__position, __old_finish, __x_copy);
00632 }
00633 }
00634 else {
00635 const size_type __old_size = size();
00636 const size_type __len = __old_size + max(__old_size, __n);
00637 iterator __new_start(_M_allocate(__len));
00638 iterator __new_finish(__new_start);
00639 __STL_TRY {
00640 __new_finish = uninitialized_copy(begin(), __position, __new_start);
00641 __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
00642 __new_finish
00643 = uninitialized_copy(__position, end(), __new_finish);
00644 }
00645 __STL_UNWIND((destroy(__new_start,__new_finish),
00646 _M_deallocate(__new_start.base(),__len)));
00647 destroy(_M_start, _M_finish);
00648 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00649 _M_start = __new_start.base();
00650 _M_finish = __new_finish.base();
00651 _M_end_of_storage = __new_start.base() + __len;
00652 }
00653 }
00654 }
00655
00656 template <class _Tp, class _Alloc> template <class _InputIterator>
00657 void
00658 vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
00659 _InputIterator __first,
00660 _InputIterator __last,
00661 input_iterator_tag)
00662 {
00663 for ( ; __first != __last; ++__first) {
00664 __pos = insert(__pos, *__first);
00665 ++__pos;
00666 }
00667 }
00668
00669 template <class _Tp, class _Alloc> template <class _ForwardIterator>
00670 void
00671 vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
00672 _ForwardIterator __first,
00673 _ForwardIterator __last,
00674 forward_iterator_tag)
00675 {
00676 if (__first != __last) {
00677 size_type __n = 0;
00678 distance(__first, __last, __n);
00679 if (size_type(_M_end_of_storage - _M_finish) >= __n) {
00680 const size_type __elems_after = end() - __position;
00681 iterator __old_finish(_M_finish);
00682 if (__elems_after > __n) {
00683 uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
00684 _M_finish += __n;
00685 copy_backward(__position, __old_finish - __n, __old_finish);
00686 copy(__first, __last, __position);
00687 }
00688 else {
00689 _ForwardIterator __mid = __first;
00690 advance(__mid, __elems_after);
00691 uninitialized_copy(__mid, __last, _M_finish);
00692 _M_finish += __n - __elems_after;
00693 uninitialized_copy(__position, __old_finish, _M_finish);
00694 _M_finish += __elems_after;
00695 copy(__first, __mid, __position);
00696 }
00697 }
00698 else {
00699 const size_type __old_size = size();
00700 const size_type __len = __old_size + max(__old_size, __n);
00701 iterator __new_start(_M_allocate(__len));
00702 iterator __new_finish(__new_start);
00703 __STL_TRY {
00704 __new_finish = uninitialized_copy(iterator(_M_start),
00705 __position, __new_start);
00706 __new_finish = uninitialized_copy(__first, __last, __new_finish);
00707 __new_finish
00708 = uninitialized_copy(__position, iterator(_M_finish), __new_finish);
00709 }
00710 __STL_UNWIND((destroy(__new_start,__new_finish),
00711 _M_deallocate(__new_start.base(),__len)));
00712 destroy(_M_start, _M_finish);
00713 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00714 _M_start = __new_start.base();
00715 _M_finish = __new_finish.base();
00716 _M_end_of_storage = __new_start.base() + __len;
00717 }
00718 }
00719 }
00720
00721 }
00722
00723 #endif
00724
00725
00726
00727