Whole document tree
    

Whole document tree

stl_vector.h Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

stl_vector.h

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

Generated on Mon Apr 8 03:11:46 2002 for libstdc++-v3 Source by doxygen1.2.15