# stl_vector.h

Go to the documentation of this file.

    00001 // Vector implementation -*- C++ -*-
    00002
    00003 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 2, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /*
    00031  *
    00032  * Copyright (c) 1994
    00033  * Hewlett-Packard Company
    00034  *
    00035  * Permission to use, copy, modify, distribute and sell this software
    00036  * and its documentation for any purpose is hereby granted without fee,
    00037  * provided that the above copyright notice appear in all copies and
    00038  * that both that copyright notice and this permission notice appear
    00039  * in supporting documentation.  Hewlett-Packard Company makes no
    00040  * representations about the suitability of this software for any
    00041  * purpose.  It is provided "as is" without express or implied warranty.
    00042  *
    00043  *
    00044  * Copyright (c) 1996
    00045  * Silicon Graphics Computer Systems, Inc.
    00046  *
    00047  * Permission to use, copy, modify, distribute and sell this software
    00048  * and its documentation for any purpose is hereby granted without fee,
    00049  * provided that the above copyright notice appear in all copies and
    00050  * that both that copyright notice and this permission notice appear
    00051  * in supporting documentation.  Silicon Graphics makes no
    00052  * representations about the suitability of this  software for any
    00053  * purpose.  It is provided "as is" without express or implied warranty.
    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 // The vector base class serves two purposes.  First, its constructor
    00072 // and destructor allocate (but don't initialize) storage.  This makes
    00073 // exception safety easier.  Second, the base class encapsulates all of
    00074 // the differences between SGI-style allocators and standard-conforming
    00075 // allocators.
    00076
    00077 // Base class for ordinary allocators.
    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 // Specialization for allocators that have the property that we don't
    00102 // actually have to store an allocator object.
    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   // concept requirements
    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   // Check whether it's an integral type.  If so, it's not an iterator.
    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   // assign(), a generalized assignment member function.  Two
    00406   // versions: one that takes a count, and one that takes a range.
    00407   // The range version is a member template, so we dispatch on whether
    00408   // or not the type is an integer.
    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   // Check whether it's an integral type.  If so, it's not an iterator.
    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   // This function is only called by the constructor.
    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 } // namespace std
    01078
    01079 #endif /* __GLIBCPP_INTERNAL_VECTOR_H */
    01080
    01081 // Local Variables:
    01082 // mode:C++
    01083 // End: