Home | History | Annotate | Download | only in stl
      1 /*
      2  *
      3  * Copyright (c) 1994
      4  * Hewlett-Packard Company
      5  *
      6  * Copyright (c) 1996,1997
      7  * Silicon Graphics Computer Systems, Inc.
      8  *
      9  * Copyright (c) 1997
     10  * Moscow Center for SPARC Technology
     11  *
     12  * Copyright (c) 1999
     13  * Boris Fomitchev
     14  *
     15  * This material is provided "as is", with absolutely no warranty expressed
     16  * or implied. Any use is at your own risk.
     17  *
     18  * Permission to use or copy this software for any purpose is hereby granted
     19  * without fee, provided the above notices are retained on all copies.
     20  * Permission to modify the code and to distribute modified code is granted,
     21  * provided the above notices are retained, and a notice that the code was
     22  * modified is included with the above copyright notice.
     23  *
     24  */
     25 
     26 /* NOTE: This is an internal header file, included by other STL headers.
     27  *   You should not attempt to use it directly.
     28  */
     29 
     30 #ifndef _STLP_INTERNAL_VECTOR_H
     31 #define _STLP_INTERNAL_VECTOR_H
     32 
     33 #ifndef _STLP_INTERNAL_ALGOBASE_H
     34 #  include <stl/_algobase.h>
     35 #endif
     36 
     37 #ifndef _STLP_INTERNAL_ALLOC_H
     38 #  include <stl/_alloc.h>
     39 #endif
     40 
     41 #ifndef _STLP_INTERNAL_ITERATOR_H
     42 #  include <stl/_iterator.h>
     43 #endif
     44 
     45 #ifndef _STLP_INTERNAL_UNINITIALIZED_H
     46 #  include <stl/_uninitialized.h>
     47 #endif
     48 
     49 _STLP_BEGIN_NAMESPACE
     50 
     51 // The vector base class serves one purpose, its constructor and
     52 // destructor allocate (but don't initialize) storage.  This makes
     53 // exception safety easier.
     54 
     55 _STLP_MOVE_TO_PRIV_NAMESPACE
     56 
     57 template <class _Tp, class _Alloc>
     58 class _Vector_base {
     59 public:
     60   typedef _Vector_base<_Tp, _Alloc> _Self;
     61   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
     62   typedef _Alloc allocator_type;
     63   typedef _Tp* pointer;
     64   typedef _STLP_alloc_proxy<pointer, _Tp, allocator_type> _AllocProxy;
     65 
     66   _Vector_base(const _Alloc& __a)
     67     : _M_start(0), _M_finish(0), _M_end_of_storage(__a, 0) {}
     68 
     69   _Vector_base(size_t __n, const _Alloc& __a)
     70     : _M_start(0), _M_finish(0), _M_end_of_storage(__a, 0) {
     71     _M_start = _M_end_of_storage.allocate(__n, __n);
     72     _M_finish = _M_start;
     73     _M_end_of_storage._M_data = _M_start + __n;
     74     _STLP_MPWFIX_TRY _STLP_MPWFIX_CATCH
     75   }
     76 
     77 #if !defined (_STLP_NO_MOVE_SEMANTIC)
     78   _Vector_base(__move_source<_Self> src)
     79     : _M_start(src.get()._M_start), _M_finish(src.get()._M_finish),
     80       _M_end_of_storage(__move_source<_AllocProxy>(src.get()._M_end_of_storage)) {
     81     //Set the source as empty:
     82     src.get()._M_finish = src.get()._M_end_of_storage._M_data = src.get()._M_start = 0;
     83   }
     84 #endif
     85 
     86   ~_Vector_base() {
     87     if (_M_start != _STLP_DEFAULT_CONSTRUCTED(pointer))
     88       _M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start);
     89   }
     90 
     91 protected:
     92   void _STLP_FUNCTION_THROWS _M_throw_length_error() const;
     93   void _STLP_FUNCTION_THROWS _M_throw_out_of_range() const;
     94 
     95   pointer _M_start;
     96   pointer _M_finish;
     97   _AllocProxy _M_end_of_storage;
     98 };
     99 
    100 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
    101 #  define vector _STLP_PTR_IMPL_NAME(vector)
    102 #elif defined (_STLP_DEBUG)
    103 #  define vector _STLP_NON_DBG_NAME(vector)
    104 #else
    105 _STLP_MOVE_TO_STD_NAMESPACE
    106 #endif
    107 
    108 template <class _Tp, _STLP_DFL_TMPL_PARAM(_Alloc, allocator<_Tp>) >
    109 class vector : protected _STLP_PRIV _Vector_base<_Tp, _Alloc>
    110 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (vector)
    111              , public __stlport_class<vector<_Tp, _Alloc> >
    112 #endif
    113 {
    114 private:
    115   typedef _STLP_PRIV _Vector_base<_Tp, _Alloc> _Base;
    116   typedef vector<_Tp, _Alloc> _Self;
    117 public:
    118   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
    119   typedef typename _Base::allocator_type allocator_type;
    120 
    121   typedef _Tp value_type;
    122   typedef value_type* pointer;
    123   typedef const value_type* const_pointer;
    124   typedef value_type* iterator;
    125   typedef const value_type* const_iterator;
    126 
    127   typedef value_type& reference;
    128   typedef const value_type& const_reference;
    129   typedef size_t size_type;
    130   typedef ptrdiff_t difference_type;
    131   typedef random_access_iterator_tag _Iterator_category;
    132 
    133   _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
    134 
    135   allocator_type get_allocator() const
    136   { return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_end_of_storage, _Tp); }
    137 
    138 private:
    139 #if defined (_STLP_NO_MOVE_SEMANTIC)
    140   typedef __false_type _Movable;
    141 #endif
    142 
    143   // handles insertions on overflow
    144   void _M_insert_overflow_aux(pointer __pos, const _Tp& __x, const __false_type& /*_Movable*/,
    145                               size_type __fill_len, bool __atend);
    146   void _M_insert_overflow_aux(pointer __pos, const _Tp& __x, const __true_type& /*_Movable*/,
    147                               size_type __fill_len, bool __atend) {
    148     //We need to take care of self referencing here:
    149     if (_M_is_inside(__x)) {
    150       value_type __x_copy = __x;
    151       _M_insert_overflow_aux(__pos, __x_copy, __false_type(), __fill_len, __atend);
    152       return;
    153     }
    154     _M_insert_overflow_aux(__pos, __x, __false_type(), __fill_len, __atend);
    155   }
    156 
    157   void _M_insert_overflow(pointer __pos, const _Tp& __x, const __false_type& /*_TrivialCopy*/,
    158                           size_type __fill_len, bool __atend = false) {
    159 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    160     typedef typename __move_traits<_Tp>::implemented _Movable;
    161 #endif
    162     _M_insert_overflow_aux(__pos, __x, _Movable(), __fill_len, __atend);
    163   }
    164   void _M_insert_overflow(pointer __pos, const _Tp& __x, const __true_type& /*_TrivialCopy*/,
    165                           size_type __fill_len, bool __atend = false);
    166   void _M_range_check(size_type __n) const {
    167     if (__n >= size_type(this->_M_finish - this->_M_start))
    168       this->_M_throw_out_of_range();
    169   }
    170 
    171   size_type _M_compute_next_size(size_type __n) {
    172     const size_type __size = size();
    173     if (__n > max_size() - __size)
    174       this->_M_throw_length_error();
    175     size_type __len = __size + (max)(__n, __size);
    176     if (__len > max_size() || __len < __size)
    177       __len = max_size(); // overflow
    178     return __len;
    179   }
    180 
    181 public:
    182   iterator begin()             { return this->_M_start; }
    183   const_iterator begin() const { return this->_M_start; }
    184   iterator end()               { return this->_M_finish; }
    185   const_iterator end() const   { return this->_M_finish; }
    186 
    187   reverse_iterator rbegin()              { return reverse_iterator(end()); }
    188   const_reverse_iterator rbegin() const  { return const_reverse_iterator(end()); }
    189   reverse_iterator rend()                { return reverse_iterator(begin()); }
    190   const_reverse_iterator rend() const    { return const_reverse_iterator(begin()); }
    191 
    192   size_type size() const        { return size_type(this->_M_finish - this->_M_start); }
    193   size_type max_size() const {
    194     size_type __vector_max_size = size_type(-1) / sizeof(_Tp);
    195     typename allocator_type::size_type __alloc_max_size = this->_M_end_of_storage.max_size();
    196     return (__alloc_max_size < __vector_max_size)?__alloc_max_size:__vector_max_size;
    197   }
    198 
    199   size_type capacity() const    { return size_type(this->_M_end_of_storage._M_data - this->_M_start); }
    200   bool empty() const            { return this->_M_start == this->_M_finish; }
    201 
    202   reference operator[](size_type __n) { return *(begin() + __n); }
    203   const_reference operator[](size_type __n) const { return *(begin() + __n); }
    204 
    205   reference front()             { return *begin(); }
    206   const_reference front() const { return *begin(); }
    207   reference back()              { return *(end() - 1); }
    208   const_reference back() const  { return *(end() - 1); }
    209 
    210   reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
    211   const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
    212 
    213 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
    214   explicit vector(const allocator_type& __a = allocator_type())
    215 #else
    216   vector()
    217     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(allocator_type()) {}
    218   vector(const allocator_type& __a)
    219 #endif
    220     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__a) {}
    221 
    222 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
    223 private:
    224   //We always call _M_initialize with only 1 parameter. Default parameter
    225   //is used to allow explicit instanciation of vector with types with no
    226   //default constructor.
    227   void _M_initialize(size_type __n, const _Tp& __val = _STLP_DEFAULT_CONSTRUCTED(_Tp))
    228   { this->_M_finish = _STLP_PRIV __uninitialized_init(this->_M_start, __n, __val); }
    229 public:
    230   explicit vector(size_type __n)
    231     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__n, allocator_type())
    232   { _M_initialize(__n); }
    233   vector(size_type __n, const _Tp& __val, const allocator_type& __a = allocator_type())
    234 #else
    235   explicit vector(size_type __n)
    236     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__n, allocator_type())
    237   { this->_M_finish = _STLP_PRIV __uninitialized_init(this->_M_start, __n, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
    238   vector(size_type __n, const _Tp& __val)
    239     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__n, allocator_type())
    240   { this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_start, __n, __val); }
    241   vector(size_type __n, const _Tp& __val, const allocator_type& __a)
    242 #endif
    243     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__n, __a)
    244   { this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_start, __n, __val); }
    245 
    246   vector(const _Self& __x)
    247     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__x.size(), __x.get_allocator()) {
    248     typedef typename __type_traits<_Tp>::has_trivial_copy_constructor _TrivialUCopy;
    249     this->_M_finish = _STLP_PRIV __ucopy_ptrs(__x.begin(), __x.end(), this->_M_start, _TrivialUCopy());
    250   }
    251 
    252 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    253   vector(__move_source<_Self> src)
    254     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__move_source<_Base>(src.get()))
    255   {}
    256 #endif
    257 
    258 #if defined (_STLP_MEMBER_TEMPLATES)
    259 private:
    260   template <class _Integer>
    261   void _M_initialize_aux(_Integer __n, _Integer __val,
    262                          const __true_type& /*_IsIntegral*/) {
    263     size_type __real_n = __n;
    264     this->_M_start = this->_M_end_of_storage.allocate(__n, __real_n);
    265     this->_M_end_of_storage._M_data = this->_M_start + __real_n;
    266     this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_start, __n, __val);
    267   }
    268 
    269   template <class _InputIterator>
    270   void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
    271                          const __false_type& /*_IsIntegral*/)
    272   { _M_range_initialize(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator)); }
    273 
    274 public:
    275   // Check whether it's an integral type.  If so, it's not an iterator.
    276   template <class _InputIterator>
    277   vector(_InputIterator __first, _InputIterator __last,
    278                const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL )
    279     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__a) {
    280     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
    281     _M_initialize_aux(__first, __last, _Integral());
    282   }
    283 
    284 #  if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS)
    285   template <class _InputIterator>
    286   vector(_InputIterator __first, _InputIterator __last)
    287     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(allocator_type()) {
    288     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
    289     _M_initialize_aux(__first, __last, _Integral());
    290   }
    291 #  endif /* _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS */
    292 
    293 #else /* _STLP_MEMBER_TEMPLATES */
    294   vector(const _Tp* __first, const _Tp* __last,
    295          const allocator_type& __a = allocator_type())
    296     : _STLP_PRIV _Vector_base<_Tp, _Alloc>(__last - __first, __a) {
    297     typedef typename __type_traits<_Tp>::has_trivial_copy_constructor _TrivialUCopy;
    298     this->_M_finish = _STLP_PRIV __ucopy_ptrs(__first, __last, this->_M_start, _TrivialUCopy());
    299   }
    300 #endif /* _STLP_MEMBER_TEMPLATES */
    301 
    302   //As the vector container is a back insert oriented container it
    303   //seems rather logical to destroy elements in reverse order.
    304   ~vector() { _STLP_STD::_Destroy_Range(rbegin(), rend()); }
    305 
    306   _Self& operator=(const _Self& __x);
    307 
    308   void reserve(size_type __n);
    309 
    310   // assign(), a generalized assignment member function.  Two
    311   // versions: one that takes a count, and one that takes a range.
    312   // The range version is a member template, so we dispatch on whether
    313   // or not the type is an integer.
    314 
    315   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
    316   void _M_fill_assign(size_type __n, const _Tp& __val);
    317 
    318 #if defined (_STLP_MEMBER_TEMPLATES)
    319   template <class _ForwardIter>
    320   void _M_assign_aux(_ForwardIter __first, _ForwardIter __last, const forward_iterator_tag &) {
    321 #else
    322   void assign(const_iterator __first, const_iterator __last) {
    323     typedef const_iterator _ForwardIter;
    324 #endif
    325     const size_type __len = _STLP_STD::distance(__first, __last);
    326     if (__len > capacity()) {
    327       size_type __n = __len;
    328       iterator __tmp = _M_allocate_and_copy(__n, __first, __last);
    329       _M_clear();
    330       _M_set(__tmp, __tmp + __len, __tmp + __n);
    331     }
    332     else if (size() >= __len) {
    333       iterator __new_finish = copy(__first, __last, this->_M_start);
    334       _STLP_STD::_Destroy_Range(__new_finish, this->_M_finish);
    335       this->_M_finish = __new_finish;
    336     }
    337     else {
    338       _ForwardIter __mid = __first;
    339       _STLP_STD::advance(__mid, size());
    340       _STLP_STD::copy(__first, __mid, this->_M_start);
    341       this->_M_finish = _STLP_STD::uninitialized_copy(__mid, __last, this->_M_finish);
    342     }
    343   }
    344 
    345 #if defined (_STLP_MEMBER_TEMPLATES)
    346   template <class _InputIter>
    347   void _M_assign_aux(_InputIter __first, _InputIter __last,
    348                      const input_iterator_tag &) {
    349     iterator __cur = begin();
    350     for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
    351       *__cur = *__first;
    352     if (__first == __last)
    353       erase(__cur, end());
    354     else
    355       insert(end(), __first, __last);
    356   }
    357 
    358   template <class _Integer>
    359   void _M_assign_dispatch(_Integer __n, _Integer __val,
    360                           const __true_type& /*_IsIntegral*/)
    361   { _M_fill_assign(__n, __val); }
    362 
    363   template <class _InputIter>
    364   void _M_assign_dispatch(_InputIter __first, _InputIter __last,
    365                           const __false_type& /*_IsIntegral*/)
    366   { _M_assign_aux(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); }
    367 
    368   template <class _InputIterator>
    369   void assign(_InputIterator __first, _InputIterator __last) {
    370     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
    371     _M_assign_dispatch(__first, __last, _Integral());
    372   }
    373 #endif
    374 
    375 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) && !defined (_STLP_NO_ANACHRONISMS)
    376   void push_back(const _Tp& __x = _STLP_DEFAULT_CONSTRUCTED(_Tp)) {
    377 #else
    378   void push_back(const _Tp& __x) {
    379 #endif
    380     if (this->_M_finish != this->_M_end_of_storage._M_data) {
    381       _Copy_Construct(this->_M_finish, __x);
    382       ++this->_M_finish;
    383     }
    384     else {
    385       typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _TrivialCopy;
    386       _M_insert_overflow(this->_M_finish, __x, _TrivialCopy(), 1, true);
    387     }
    388   }
    389 
    390 #if !defined(_STLP_DONT_SUP_DFLT_PARAM) && !defined(_STLP_NO_ANACHRONISMS)
    391   iterator insert(iterator __pos, const _Tp& __x = _STLP_DEFAULT_CONSTRUCTED(_Tp));
    392 #else
    393   iterator insert(iterator __pos, const _Tp& __x);
    394 #endif
    395 
    396 #if defined(_STLP_DONT_SUP_DFLT_PARAM) && !defined(_STLP_NO_ANACHRONISMS)
    397   void push_back() { push_back(_STLP_DEFAULT_CONSTRUCTED(_Tp)); }
    398   iterator insert(iterator __pos) { return insert(__pos, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
    399 #endif
    400 
    401   void swap(_Self& __x) {
    402     _STLP_STD::swap(this->_M_start, __x._M_start);
    403     _STLP_STD::swap(this->_M_finish, __x._M_finish);
    404     this->_M_end_of_storage.swap(__x._M_end_of_storage);
    405   }
    406 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
    407   void _M_swap_workaround(_Self& __x) { swap(__x); }
    408 #endif
    409 
    410 private:
    411   void _M_fill_insert_aux (iterator __pos, size_type __n, const _Tp& __x, const __true_type& /*_Movable*/);
    412   void _M_fill_insert_aux (iterator __pos, size_type __n, const _Tp& __x, const __false_type& /*_Movable*/);
    413   void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
    414 
    415   bool _M_is_inside(const value_type& __x) const {
    416     return (&__x >= this->_M_start && &__x < this->_M_finish);
    417   }
    418 
    419 #if defined (_STLP_MEMBER_TEMPLATES)
    420   template <class _ForwardIterator>
    421   void _M_range_insert_realloc(iterator __pos,
    422                                _ForwardIterator __first, _ForwardIterator __last,
    423 #else
    424   void _M_range_insert_realloc(iterator __pos,
    425                                const_iterator __first, const_iterator __last,
    426 #endif
    427                                size_type __n) {
    428     typedef typename __type_traits<_Tp>::has_trivial_copy_constructor _TrivialUCopy;
    429 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    430     typedef typename __move_traits<_Tp>::implemented _Movable;
    431 #endif
    432     size_type __len = _M_compute_next_size(__n);
    433     pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
    434     pointer __new_finish = __new_start;
    435     _STLP_TRY {
    436       __new_finish = _STLP_PRIV __uninitialized_move(this->_M_start, __pos, __new_start, _TrivialUCopy(), _Movable());
    437       __new_finish = uninitialized_copy(__first, __last, __new_finish);
    438       __new_finish = _STLP_PRIV __uninitialized_move(__pos, this->_M_finish, __new_finish, _TrivialUCopy(), _Movable());
    439     }
    440     _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
    441                   this->_M_end_of_storage.deallocate(__new_start,__len)))
    442     _M_clear_after_move();
    443     _M_set(__new_start, __new_finish, __new_start + __len);
    444   }
    445 
    446 #if defined (_STLP_MEMBER_TEMPLATES)
    447   template <class _ForwardIterator>
    448   void _M_range_insert_aux(iterator __pos,
    449                            _ForwardIterator __first, _ForwardIterator __last,
    450 #else
    451   void _M_range_insert_aux(iterator __pos,
    452                            const_iterator __first, const_iterator __last,
    453 #endif
    454                            size_type __n, const __true_type& /*_Movable*/) {
    455     iterator __src = this->_M_finish - 1;
    456     iterator __dst = __src + __n;
    457     for (; __src >= __pos; --__dst, --__src) {
    458       _STLP_STD::_Move_Construct(__dst, *__src);
    459       _STLP_STD::_Destroy_Moved(__src);
    460     }
    461     uninitialized_copy(__first, __last, __pos);
    462     this->_M_finish += __n;
    463   }
    464 
    465 #if defined (_STLP_MEMBER_TEMPLATES)
    466   template <class _ForwardIterator>
    467   void _M_range_insert_aux(iterator __pos,
    468                            _ForwardIterator __first, _ForwardIterator __last,
    469 #else
    470   void _M_range_insert_aux(iterator __pos,
    471                            const_iterator __first, const_iterator __last,
    472 #endif
    473                            size_type __n, const __false_type& /*_Movable*/) {
    474     typedef typename __type_traits<_Tp>::has_trivial_copy_constructor _TrivialUCopy;
    475     typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _TrivialCopy;
    476     const size_type __elems_after = this->_M_finish - __pos;
    477     pointer __old_finish = this->_M_finish;
    478     if (__elems_after > __n) {
    479       _STLP_PRIV __ucopy_ptrs(this->_M_finish - __n, this->_M_finish, this->_M_finish, _TrivialUCopy());
    480       this->_M_finish += __n;
    481       _STLP_PRIV __copy_backward_ptrs(__pos, __old_finish - __n, __old_finish, _TrivialCopy());
    482       copy(__first, __last, __pos);
    483     }
    484     else {
    485 #if defined ( _STLP_MEMBER_TEMPLATES )
    486       _ForwardIterator __mid = __first;
    487       _STLP_STD::advance(__mid, __elems_after);
    488 #else
    489       const_pointer __mid = __first + __elems_after;
    490 #endif
    491       uninitialized_copy(__mid, __last, this->_M_finish);
    492       this->_M_finish += __n - __elems_after;
    493       _STLP_PRIV __ucopy_ptrs(__pos, __old_finish, this->_M_finish, _TrivialUCopy());
    494       this->_M_finish += __elems_after;
    495       copy(__first, __mid, __pos);
    496     } /* elems_after */
    497   }
    498 
    499 
    500 #if defined (_STLP_MEMBER_TEMPLATES)
    501   template <class _Integer>
    502   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
    503                           const __true_type&)
    504   { _M_fill_insert(__pos, (size_type) __n, (_Tp) __val); }
    505 
    506   template <class _InputIterator>
    507   void _M_insert_dispatch(iterator __pos,
    508                           _InputIterator __first, _InputIterator __last,
    509                           const __false_type&)
    510   { _M_range_insert(__pos, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator)); }
    511 
    512 public:
    513   // Check whether it's an integral type.  If so, it's not an iterator.
    514   template <class _InputIterator>
    515   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
    516     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
    517     _M_insert_dispatch(__pos, __first, __last, _Integral());
    518   }
    519 
    520 private:
    521   template <class _InputIterator>
    522   void _M_range_insert(iterator __pos,
    523                        _InputIterator __first, _InputIterator __last,
    524                        const input_iterator_tag &) {
    525     for ( ; __first != __last; ++__first) {
    526       __pos = insert(__pos, *__first);
    527       ++__pos;
    528     }
    529   }
    530 
    531   template <class _ForwardIterator>
    532   void _M_range_insert(iterator __pos,
    533                        _ForwardIterator __first, _ForwardIterator __last,
    534                        const forward_iterator_tag &) {
    535 #else
    536 public:
    537   void insert(iterator __pos,
    538               const_iterator __first, const_iterator __last) {
    539 #endif
    540 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    541     typedef typename __move_traits<_Tp>::implemented _Movable;
    542 #endif
    543     /* This method do not check self referencing.
    544      * Standard forbids it, checked by the debug mode.
    545      */
    546     if (__first != __last) {
    547       size_type __n = _STLP_STD::distance(__first, __last);
    548 
    549       if (size_type(this->_M_end_of_storage._M_data - this->_M_finish) >= __n) {
    550         _M_range_insert_aux(__pos, __first, __last, __n, _Movable());
    551       }
    552       else {
    553         _M_range_insert_realloc(__pos, __first, __last, __n);
    554       }
    555     }
    556   }
    557 
    558 public:
    559   void insert (iterator __pos, size_type __n, const _Tp& __x)
    560   { _M_fill_insert(__pos, __n, __x); }
    561 
    562   void pop_back() {
    563     --this->_M_finish;
    564     _STLP_STD::_Destroy(this->_M_finish);
    565   }
    566 
    567 private:
    568   iterator _M_erase(iterator __pos, const __true_type& /*_Movable*/) {
    569     _STLP_STD::_Destroy(__pos);
    570     iterator __dst = __pos, __src = __dst + 1;
    571     iterator __end = end();
    572     for (; __src != __end; ++__dst, ++__src) {
    573       _STLP_STD::_Move_Construct(__dst, *__src);
    574       _STLP_STD::_Destroy_Moved(__src);
    575     }
    576     this->_M_finish = __dst;
    577     return __pos;
    578   }
    579   iterator _M_erase(iterator __pos, const __false_type& /*_Movable*/) {
    580     if (__pos + 1 != end()) {
    581       typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _TrivialCopy;
    582       _STLP_PRIV __copy_ptrs(__pos + 1, this->_M_finish, __pos, _TrivialCopy());
    583     }
    584     --this->_M_finish;
    585     _STLP_STD::_Destroy(this->_M_finish);
    586     return __pos;
    587   }
    588   iterator _M_erase(iterator __first, iterator __last, const __true_type& /*_Movable*/) {
    589     iterator __dst = __first, __src = __last;
    590     iterator __end = end();
    591     for (; __dst != __last && __src != __end; ++__dst, ++__src) {
    592       _STLP_STD::_Destroy(__dst);
    593       _STLP_STD::_Move_Construct(__dst, *__src);
    594     }
    595     if (__dst != __last) {
    596       //There is more elements to erase than element to move:
    597       _STLP_STD::_Destroy_Range(__dst, __last);
    598       _STLP_STD::_Destroy_Moved_Range(__last, __end);
    599     }
    600     else {
    601       //There is more element to move than element to erase:
    602       for (; __src != __end; ++__dst, ++__src) {
    603         _STLP_STD::_Destroy_Moved(__dst);
    604         _STLP_STD::_Move_Construct(__dst, *__src);
    605       }
    606       _STLP_STD::_Destroy_Moved_Range(__dst, __end);
    607     }
    608     this->_M_finish = __dst;
    609     return __first;
    610   }
    611   iterator _M_erase(iterator __first, iterator __last, const __false_type& /*_Movable*/) {
    612     typedef typename __type_traits<_Tp>::has_trivial_assignment_operator _TrivialCopy;
    613     pointer __i = _STLP_PRIV __copy_ptrs(__last, this->_M_finish, __first, _TrivialCopy());
    614     _STLP_STD::_Destroy_Range(__i, this->_M_finish);
    615     this->_M_finish = __i;
    616     return __first;
    617   }
    618 
    619 public:
    620   iterator erase(iterator __pos) {
    621 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    622     typedef typename __move_traits<_Tp>::implemented _Movable;
    623 #endif
    624     return _M_erase(__pos, _Movable());
    625   }
    626   iterator erase(iterator __first, iterator __last) {
    627 #if !defined (_STLP_NO_MOVE_SEMANTIC)
    628     typedef typename __move_traits<_Tp>::implemented _Movable;
    629 #endif
    630     if (__first == __last)
    631       return __first;
    632     return _M_erase(__first, __last, _Movable());
    633   }
    634 
    635 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
    636   void resize(size_type __new_size, const _Tp& __x = _STLP_DEFAULT_CONSTRUCTED(_Tp)) {
    637 #else
    638   void resize(size_type __new_size, const _Tp& __x) {
    639 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
    640     if (__new_size < size())
    641       erase(begin() + __new_size, end());
    642     else
    643       insert(end(), __new_size - size(), __x);
    644   }
    645 
    646 #if defined (_STLP_DONT_SUP_DFLT_PARAM)
    647   void resize(size_type __new_size) { resize(__new_size, _STLP_DEFAULT_CONSTRUCTED(_Tp)); }
    648 #endif /*_STLP_DONT_SUP_DFLT_PARAM*/
    649 
    650   void clear() {
    651     erase(begin(), end());
    652   }
    653 
    654 private:
    655   void _M_clear() {
    656     _STLP_STD::_Destroy_Range(rbegin(), rend());
    657     this->_M_end_of_storage.deallocate(this->_M_start, this->_M_end_of_storage._M_data - this->_M_start);
    658   }
    659 
    660   void _M_clear_after_move() {
    661     _STLP_STD::_Destroy_Moved_Range(rbegin(), rend());
    662     this->_M_end_of_storage.deallocate(this->_M_start, this->_M_end_of_storage._M_data - this->_M_start);
    663   }
    664 
    665   void _M_set(pointer __s, pointer __f, pointer __e) {
    666     this->_M_start = __s;
    667     this->_M_finish = __f;
    668     this->_M_end_of_storage._M_data = __e;
    669   }
    670 
    671 #if defined (_STLP_MEMBER_TEMPLATES)
    672   template <class _ForwardIterator>
    673   pointer _M_allocate_and_copy(size_type& __n,
    674                                _ForwardIterator __first, _ForwardIterator __last)
    675 #else /* _STLP_MEMBER_TEMPLATES */
    676   pointer _M_allocate_and_copy(size_type& __n,
    677                                const_pointer __first, const_pointer __last)
    678 #endif /* _STLP_MEMBER_TEMPLATES */
    679   {
    680     pointer __result = this->_M_end_of_storage.allocate(__n, __n);
    681     _STLP_TRY {
    682       uninitialized_copy(__first, __last, __result);
    683       return __result;
    684     }
    685     _STLP_UNWIND(this->_M_end_of_storage.deallocate(__result, __n))
    686     _STLP_RET_AFTER_THROW(__result)
    687   }
    688 
    689 
    690 #if defined (_STLP_MEMBER_TEMPLATES)
    691   template <class _InputIterator>
    692   void _M_range_initialize(_InputIterator __first, _InputIterator __last,
    693                            const input_iterator_tag &) {
    694     for ( ; __first != __last; ++__first)
    695       push_back(*__first);
    696   }
    697   // This function is only called by the constructor.
    698   template <class _ForwardIterator>
    699   void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
    700                            const forward_iterator_tag &) {
    701     size_type __n = _STLP_STD::distance(__first, __last);
    702     this->_M_start = this->_M_end_of_storage.allocate(__n, __n);
    703     this->_M_end_of_storage._M_data = this->_M_start + __n;
    704     this->_M_finish = uninitialized_copy(__first, __last, this->_M_start);
    705   }
    706 #endif /* _STLP_MEMBER_TEMPLATES */
    707 };
    708 
    709 #if defined (vector)
    710 #  undef vector
    711 _STLP_MOVE_TO_STD_NAMESPACE
    712 #endif
    713 
    714 _STLP_END_NAMESPACE
    715 
    716 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
    717 #  include <stl/_vector.c>
    718 #endif
    719 
    720 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
    721 #  include <stl/pointers/_vector.h>
    722 #endif
    723 
    724 //We define the bool specialization before the debug interfave
    725 //to benefit of the debug version of vector even for the bool
    726 //specialization.
    727 #if !defined (_STLP_NO_BOOL) || !defined (_STLP_NO_EXTENSIONS)
    728 #  if !defined (_STLP_INTERNAL_BVECTOR_H)
    729 #    include <stl/_bvector.h>
    730 #  endif
    731 #endif
    732 
    733 #if defined (_STLP_DEBUG)
    734 #  include <stl/debug/_vector.h>
    735 #endif
    736 
    737 _STLP_BEGIN_NAMESPACE
    738 
    739 #if !defined (_STLP_NO_BOOL) && !defined (_STLP_NO_EXTENSIONS)
    740 // This typedef is non-standard.  It is provided for backward compatibility.
    741 typedef vector<bool, allocator<bool> > bit_vector;
    742 #endif
    743 
    744 #define _STLP_TEMPLATE_HEADER template <class _Tp, class _Alloc>
    745 #define _STLP_TEMPLATE_CONTAINER vector<_Tp, _Alloc>
    746 #include <stl/_relops_cont.h>
    747 #undef _STLP_TEMPLATE_CONTAINER
    748 #undef _STLP_TEMPLATE_HEADER
    749 
    750 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    751 #  if !defined (_STLP_NO_MOVE_SEMANTIC)
    752 template <class _Tp, class _Alloc>
    753 struct __move_traits<vector<_Tp, _Alloc> > {
    754   typedef __true_type implemented;
    755   typedef typename __move_traits<_Alloc>::complete complete;
    756 };
    757 #  endif
    758 
    759 #  if !defined (_STLP_DEBUG)
    760 template <class _Tp, class _Alloc>
    761 struct _DefaultZeroValue<vector<_Tp, _Alloc> >
    762 { typedef typename __type_traits<_Alloc>::has_trivial_default_constructor _Ret; };
    763 #  endif
    764 
    765 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
    766 
    767 _STLP_END_NAMESPACE
    768 
    769 #endif /* _STLP_VECTOR_H */
    770 
    771 // Local Variables:
    772 // mode:C++
    773 // End:
    774