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:

Generated on Wed May 1 19:19:38 2002 for libstdc++-v3 Source by doxygen1.2.15