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

Generated at Tue May 1 16:28:40 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001