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