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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00061 #ifndef __GLIBCPP_INTERNAL_VECTOR_H
00062 #define __GLIBCPP_INTERNAL_VECTOR_H
00063
00064 #include <bits/stl_iterator_base_funcs.h>
00065 #include <bits/functexcept.h>
00066 #include <bits/concept_check.h>
00067
00068 namespace std
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078 template <class _Tp, class _Allocator, bool _IsStatic>
00079 class _Vector_alloc_base {
00080 public:
00081 typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00082 allocator_type;
00083 allocator_type get_allocator() const { return _M_data_allocator; }
00084
00085 _Vector_alloc_base(const allocator_type& __a)
00086 : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
00087 {}
00088
00089 protected:
00090 allocator_type _M_data_allocator;
00091 _Tp* _M_start;
00092 _Tp* _M_finish;
00093 _Tp* _M_end_of_storage;
00094
00095 _Tp* _M_allocate(size_t __n)
00096 { return _M_data_allocator.allocate(__n); }
00097 void _M_deallocate(_Tp* __p, size_t __n)
00098 { if (__p) _M_data_allocator.deallocate(__p, __n); }
00099 };
00100
00101
00102
00103 template <class _Tp, class _Allocator>
00104 class _Vector_alloc_base<_Tp, _Allocator, true> {
00105 public:
00106 typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00107 allocator_type;
00108 allocator_type get_allocator() const { return allocator_type(); }
00109
00110 _Vector_alloc_base(const allocator_type&)
00111 : _M_start(0), _M_finish(0), _M_end_of_storage(0)
00112 {}
00113
00114 protected:
00115 _Tp* _M_start;
00116 _Tp* _M_finish;
00117 _Tp* _M_end_of_storage;
00118
00119 typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
00120 _Tp* _M_allocate(size_t __n)
00121 { return _Alloc_type::allocate(__n); }
00122 void _M_deallocate(_Tp* __p, size_t __n)
00123 { _Alloc_type::deallocate(__p, __n);}
00124 };
00125
00126 template <class _Tp, class _Alloc>
00127 struct _Vector_base
00128 : public _Vector_alloc_base<_Tp, _Alloc,
00129 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00130 {
00131 typedef _Vector_alloc_base<_Tp, _Alloc,
00132 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00133 _Base;
00134 typedef typename _Base::allocator_type allocator_type;
00135
00136 _Vector_base(const allocator_type& __a) : _Base(__a) {}
00137 _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
00138 _M_start = _M_allocate(__n);
00139 _M_finish = _M_start;
00140 _M_end_of_storage = _M_start + __n;
00141 }
00142
00143 ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
00144 };
00145
00146
00165 template <class _Tp, class _Alloc = allocator<_Tp> >
00166 class vector : protected _Vector_base<_Tp, _Alloc>
00167 {
00168
00169 __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
00170
00171 private:
00172 typedef _Vector_base<_Tp, _Alloc> _Base;
00173 typedef vector<_Tp, _Alloc> vector_type;
00174 public:
00175 typedef _Tp value_type;
00176 typedef value_type* pointer;
00177 typedef const value_type* const_pointer;
00178 typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
00179 typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
00180 const_iterator;
00181 typedef value_type& reference;
00182 typedef const value_type& const_reference;
00183 typedef size_t size_type;
00184 typedef ptrdiff_t difference_type;
00185
00186 typedef typename _Base::allocator_type allocator_type;
00187 allocator_type get_allocator() const { return _Base::get_allocator(); }
00188
00189 typedef reverse_iterator<const_iterator> const_reverse_iterator;
00190 typedef reverse_iterator<iterator> reverse_iterator;
00191
00192 protected:
00193 using _Base::_M_allocate;
00194 using _Base::_M_deallocate;
00195 using _Base::_M_start;
00196 using _Base::_M_finish;
00197 using _Base::_M_end_of_storage;
00198
00199 protected:
00200 void _M_insert_aux(iterator __position, const _Tp& __x);
00201 void _M_insert_aux(iterator __position);
00202
00203 public:
00208 iterator begin() { return iterator (_M_start); }
00209
00214 const_iterator begin() const
00215 { return const_iterator (_M_start); }
00216
00221 iterator end() { return iterator (_M_finish); }
00222
00227 const_iterator end() const { return const_iterator (_M_finish); }
00228
00233 reverse_iterator rbegin()
00234 { return reverse_iterator(end()); }
00235
00240 const_reverse_iterator rbegin() const
00241 { return const_reverse_iterator(end()); }
00242
00248 reverse_iterator rend()
00249 { return reverse_iterator(begin()); }
00250
00256 const_reverse_iterator rend() const
00257 { return const_reverse_iterator(begin()); }
00258
00260 size_type size() const
00261 { return size_type(end() - begin()); }
00262
00264 size_type max_size() const
00265 { return size_type(-1) / sizeof(_Tp); }
00266
00271 size_type capacity() const
00272 { return size_type(const_iterator(_M_end_of_storage) - begin()); }
00273
00277 bool empty() const
00278 { return begin() == end(); }
00279
00289 reference operator[](size_type __n) { return *(begin() + __n); }
00290
00300 const_reference operator[](size_type __n) const { return *(begin() + __n); }
00301
00302 void _M_range_check(size_type __n) const {
00303 if (__n >= this->size())
00304 __throw_out_of_range("vector");
00305 }
00306
00316 reference at(size_type __n)
00317 { _M_range_check(__n); return (*this)[__n]; }
00318
00328 const_reference at(size_type __n) const
00329 { _M_range_check(__n); return (*this)[__n]; }
00330
00331
00332 explicit vector(const allocator_type& __a = allocator_type())
00333 : _Base(__a) {}
00334
00335 vector(size_type __n, const _Tp& __value,
00336 const allocator_type& __a = allocator_type())
00337 : _Base(__n, __a)
00338 { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
00339
00340 explicit vector(size_type __n)
00341 : _Base(__n, allocator_type())
00342 { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
00343
00344 vector(const vector<_Tp, _Alloc>& __x)
00345 : _Base(__x.size(), __x.get_allocator())
00346 { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
00347
00348
00349 template <class _InputIterator>
00350 vector(_InputIterator __first, _InputIterator __last,
00351 const allocator_type& __a = allocator_type())
00352 : _Base(__a)
00353 {
00354 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00355 _M_initialize_aux(__first, __last, _Integral());
00356 }
00357
00358 template <class _Integer>
00359 void _M_initialize_aux(_Integer __n, _Integer __value, __true_type)
00360 {
00361 _M_start = _M_allocate(__n);
00362 _M_end_of_storage = _M_start + __n;
00363 _M_finish = uninitialized_fill_n(_M_start, __n, __value);
00364 }
00365
00366 template<class _InputIterator>
00367 void
00368 _M_initialize_aux(_InputIterator __first, _InputIterator __last, __false_type)
00369 {
00370 typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
00371 _M_range_initialize(__first, __last, _IterCategory());
00372 }
00373
00374 ~vector()
00375 { _Destroy(_M_start, _M_finish); }
00376
00377 vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
00378
00393 void reserve(size_type __n) {
00394 if (capacity() < __n) {
00395 const size_type __old_size = size();
00396 pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
00397 _Destroy(_M_start, _M_finish);
00398 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00399 _M_start = __tmp;
00400 _M_finish = __tmp + __old_size;
00401 _M_end_of_storage = _M_start + __n;
00402 }
00403 }
00404
00405
00406
00407
00408
00409
00421 void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00422 void _M_fill_assign(size_type __n, const _Tp& __val);
00423
00424 template<class _InputIterator>
00425 void
00426 assign(_InputIterator __first, _InputIterator __last)
00427 {
00428 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00429 _M_assign_dispatch(__first, __last, _Integral());
00430 }
00431
00432 template<class _Integer>
00433 void
00434 _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00435 { _M_fill_assign((size_type) __n, (_Tp) __val); }
00436
00437 template<class _InputIter>
00438 void
00439 _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
00440 {
00441 typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
00442 _M_assign_aux(__first, __last, _IterCategory());
00443 }
00444
00445 template <class _InputIterator>
00446 void
00447 _M_assign_aux(_InputIterator __first, _InputIterator __last,
00448 input_iterator_tag);
00449
00450 template <class _ForwardIterator>
00451 void
00452 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00453 forward_iterator_tag);
00454
00459 reference front() { return *begin(); }
00460
00465 const_reference front() const { return *begin(); }
00466
00471 reference back() { return *(end() - 1); }
00472
00477 const_reference back() const { return *(end() - 1); }
00478
00488 void
00489 push_back(const _Tp& __x)
00490 {
00491 if (_M_finish != _M_end_of_storage) {
00492 _Construct(_M_finish, __x);
00493 ++_M_finish;
00494 }
00495 else
00496 _M_insert_aux(end(), __x);
00497 }
00498
00499 #ifdef _GLIBCPP_DEPRECATED
00500
00507 void
00508 push_back()
00509 {
00510 if (_M_finish != _M_end_of_storage) {
00511 _Construct(_M_finish);
00512 ++_M_finish;
00513 }
00514 else
00515 _M_insert_aux(end());
00516 }
00517 #endif
00518
00519 void
00520 swap(vector<_Tp, _Alloc>& __x)
00521 {
00522 std::swap(_M_start, __x._M_start);
00523 std::swap(_M_finish, __x._M_finish);
00524 std::swap(_M_end_of_storage, __x._M_end_of_storage);
00525 }
00526
00538 iterator
00539 insert(iterator __position, const _Tp& __x)
00540 {
00541 size_type __n = __position - begin();
00542 if (_M_finish != _M_end_of_storage && __position == end()) {
00543 _Construct(_M_finish, __x);
00544 ++_M_finish;
00545 }
00546 else
00547 _M_insert_aux(iterator(__position), __x);
00548 return begin() + __n;
00549 }
00550
00562 iterator
00563 insert(iterator __position)
00564 {
00565 size_type __n = __position - begin();
00566 if (_M_finish != _M_end_of_storage && __position == end()) {
00567 _Construct(_M_finish);
00568 ++_M_finish;
00569 }
00570 else
00571 _M_insert_aux(iterator(__position));
00572 return begin() + __n;
00573 }
00574
00575
00576 template<class _InputIterator>
00577 void
00578 insert(iterator __pos, _InputIterator __first, _InputIterator __last)
00579 {
00580 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00581 _M_insert_dispatch(__pos, __first, __last, _Integral());
00582 }
00583
00584 template <class _Integer>
00585 void
00586 _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type)
00587 { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
00588
00589 template<class _InputIterator>
00590 void
00591 _M_insert_dispatch(iterator __pos,
00592 _InputIterator __first, _InputIterator __last,
00593 __false_type)
00594 {
00595 typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
00596 _M_range_insert(__pos, __first, __last, _IterCategory());
00597 }
00598
00612 void insert (iterator __pos, size_type __n, const _Tp& __x)
00613 { _M_fill_insert(__pos, __n, __x); }
00614
00615 void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
00616
00626 void pop_back() {
00627 --_M_finish;
00628 _Destroy(_M_finish);
00629 }
00630
00645 iterator erase(iterator __position) {
00646 if (__position + 1 != end())
00647 copy(__position + 1, end(), __position);
00648 --_M_finish;
00649 _Destroy(_M_finish);
00650 return __position;
00651 }
00652
00668 iterator erase(iterator __first, iterator __last) {
00669 iterator __i(copy(__last, end(), __first));
00670 _Destroy(__i, end());
00671 _M_finish = _M_finish - (__last - __first);
00672 return __first;
00673 }
00674
00685 void resize(size_type __new_size, const _Tp& __x) {
00686 if (__new_size < size())
00687 erase(begin() + __new_size, end());
00688 else
00689 insert(end(), __new_size - size(), __x);
00690 }
00691
00701 void resize(size_type __new_size) { resize(__new_size, _Tp()); }
00702
00709 void clear() { erase(begin(), end()); }
00710
00711 protected:
00712
00713 template <class _ForwardIterator>
00714 pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
00715 _ForwardIterator __last)
00716 {
00717 pointer __result = _M_allocate(__n);
00718 try {
00719 uninitialized_copy(__first, __last, __result);
00720 return __result;
00721 }
00722 catch(...)
00723 {
00724 _M_deallocate(__result, __n);
00725 __throw_exception_again;
00726 }
00727 }
00728
00729 template <class _InputIterator>
00730 void _M_range_initialize(_InputIterator __first,
00731 _InputIterator __last, input_iterator_tag)
00732 {
00733 for ( ; __first != __last; ++__first)
00734 push_back(*__first);
00735 }
00736
00737
00738 template <class _ForwardIterator>
00739 void _M_range_initialize(_ForwardIterator __first,
00740 _ForwardIterator __last, forward_iterator_tag)
00741 {
00742 size_type __n = distance(__first, __last);
00743 _M_start = _M_allocate(__n);
00744 _M_end_of_storage = _M_start + __n;
00745 _M_finish = uninitialized_copy(__first, __last, _M_start);
00746 }
00747
00748 template <class _InputIterator>
00749 void _M_range_insert(iterator __pos,
00750 _InputIterator __first, _InputIterator __last,
00751 input_iterator_tag);
00752
00753 template <class _ForwardIterator>
00754 void _M_range_insert(iterator __pos,
00755 _ForwardIterator __first, _ForwardIterator __last,
00756 forward_iterator_tag);
00757 };
00758
00759 template <class _Tp, class _Alloc>
00760 inline bool
00761 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00762 {
00763 return __x.size() == __y.size() &&
00764 equal(__x.begin(), __x.end(), __y.begin());
00765 }
00766
00767 template <class _Tp, class _Alloc>
00768 inline bool
00769 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00770 {
00771 return lexicographical_compare(__x.begin(), __x.end(),
00772 __y.begin(), __y.end());
00773 }
00774
00775 template <class _Tp, class _Alloc>
00776 inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
00777 {
00778 __x.swap(__y);
00779 }
00780
00781 template <class _Tp, class _Alloc>
00782 inline bool
00783 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00784 return !(__x == __y);
00785 }
00786
00787 template <class _Tp, class _Alloc>
00788 inline bool
00789 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00790 return __y < __x;
00791 }
00792
00793 template <class _Tp, class _Alloc>
00794 inline bool
00795 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00796 return !(__y < __x);
00797 }
00798
00799 template <class _Tp, class _Alloc>
00800 inline bool
00801 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
00802 return !(__x < __y);
00803 }
00804
00805 template <class _Tp, class _Alloc>
00806 vector<_Tp,_Alloc>&
00807 vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
00808 {
00809 if (&__x != this) {
00810 const size_type __xlen = __x.size();
00811 if (__xlen > capacity()) {
00812 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
00813 _Destroy(_M_start, _M_finish);
00814 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00815 _M_start = __tmp;
00816 _M_end_of_storage = _M_start + __xlen;
00817 }
00818 else if (size() >= __xlen) {
00819 iterator __i(copy(__x.begin(), __x.end(), begin()));
00820 _Destroy(__i, end());
00821 }
00822 else {
00823 copy(__x.begin(), __x.begin() + size(), _M_start);
00824 uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
00825 }
00826 _M_finish = _M_start + __xlen;
00827 }
00828 return *this;
00829 }
00830
00831 template <class _Tp, class _Alloc>
00832 void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val)
00833 {
00834 if (__n > capacity()) {
00835 vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
00836 __tmp.swap(*this);
00837 }
00838 else if (__n > size()) {
00839 fill(begin(), end(), __val);
00840 _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
00841 }
00842 else
00843 erase(fill_n(begin(), __n, __val), end());
00844 }
00845
00846 template <class _Tp, class _Alloc> template <class _InputIter>
00847 void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
00848 input_iterator_tag) {
00849 iterator __cur(begin());
00850 for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00851 *__cur = *__first;
00852 if (__first == __last)
00853 erase(__cur, end());
00854 else
00855 insert(end(), __first, __last);
00856 }
00857
00858 template <class _Tp, class _Alloc> template <class _ForwardIter>
00859 void
00860 vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
00861 forward_iterator_tag) {
00862 size_type __len = distance(__first, __last);
00863
00864 if (__len > capacity()) {
00865 pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
00866 _Destroy(_M_start, _M_finish);
00867 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00868 _M_start = __tmp;
00869 _M_end_of_storage = _M_finish = _M_start + __len;
00870 }
00871 else if (size() >= __len) {
00872 iterator __new_finish(copy(__first, __last, _M_start));
00873 _Destroy(__new_finish, end());
00874 _M_finish = __new_finish.base();
00875 }
00876 else {
00877 _ForwardIter __mid = __first;
00878 advance(__mid, size());
00879 copy(__first, __mid, _M_start);
00880 _M_finish = uninitialized_copy(__mid, __last, _M_finish);
00881 }
00882 }
00883
00884 template <class _Tp, class _Alloc>
00885 void
00886 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
00887 {
00888 if (_M_finish != _M_end_of_storage) {
00889 _Construct(_M_finish, *(_M_finish - 1));
00890 ++_M_finish;
00891 _Tp __x_copy = __x;
00892 copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
00893 *__position = __x_copy;
00894 }
00895 else {
00896 const size_type __old_size = size();
00897 const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
00898 iterator __new_start(_M_allocate(__len));
00899 iterator __new_finish(__new_start);
00900 try {
00901 __new_finish = uninitialized_copy(iterator(_M_start), __position,
00902 __new_start);
00903 _Construct(__new_finish.base(), __x);
00904 ++__new_finish;
00905 __new_finish = uninitialized_copy(__position, iterator(_M_finish),
00906 __new_finish);
00907 }
00908 catch(...)
00909 {
00910 _Destroy(__new_start,__new_finish);
00911 _M_deallocate(__new_start.base(),__len);
00912 __throw_exception_again;
00913 }
00914 _Destroy(begin(), end());
00915 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00916 _M_start = __new_start.base();
00917 _M_finish = __new_finish.base();
00918 _M_end_of_storage = __new_start.base() + __len;
00919 }
00920 }
00921
00922 template <class _Tp, class _Alloc>
00923 void
00924 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
00925 {
00926 if (_M_finish != _M_end_of_storage) {
00927 _Construct(_M_finish, *(_M_finish - 1));
00928 ++_M_finish;
00929 copy_backward(__position, iterator(_M_finish - 2),
00930 iterator(_M_finish - 1));
00931 *__position = _Tp();
00932 }
00933 else {
00934 const size_type __old_size = size();
00935 const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
00936 pointer __new_start = _M_allocate(__len);
00937 pointer __new_finish = __new_start;
00938 try {
00939 __new_finish = uninitialized_copy(iterator(_M_start), __position,
00940 __new_start);
00941 _Construct(__new_finish);
00942 ++__new_finish;
00943 __new_finish = uninitialized_copy(__position, iterator(_M_finish),
00944 __new_finish);
00945 }
00946 catch(...)
00947 {
00948 _Destroy(__new_start,__new_finish);
00949 _M_deallocate(__new_start,__len);
00950 __throw_exception_again;
00951 }
00952 _Destroy(begin(), end());
00953 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
00954 _M_start = __new_start;
00955 _M_finish = __new_finish;
00956 _M_end_of_storage = __new_start + __len;
00957 }
00958 }
00959
00960 template <class _Tp, class _Alloc>
00961 void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
00962 const _Tp& __x)
00963 {
00964 if (__n != 0) {
00965 if (size_type(_M_end_of_storage - _M_finish) >= __n) {
00966 _Tp __x_copy = __x;
00967 const size_type __elems_after = end() - __position;
00968 iterator __old_finish(_M_finish);
00969 if (__elems_after > __n) {
00970 uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
00971 _M_finish += __n;
00972 copy_backward(__position, __old_finish - __n, __old_finish);
00973 fill(__position, __position + __n, __x_copy);
00974 }
00975 else {
00976 uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
00977 _M_finish += __n - __elems_after;
00978 uninitialized_copy(__position, __old_finish, _M_finish);
00979 _M_finish += __elems_after;
00980 fill(__position, __old_finish, __x_copy);
00981 }
00982 }
00983 else {
00984 const size_type __old_size = size();
00985 const size_type __len = __old_size + max(__old_size, __n);
00986 iterator __new_start(_M_allocate(__len));
00987 iterator __new_finish(__new_start);
00988 try {
00989 __new_finish = uninitialized_copy(begin(), __position, __new_start);
00990 __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
00991 __new_finish
00992 = uninitialized_copy(__position, end(), __new_finish);
00993 }
00994 catch(...)
00995 {
00996 _Destroy(__new_start,__new_finish);
00997 _M_deallocate(__new_start.base(),__len);
00998 __throw_exception_again;
00999 }
01000 _Destroy(_M_start, _M_finish);
01001 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
01002 _M_start = __new_start.base();
01003 _M_finish = __new_finish.base();
01004 _M_end_of_storage = __new_start.base() + __len;
01005 }
01006 }
01007 }
01008
01009 template <class _Tp, class _Alloc> template <class _InputIterator>
01010 void
01011 vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
01012 _InputIterator __first,
01013 _InputIterator __last,
01014 input_iterator_tag)
01015 {
01016 for ( ; __first != __last; ++__first) {
01017 __pos = insert(__pos, *__first);
01018 ++__pos;
01019 }
01020 }
01021
01022 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01023 void
01024 vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
01025 _ForwardIterator __first,
01026 _ForwardIterator __last,
01027 forward_iterator_tag)
01028 {
01029 if (__first != __last) {
01030 size_type __n = distance(__first, __last);
01031 if (size_type(_M_end_of_storage - _M_finish) >= __n) {
01032 const size_type __elems_after = end() - __position;
01033 iterator __old_finish(_M_finish);
01034 if (__elems_after > __n) {
01035 uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
01036 _M_finish += __n;
01037 copy_backward(__position, __old_finish - __n, __old_finish);
01038 copy(__first, __last, __position);
01039 }
01040 else {
01041 _ForwardIterator __mid = __first;
01042 advance(__mid, __elems_after);
01043 uninitialized_copy(__mid, __last, _M_finish);
01044 _M_finish += __n - __elems_after;
01045 uninitialized_copy(__position, __old_finish, _M_finish);
01046 _M_finish += __elems_after;
01047 copy(__first, __mid, __position);
01048 }
01049 }
01050 else {
01051 const size_type __old_size = size();
01052 const size_type __len = __old_size + max(__old_size, __n);
01053 iterator __new_start(_M_allocate(__len));
01054 iterator __new_finish(__new_start);
01055 try {
01056 __new_finish = uninitialized_copy(iterator(_M_start),
01057 __position, __new_start);
01058 __new_finish = uninitialized_copy(__first, __last, __new_finish);
01059 __new_finish
01060 = uninitialized_copy(__position, iterator(_M_finish), __new_finish);
01061 }
01062 catch(...)
01063 {
01064 _Destroy(__new_start,__new_finish);
01065 _M_deallocate(__new_start.base(), __len);
01066 __throw_exception_again;
01067 }
01068 _Destroy(_M_start, _M_finish);
01069 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
01070 _M_start = __new_start.base();
01071 _M_finish = __new_finish.base();
01072 _M_end_of_storage = __new_start.base() + __len;
01073 }
01074 }
01075 }
01076
01077 }
01078
01079 #endif
01080
01081
01082
01083