OSDN Git Service

2002-05-21 Phil Edwards <pme@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / stl_vector.h
1 // Vector implementation -*- C++ -*-
2
3 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /*
31  *
32  * Copyright (c) 1994
33  * Hewlett-Packard Company
34  *
35  * Permission to use, copy, modify, distribute and sell this software
36  * and its documentation for any purpose is hereby granted without fee,
37  * provided that the above copyright notice appear in all copies and
38  * that both that copyright notice and this permission notice appear
39  * in supporting documentation.  Hewlett-Packard Company makes no
40  * representations about the suitability of this software for any
41  * purpose.  It is provided "as is" without express or implied warranty.
42  *
43  *
44  * Copyright (c) 1996
45  * Silicon Graphics Computer Systems, Inc.
46  *
47  * Permission to use, copy, modify, distribute and sell this software
48  * and its documentation for any purpose is hereby granted without fee,
49  * provided that the above copyright notice appear in all copies and
50  * that both that copyright notice and this permission notice appear
51  * in supporting documentation.  Silicon Graphics makes no
52  * representations about the suitability of this  software for any
53  * purpose.  It is provided "as is" without express or implied warranty.
54  */
55
56 /** @file stl_vector.h
57  *  This is an internal header file, included by other library headers.
58  *  You should not attempt to use it directly.
59  */
60
61 #ifndef __GLIBCPP_INTERNAL_VECTOR_H
62 #define __GLIBCPP_INTERNAL_VECTOR_H
63
64 #include <bits/stl_iterator_base_funcs.h>
65 #include <bits/functexcept.h>
66 #include <bits/concept_check.h>
67
68 // Since this entire file is within namespace std, there's no reason to
69 // waste two spaces along the left column.  Thus the leading indentation is
70 // slightly violated from here on.
71 namespace std
72 {
73
74 /// @if maint Primary default version.  @endif
75 /**
76  *  @if maint
77  *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
78  *  @endif
79 */
80 template <class _Tp, class _Allocator, bool _IsStatic>
81 class _Vector_alloc_base
82 {
83 public:
84   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
85           allocator_type;
86
87   allocator_type
88   get_allocator() const { return _M_data_allocator; }
89
90   _Vector_alloc_base(const allocator_type& __a)
91     : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
92   {}
93
94 protected:
95   allocator_type _M_data_allocator;
96   _Tp* _M_start;
97   _Tp* _M_finish;
98   _Tp* _M_end_of_storage;
99
100   _Tp*
101   _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); }
102
103   void
104   _M_deallocate(_Tp* __p, size_t __n)
105     { if (__p) _M_data_allocator.deallocate(__p, __n); }
106 };
107
108 /// @if maint Specialization for instanceless allocators.  @endif
109 template <class _Tp, class _Allocator>
110 class _Vector_alloc_base<_Tp, _Allocator, true>
111 {
112 public:
113   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
114           allocator_type;
115
116   allocator_type
117   get_allocator() const { return allocator_type(); }
118
119   _Vector_alloc_base(const allocator_type&)
120     : _M_start(0), _M_finish(0), _M_end_of_storage(0)
121   {}
122
123 protected:
124   _Tp* _M_start;
125   _Tp* _M_finish;
126   _Tp* _M_end_of_storage;
127
128   typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
129
130   _Tp*
131   _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
132
133   void
134   _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}
135 };
136
137
138 /**
139  *  @if maint
140  *  See bits/stl_deque.h's _Deque_base for an explanation.
141  *  @endif
142 */
143 template <class _Tp, class _Alloc>
144 struct _Vector_base
145   : public _Vector_alloc_base<_Tp, _Alloc,
146                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
147 {
148   typedef _Vector_alloc_base<_Tp, _Alloc,
149                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
150           _Base;
151   typedef typename _Base::allocator_type allocator_type;
152
153   _Vector_base(const allocator_type& __a)
154     : _Base(__a) {}
155   _Vector_base(size_t __n, const allocator_type& __a)
156     : _Base(__a)
157   {
158     _M_start = _M_allocate(__n);
159     _M_finish = _M_start;
160     _M_end_of_storage = _M_start + __n;
161   }
162
163   ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
164 };
165
166
167 /**
168  *  @brief  A standard container which offers fixed time access to individual
169  *  elements in any order.
170  *
171  *  @ingroup Containers
172  *  @ingroup Sequences
173  *
174  *  Meets the requirements of a <a href="tables.html#65">container</a>, a
175  *  <a href="tables.html#66">reversible container</a>, and a
176  *  <a href="tables.html#67">sequence</a>, including the
177  *  <a href="tables.html#68">optional sequence requirements</a> with the
178  *  %exception of @c push_front and @c pop_front.
179  *
180  *  In some terminology a %vector can be described as a dynamic C-style array,
181  *  it offers fast and efficient access to individual elements in any order
182  *  and saves the user from worrying about memory and size allocation.
183  *  Subscripting ( @c [] ) access is also provided as with C-style arrays.
184 */
185 template <class _Tp, class _Alloc = allocator<_Tp> >
186 class vector : protected _Vector_base<_Tp, _Alloc>
187 {
188   // concept requirements
189   __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
190
191   typedef _Vector_base<_Tp, _Alloc>                     _Base;
192   typedef vector<_Tp, _Alloc>                           vector_type;
193
194 public:
195   typedef _Tp                                           value_type;
196   typedef value_type*                                   pointer;
197   typedef const value_type*                             const_pointer;
198   typedef __gnu_cxx::__normal_iterator<pointer, vector_type>    iterator;
199   typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
200                                                         const_iterator;
201   typedef reverse_iterator<const_iterator>              const_reverse_iterator;
202   typedef reverse_iterator<iterator>                    reverse_iterator;
203   typedef value_type&                                   reference;
204   typedef const value_type&                             const_reference;
205   typedef size_t                                        size_type;
206   typedef ptrdiff_t                                     difference_type;
207   typedef typename _Base::allocator_type                allocator_type;
208
209 protected:
210   /** @if maint
211    *  These two functions and three data members are all from the top-most
212    *  base class, which varies depending on the type of %allocator.  They
213    *  should be pretty self-explanatory, as %vector uses a simple contiguous 
214    *  allocation scheme.
215    *  @endif
216   */
217   using _Base::_M_allocate;
218   using _Base::_M_deallocate;
219   using _Base::_M_start;
220   using _Base::_M_finish;
221   using _Base::_M_end_of_storage;
222
223 protected:
224   void _M_insert_aux(iterator __position, const _Tp& __x);
225 #ifdef _GLIBCPP_DEPRECATED
226   void _M_insert_aux(iterator __position);
227 #endif
228
229 public:
230   // [23.2.4.1] construct/copy/destroy
231   // (assign() and get_allocator() are also listed in this section)
232   /**
233    *  @brief  Default constructor creates no elements.
234   */
235   explicit
236   vector(const allocator_type& __a = allocator_type())
237     : _Base(__a) {}
238
239   /**
240    *  @brief  Create a %vector with copies of an exemplar element.
241    *  @param  n  The number of elements to initially create.
242    *  @param  value  An element to copy.
243    * 
244    *  This constructor fills the %vector with @a n copies of @a value.
245   */
246   vector(size_type __n, const _Tp& __value,
247          const allocator_type& __a = allocator_type())
248     : _Base(__n, __a)
249     { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
250
251   /**
252    *  @brief  Create a %vector with default elements.
253    *  @param  n  The number of elements to initially create.
254    * 
255    *  This constructor fills the %vector with @a n copies of a
256    *  default-constructed element.
257   */
258   explicit
259   vector(size_type __n)
260     : _Base(__n, allocator_type())
261     { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
262
263   /**
264    *  @brief  %Vector copy constructor.
265    *  @param  x  A %vector of identical element and allocator types.
266    * 
267    *  The newly-created %vector uses a copy of the allocation object used
268    *  by @a x.  All the elements of @a x are copied, but any extra memory in
269    *  @a x (for fast expansion) will not be copied.
270   */
271   vector(const vector<_Tp, _Alloc>& __x)
272     : _Base(__x.size(), __x.get_allocator())
273     { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
274
275   /**
276    *  @brief  Builds a %vector from a range.
277    *  @param  first  An input iterator.
278    *  @param  last  An input iterator.
279    * 
280    *  Creats a %vector consisting of copies of the elements from [first,last).
281    *
282    *  If the iterators are forward, bidirectional, or random-access, then
283    *  this will call the elements' copy constructor N times (where N is
284    *  distance(first,last)) and do no memory reallocation.  But if only
285    *  input iterators are used, then this will do at most 2N calls to the
286    *  copy constructor, and logN memory reallocations.
287   */
288   template <class _InputIterator>
289     vector(_InputIterator __first, _InputIterator __last,
290            const allocator_type& __a = allocator_type())
291         : _Base(__a)
292     {
293       // Check whether it's an integral type.  If so, it's not an iterator.
294       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
295       _M_initialize_aux(__first, __last, _Integral());
296     }
297
298 protected:
299   template<class _Integer>
300     void
301     _M_initialize_aux(_Integer __n, _Integer __value, __true_type)
302     {
303       _M_start = _M_allocate(__n);
304       _M_end_of_storage = _M_start + __n;
305       _M_finish = uninitialized_fill_n(_M_start, __n, __value);
306     }
307
308   template<class _InputIterator>
309     void
310     _M_initialize_aux(_InputIterator __first,_InputIterator __last,__false_type)
311     {
312       typedef typename iterator_traits<_InputIterator>::iterator_category
313                        _IterCategory;
314       _M_range_initialize(__first, __last, _IterCategory());
315     }
316
317 public:
318   /**
319    *  Creats a %vector consisting of copies of the elements from [first,last).
320    *
321    *  The dtor only erases the elements, and that if the elements
322    *  themselves are pointers, the pointed-to memory is not touched in any
323    *  way.  Managing the pointer is the user's responsibilty.
324   */
325   ~vector() { _Destroy(_M_start, _M_finish); }
326
327   /**
328    *  @brief  %Vector assignment operator.
329    *  @param  x  A %vector of identical element and allocator types.
330    * 
331    *  All the elements of @a x are copied, but any extra memory in @a x (for
332    *  fast expansion) will not be copied.  Unlike the copy constructor, the
333    *  allocator object is not copied.
334   */
335   vector<_Tp, _Alloc>&
336   operator=(const vector<_Tp, _Alloc>& __x);
337
338   /**
339    *  @brief  Assigns a given value to a %vector.
340    *  @param  n  Number of elements to be assigned.
341    *  @param  val  Value to be assigned.
342    *
343    *  This function fills a %vector with @a n copies of the given value.
344    *  Note that the assignment completely changes the %vector and that the
345    *  resulting %vector's size is the same as the number of elements assigned.
346    *  Old data may be lost.
347   */
348   void
349   assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
350
351 protected:
352   void
353   _M_fill_assign(size_type __n, const _Tp& __val);
354
355 public:
356   /**
357    *  @brief  Assigns a range to a %vector.
358    *  @param  first  An input iterator.
359    *  @param  last   An input iterator.
360    *
361    *  This function fills a %vector with copies of the elements in the
362    *  range [first,last).
363    *
364    *  Note that the assignment completely changes the %vector and that the
365    *  resulting %vector's size is the same as the number of elements assigned.
366    *  Old data may be lost.
367   */
368   template<class _InputIterator>
369     void
370     assign(_InputIterator __first, _InputIterator __last)
371     {
372       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
373       _M_assign_dispatch(__first, __last, _Integral());
374     }
375
376 protected:
377   template<class _Integer>
378     void
379      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
380      { _M_fill_assign((size_type) __n, (_Tp) __val); }
381
382   template<class _InputIter>
383     void
384     _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
385     {
386       typedef typename iterator_traits<_InputIter>::iterator_category
387                        _IterCategory;
388       _M_assign_aux(__first, __last, _IterCategory());
389     }
390
391   template <class _InputIterator>
392     void 
393     _M_assign_aux(_InputIterator __first, _InputIterator __last,
394                   input_iterator_tag);
395
396   template <class _ForwardIterator>
397     void 
398     _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
399                   forward_iterator_tag);
400
401 public:
402   /// Get a copy of the memory allocation object.
403   allocator_type
404   get_allocator() const { return _Base::get_allocator(); }
405
406   // iterators
407   /**
408    *  Returns a read/write iterator that points to the first element in the
409    *  %vector.  Iteration is done in ordinary element order.
410   */
411   iterator
412   begin() { return iterator (_M_start); }
413
414   /**
415    *  Returns a read-only (constant) iterator that points to the first element
416    *  in the %vector.  Iteration is done in ordinary element order.
417   */
418   const_iterator
419   begin() const { return const_iterator (_M_start); }
420
421   /**
422    *  Returns a read/write iterator that points one past the last element in
423    *  the %vector.  Iteration is done in ordinary element order.
424   */
425   iterator
426   end() { return iterator (_M_finish); }
427
428   /**
429    *  Returns a read-only (constant) iterator that points one past the last
430    *  element in the %vector.  Iteration is done in ordinary element order.
431   */
432   const_iterator
433   end() const { return const_iterator (_M_finish); }
434
435   /**
436    *  Returns a read/write reverse iterator that points to the last element in
437    *  the %vector.  Iteration is done in reverse element order.
438   */
439   reverse_iterator
440   rbegin() { return reverse_iterator(end()); }
441
442   /**
443    *  Returns a read-only (constant) reverse iterator that points to the last
444    *  element in the %vector.  Iteration is done in reverse element order.
445   */
446   const_reverse_iterator
447   rbegin() const { return const_reverse_iterator(end()); }
448
449   /**
450    *  Returns a read/write reverse iterator that points to one before the
451    *  first element in the %vector.  Iteration is done in reverse element
452    *  order.
453   */
454   reverse_iterator
455   rend() { return reverse_iterator(begin()); }
456
457   /**
458    *  Returns a read-only (constant) reverse iterator that points to one
459    *  before the first element in the %vector.  Iteration is done in reverse
460    *  element order.
461   */
462   const_reverse_iterator
463   rend() const { return const_reverse_iterator(begin()); }
464
465   // [23.2.4.2] capacity
466   /**  Returns the number of elements in the %vector.  */
467   size_type
468   size() const { return size_type(end() - begin()); }
469
470   /**  Returns the size() of the largest possible %vector.  */
471   size_type
472   max_size() const { return size_type(-1) / sizeof(_Tp); }
473
474   /**
475    *  @brief  Resizes the %vector to the specified number of elements.
476    *  @param  new_size  Number of elements the %vector should contain.
477    *  @param  x  Data with which new elements should be populated.
478    *
479    *  This function will %resize the %vector to the specified number of
480    *  elements.  If the number is smaller than the %vector's current size the
481    *  %vector is truncated, otherwise the %vector is extended and new elements
482    *  are populated with given data.
483   */
484   void
485   resize(size_type __new_size, const _Tp& __x)
486   {
487     if (__new_size < size())
488       erase(begin() + __new_size, end());
489     else
490       insert(end(), __new_size - size(), __x);
491   }
492
493   /**
494    *  @brief  Resizes the %vector to the specified number of elements.
495    *  @param  new_size  Number of elements the %vector should contain.
496    *
497    *  This function will resize the %vector to the specified number of
498    *  elements.  If the number is smaller than the %vector's current size the
499    *  %vector is truncated, otherwise the %vector is extended and new elements
500    *  are default-constructed.
501   */
502   void
503   resize(size_type __new_size) { resize(__new_size, _Tp()); }
504
505   /**
506    *  Returns the total number of elements that the %vector can hold before
507    *  needing to allocate more memory.
508   */
509   size_type
510   capacity() const
511     { return size_type(const_iterator(_M_end_of_storage) - begin()); }
512
513   /**
514    *  Returns true if the %vector is empty.  (Thus begin() would equal end().)
515   */
516   bool
517   empty() const { return begin() == end(); }
518
519   /**
520    *  @brief  Attempt to preallocate enough memory for specified number of
521    *          elements.
522    *  @param  n  Number of elements required.
523    *  @throw  std::length_error  If @a n exceeds @c max_size().
524    *
525    *  This function attempts to reserve enough memory for the %vector to hold
526    *  the specified number of elements.  If the number requested is more than
527    *  max_size(), length_error is thrown.
528    *
529    *  The advantage of this function is that if optimal code is a necessity
530    *  and the user can determine the number of elements that will be required,
531    *  the user can reserve the memory in %advance, and thus prevent a possible
532    *  reallocation of memory and copying of %vector data.
533   */
534   void
535   reserve(size_type __n)   // FIXME should be out of class
536   {
537     if (capacity() < __n) {
538       const size_type __old_size = size();
539       pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
540       _Destroy(_M_start, _M_finish);
541       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
542       _M_start = __tmp;
543       _M_finish = __tmp + __old_size;
544       _M_end_of_storage = _M_start + __n;
545     }
546   }
547
548   // element access
549   /**
550    *  @brief  Subscript access to the data contained in the %vector.
551    *  @param  n  The index of the element for which data should be accessed.
552    *  @return  Read/write reference to data.
553    *
554    *  This operator allows for easy, array-style, data access.
555    *  Note that data access with this operator is unchecked and out_of_range
556    *  lookups are not defined. (For checked lookups see at().)
557   */
558   reference
559   operator[](size_type __n) { return *(begin() + __n); }
560
561   /**
562    *  @brief  Subscript access to the data contained in the %vector.
563    *  @param  n  The index of the element for which data should be accessed.
564    *  @return  Read-only (constant) reference to data.
565    *
566    *  This operator allows for easy, array-style, data access.
567    *  Note that data access with this operator is unchecked and out_of_range
568    *  lookups are not defined. (For checked lookups see at().)
569   */
570   const_reference
571   operator[](size_type __n) const { return *(begin() + __n); }
572
573 protected:
574   /// @if maint Safety check used only from at().  @endif
575   void
576   _M_range_check(size_type __n) const
577   {
578     if (__n >= this->size())
579       __throw_out_of_range("vector [] access out of range");
580   }
581
582 public:
583   /**
584    *  @brief  Provides access to the data contained in the %vector.
585    *  @param  n  The index of the element for which data should be accessed.
586    *  @return  Read/write reference to data.
587    *  @throw  std::out_of_range  If @a n is an invalid index.
588    *
589    *  This function provides for safer data access.  The parameter is first
590    *  checked that it is in the range of the vector.  The function throws
591    *  out_of_range if the check fails.
592   */
593   reference
594   at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
595
596   /**
597    *  @brief  Provides access to the data contained in the %vector.
598    *  @param  n  The index of the element for which data should be accessed.
599    *  @return  Read-only (constant) reference to data.
600    *  @throw  std::out_of_range  If @a n is an invalid index.
601    *
602    *  This function provides for safer data access.  The parameter is first
603    *  checked that it is in the range of the vector.  The function throws
604    *  out_of_range if the check fails.
605   */
606   const_reference
607   at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
608
609   /**
610    *  Returns a read/write reference to the data at the first element of the
611    *  %vector.
612   */
613   reference
614   front() { return *begin(); }
615
616   /**
617    *  Returns a read-only (constant) reference to the data at the first
618    *  element of the %vector.
619   */
620   const_reference
621   front() const { return *begin(); }
622
623   /**
624    *  Returns a read/write reference to the data at the last element of the
625    *  %vector.
626   */
627   reference
628   back() { return *(end() - 1); }
629
630   /**
631    *  Returns a read-only (constant) reference to the data at the last
632    *  element of the %vector.
633   */
634   const_reference
635   back() const { return *(end() - 1); }
636
637   // [23.2.4.3] modifiers
638   /**
639    *  @brief  Add data to the end of the %vector.
640    *  @param  x  Data to be added.
641    *
642    *  This is a typical stack operation.  The function creates an element at
643    *  the end of the %vector and assigns the given data to it.
644    *  Due to the nature of a %vector this operation can be done in constant
645    *  time if the %vector has preallocated space available.
646   */
647   void
648   push_back(const _Tp& __x)
649   {
650     if (_M_finish != _M_end_of_storage) {
651       _Construct(_M_finish, __x);
652       ++_M_finish;
653     }
654     else
655       _M_insert_aux(end(), __x);
656   }
657
658   /**
659    *  @brief  Removes last element.
660    *
661    *  This is a typical stack operation. It shrinks the %vector by one.
662    *
663    *  Note that no data is returned, and if the last element's data is
664    *  needed, it should be retrieved before pop_back() is called.
665   */
666   void
667   pop_back()
668   {
669     --_M_finish;
670     _Destroy(_M_finish);
671   }
672
673   /**
674    *  @brief  Inserts given value into %vector before specified iterator.
675    *  @param  position  An iterator into the %vector.
676    *  @param  x  Data to be inserted.
677    *  @return  An iterator that points to the inserted data.
678    *
679    *  This function will insert a copy of the given value before the specified
680    *  location.
681    *  Note that this kind of operation could be expensive for a %vector and if
682    *  it is frequently used the user should consider using std::list.
683   */
684   iterator
685   insert(iterator __position, const _Tp& __x)
686   {
687     size_type __n = __position - begin();
688     if (_M_finish != _M_end_of_storage && __position == end()) {
689       _Construct(_M_finish, __x);
690       ++_M_finish;
691     }
692     else
693       _M_insert_aux(iterator(__position), __x);
694     return begin() + __n;
695   }
696
697 #ifdef _GLIBCPP_DEPRECATED
698   /**
699    *  @brief  Inserts an element into the %vector.
700    *  @param  position  An iterator into the %vector.
701    *  @return  An iterator that points to the inserted element.
702    *
703    *  This function will insert a default-constructed element before the
704    *  specified location.  You should consider using insert(position,Tp())
705    *  instead.
706    *  Note that this kind of operation could be expensive for a vector and if
707    *  it is frequently used the user should consider using std::list.
708    *
709    *  @note This was deprecated in 3.2 and will be removed in 3.3.  You must
710    *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
711    *        c++config.h.
712   */
713   iterator
714   insert(iterator __position)
715   {
716     size_type __n = __position - begin();
717     if (_M_finish != _M_end_of_storage && __position == end()) {
718       _Construct(_M_finish);
719       ++_M_finish;
720     }
721     else
722       _M_insert_aux(iterator(__position));
723     return begin() + __n;
724   }
725 #endif
726
727   /**
728    *  @brief  Inserts a number of copies of given data into the %vector.
729    *  @param  position  An iterator into the %vector.
730    *  @param  n  Number of elements to be inserted.
731    *  @param  x  Data to be inserted.
732    *
733    *  This function will insert a specified number of copies of the given data
734    *  before the location specified by @a position.
735    *
736    *  Note that this kind of operation could be expensive for a %vector and if
737    *  it is frequently used the user should consider using std::list.
738   */
739   void
740   insert (iterator __pos, size_type __n, const _Tp& __x)
741     { _M_fill_insert(__pos, __n, __x); }
742
743 protected:
744   void
745   _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
746
747 public:
748   /**
749    *  @brief  Inserts a range into the %vector.
750    *  @param  pos  An iterator into the %vector.
751    *  @param  first  An input iterator.
752    *  @param  last   An input iterator.
753    *
754    *  This function will insert copies of the data in the range [first,last)
755    *  into the %vector before the location specified by @a pos.
756    *
757    *  Note that this kind of operation could be expensive for a %vector and if
758    *  it is frequently used the user should consider using std::list.
759   */
760   template<class _InputIterator>
761     void
762     insert(iterator __pos, _InputIterator __first, _InputIterator __last)
763       {
764         // Check whether it's an integral type.  If so, it's not an iterator.
765         typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
766         _M_insert_dispatch(__pos, __first, __last, _Integral());
767       }
768
769 protected:
770   template<class _Integer>
771     void
772     _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
773                        __true_type)
774     {
775       _M_fill_insert(__pos, static_cast<size_type>(__n),
776                             static_cast<_Tp>(__val));
777     }
778
779   template<class _InputIterator>
780     void
781     _M_insert_dispatch(iterator __pos, _InputIterator __first,
782                        _InputIterator __last, __false_type)
783     {
784       typedef typename iterator_traits<_InputIterator>::iterator_category
785                        _IterCategory;
786       _M_range_insert(__pos, __first, __last, _IterCategory());
787     }
788
789 public:
790   /**
791    *  @brief  Remove element at given position.
792    *  @param  position  Iterator pointing to element to be erased.
793    *  @return  An iterator pointing to the next element (or end()).
794    *
795    *  This function will erase the element at the given position and thus
796    *  shorten the %vector by one.
797    *
798    *  Note This operation could be expensive and if it is frequently used the
799    *  user should consider using std::list.  The user is also cautioned that
800    *  this function only erases the element, and that if the element is itself
801    *  a pointer, the pointed-to memory is not touched in any way.  Managing
802    *  the pointer is the user's responsibilty.
803   */
804   iterator
805   erase(iterator __position)
806   {
807     if (__position + 1 != end())
808       copy(__position + 1, end(), __position);
809     --_M_finish;
810     _Destroy(_M_finish);
811     return __position;
812   }
813
814   /**
815    *  @brief  Remove a range of elements.
816    *  @param  first  Iterator pointing to the first element to be erased.
817    *  @param  last  Iterator pointing to one past the last element to be erased.
818    *  @return  An iterator pointing to the element pointed to by @a last
819    *           prior to erasing (or end()).
820    *
821    *  This function will erase the elements in the range [first,last) and
822    *  shorten the %vector accordingly.
823    *
824    *  Note This operation could be expensive and if it is frequently used the
825    *  user should consider using std::list.  The user is also cautioned that
826    *  this function only erases the elements, and that if the elements
827    *  themselves are pointers, the pointed-to memory is not touched in any
828    *  way.  Managing the pointer is the user's responsibilty.
829   */
830   iterator
831   erase(iterator __first, iterator __last)
832   {
833     iterator __i(copy(__last, end(), __first));
834     _Destroy(__i, end());
835     _M_finish = _M_finish - (__last - __first);
836     return __first;
837   }
838
839   /**
840    *  @brief  Swaps data with another %vector.
841    *  @param  x  A %vector of the same element and allocator types.
842    *
843    *  This exchanges the elements between two vectors in constant time.
844    *  (Three pointers, so it should be quite fast.)
845    *  Note that the global std::swap() function is specialized such that
846    *  std::swap(v1,v2) will feed to this function.
847   */
848   void
849   swap(vector<_Tp, _Alloc>& __x)
850   {
851     std::swap(_M_start, __x._M_start);
852     std::swap(_M_finish, __x._M_finish);
853     std::swap(_M_end_of_storage, __x._M_end_of_storage);
854   }
855
856   /**
857    *  Erases all the elements.  Note that this function only erases the
858    *  elements, and that if the elements themselves are pointers, the
859    *  pointed-to memory is not touched in any way.  Managing the pointer is
860    *  the user's responsibilty.
861   */
862   void
863   clear() { erase(begin(), end()); }
864
865 protected:
866   template <class _ForwardIterator>
867   pointer
868     _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
869                          _ForwardIterator __last)
870   {
871     pointer __result = _M_allocate(__n);
872     try
873       {
874         uninitialized_copy(__first, __last, __result);
875         return __result;
876       }
877     catch(...)
878       {
879         _M_deallocate(__result, __n);
880         __throw_exception_again;
881       }
882   }
883
884   template <class _InputIterator>
885   void
886     _M_range_initialize(_InputIterator __first,
887                         _InputIterator __last, input_iterator_tag)
888   {
889     for ( ; __first != __last; ++__first)
890       push_back(*__first);
891   }
892
893   // This function is only called by the constructor.
894   template <class _ForwardIterator>
895   void _M_range_initialize(_ForwardIterator __first,
896                            _ForwardIterator __last, forward_iterator_tag)
897   {
898     size_type __n = distance(__first, __last);
899     _M_start = _M_allocate(__n);
900     _M_end_of_storage = _M_start + __n;
901     _M_finish = uninitialized_copy(__first, __last, _M_start);
902   }
903
904   template <class _InputIterator>
905   void _M_range_insert(iterator __pos,
906                        _InputIterator __first, _InputIterator __last,
907                        input_iterator_tag);
908
909   template <class _ForwardIterator>
910   void _M_range_insert(iterator __pos,
911                        _ForwardIterator __first, _ForwardIterator __last,
912                        forward_iterator_tag);
913 };
914
915
916 /**
917  *  @brief  Vector equality comparison.
918  *  @param  x  A %vector.
919  *  @param  y  A %vector of the same type as @a x.
920  *  @return  True iff the size and elements of the vectors are equal.
921  *
922  *  This is an equivalence relation.  It is linear in the size of the
923  *  vectors.  Vectors are considered equivalent if their sizes are equal,
924  *  and if corresponding elements compare equal.
925 */
926 template <class _Tp, class _Alloc>
927 inline bool
928 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
929 {
930   return __x.size() == __y.size() &&
931          equal(__x.begin(), __x.end(), __y.begin());
932 }
933
934 /**
935  *  @brief  Vector ordering relation.
936  *  @param  x  A %vector.
937  *  @param  y  A %vector of the same type as @a x.
938  *  @return  True iff @a x is lexographically less than @a y.
939  *
940  *  This is a total ordering relation.  It is linear in the size of the
941  *  vectors.  The elements must be comparable with @c <.
942  *
943  *  See std::lexographical_compare() for how the determination is made.
944 */
945 template <class _Tp, class _Alloc>
946 inline bool
947 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
948 {
949   return lexicographical_compare(__x.begin(), __x.end(),
950                                  __y.begin(), __y.end());
951 }
952
953 /// See std::vector::swap().
954 template <class _Tp, class _Alloc>
955 inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
956 {
957   __x.swap(__y);
958 }
959
960 /// Based on operator==
961 template <class _Tp, class _Alloc>
962 inline bool
963 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
964   return !(__x == __y);
965 }
966
967 /// Based on operator<
968 template <class _Tp, class _Alloc>
969 inline bool
970 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
971   return __y < __x;
972 }
973
974 /// Based on operator<
975 template <class _Tp, class _Alloc>
976 inline bool
977 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
978   return !(__y < __x);
979 }
980
981 /// Based on operator<
982 template <class _Tp, class _Alloc>
983 inline bool
984 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
985   return !(__x < __y);
986 }
987
988 // XXX begin tcc me
989 template <class _Tp, class _Alloc>
990 vector<_Tp,_Alloc>&
991 vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
992 {
993   if (&__x != this) {
994     const size_type __xlen = __x.size();
995     if (__xlen > capacity()) {
996       pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
997       _Destroy(_M_start, _M_finish);
998       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
999       _M_start = __tmp;
1000       _M_end_of_storage = _M_start + __xlen;
1001     }
1002     else if (size() >= __xlen) {
1003       iterator __i(copy(__x.begin(), __x.end(), begin()));
1004       _Destroy(__i, end());
1005     }
1006     else {
1007       copy(__x.begin(), __x.begin() + size(), _M_start);
1008       uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
1009     }
1010     _M_finish = _M_start + __xlen;
1011   }
1012   return *this;
1013 }
1014
1015 template <class _Tp, class _Alloc>
1016 void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val)
1017 {
1018   if (__n > capacity()) {
1019     vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
1020     __tmp.swap(*this);
1021   }
1022   else if (__n > size()) {
1023     fill(begin(), end(), __val);
1024     _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
1025   }
1026   else
1027     erase(fill_n(begin(), __n, __val), end());
1028 }
1029
1030 template <class _Tp, class _Alloc> template <class _InputIter>
1031 void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
1032                                         input_iterator_tag) {
1033   iterator __cur(begin());
1034   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
1035     *__cur = *__first;
1036   if (__first == __last)
1037     erase(__cur, end());
1038   else
1039     insert(end(), __first, __last);
1040 }
1041
1042 template <class _Tp, class _Alloc> template <class _ForwardIter>
1043 void
1044 vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
1045                                    forward_iterator_tag) {
1046   size_type __len = distance(__first, __last);
1047
1048   if (__len > capacity()) {
1049     pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
1050     _Destroy(_M_start, _M_finish);
1051     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1052     _M_start = __tmp;
1053     _M_end_of_storage = _M_finish = _M_start + __len;
1054   }
1055   else if (size() >= __len) {
1056     iterator __new_finish(copy(__first, __last, _M_start));
1057     _Destroy(__new_finish, end());
1058     _M_finish = __new_finish.base();
1059   }
1060   else {
1061     _ForwardIter __mid = __first;
1062     advance(__mid, size());
1063     copy(__first, __mid, _M_start);
1064     _M_finish = uninitialized_copy(__mid, __last, _M_finish);
1065   }
1066 }
1067
1068 template <class _Tp, class _Alloc>
1069 void
1070 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
1071 {
1072   if (_M_finish != _M_end_of_storage) {
1073     _Construct(_M_finish, *(_M_finish - 1));
1074     ++_M_finish;
1075     _Tp __x_copy = __x;
1076     copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
1077     *__position = __x_copy;
1078   }
1079   else {
1080     const size_type __old_size = size();
1081     const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
1082     iterator __new_start(_M_allocate(__len));
1083     iterator __new_finish(__new_start);
1084     try {
1085       __new_finish = uninitialized_copy(iterator(_M_start), __position,
1086                                         __new_start);
1087       _Construct(__new_finish.base(), __x);
1088       ++__new_finish;
1089       __new_finish = uninitialized_copy(__position, iterator(_M_finish),
1090                                         __new_finish);
1091     }
1092     catch(...)
1093       {
1094         _Destroy(__new_start,__new_finish);
1095         _M_deallocate(__new_start.base(),__len);
1096         __throw_exception_again;
1097       }
1098     _Destroy(begin(), end());
1099     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1100     _M_start = __new_start.base();
1101     _M_finish = __new_finish.base();
1102     _M_end_of_storage = __new_start.base() + __len;
1103   }
1104 }
1105
1106 #ifdef _GLIBCPP_DEPRECATED
1107 template <class _Tp, class _Alloc>
1108 void
1109 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
1110 {
1111   if (_M_finish != _M_end_of_storage) {
1112     _Construct(_M_finish, *(_M_finish - 1));
1113     ++_M_finish;
1114     copy_backward(__position, iterator(_M_finish - 2),
1115                   iterator(_M_finish - 1));
1116     *__position = _Tp();
1117   }
1118   else {
1119     const size_type __old_size = size();
1120     const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
1121     pointer __new_start = _M_allocate(__len);
1122     pointer __new_finish = __new_start;
1123     try {
1124       __new_finish = uninitialized_copy(iterator(_M_start), __position,
1125                                         __new_start);
1126       _Construct(__new_finish);
1127       ++__new_finish;
1128       __new_finish = uninitialized_copy(__position, iterator(_M_finish),
1129                                         __new_finish);
1130     }
1131     catch(...)
1132       {
1133         _Destroy(__new_start,__new_finish);
1134         _M_deallocate(__new_start,__len);
1135         __throw_exception_again;
1136       }
1137     _Destroy(begin(), end());
1138     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1139     _M_start = __new_start;
1140     _M_finish = __new_finish;
1141     _M_end_of_storage = __new_start + __len;
1142   }
1143 }
1144 #endif
1145
1146 template <class _Tp, class _Alloc>
1147 void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
1148                                          const _Tp& __x)
1149 {
1150   if (__n != 0) {
1151     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
1152       _Tp __x_copy = __x;
1153       const size_type __elems_after = end() - __position;
1154       iterator __old_finish(_M_finish);
1155       if (__elems_after > __n) {
1156         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
1157         _M_finish += __n;
1158         copy_backward(__position, __old_finish - __n, __old_finish);
1159         fill(__position, __position + __n, __x_copy);
1160       }
1161       else {
1162         uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
1163         _M_finish += __n - __elems_after;
1164         uninitialized_copy(__position, __old_finish, _M_finish);
1165         _M_finish += __elems_after;
1166         fill(__position, __old_finish, __x_copy);
1167       }
1168     }
1169     else {
1170       const size_type __old_size = size();
1171       const size_type __len = __old_size + max(__old_size, __n);
1172       iterator __new_start(_M_allocate(__len));
1173       iterator __new_finish(__new_start);
1174       try {
1175         __new_finish = uninitialized_copy(begin(), __position, __new_start);
1176         __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
1177         __new_finish
1178           = uninitialized_copy(__position, end(), __new_finish);
1179       }
1180       catch(...)
1181         {
1182           _Destroy(__new_start,__new_finish);
1183           _M_deallocate(__new_start.base(),__len);
1184           __throw_exception_again;
1185         }
1186       _Destroy(_M_start, _M_finish);
1187       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1188       _M_start = __new_start.base();
1189       _M_finish = __new_finish.base();
1190       _M_end_of_storage = __new_start.base() + __len;
1191     }
1192   }
1193 }
1194
1195 template <class _Tp, class _Alloc> template <class _InputIterator>
1196 void
1197 vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
1198                                      _InputIterator __first,
1199                                      _InputIterator __last,
1200                                      input_iterator_tag)
1201 {
1202   for ( ; __first != __last; ++__first) {
1203     __pos = insert(__pos, *__first);
1204     ++__pos;
1205   }
1206 }
1207
1208 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1209 void
1210 vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
1211                                      _ForwardIterator __first,
1212                                      _ForwardIterator __last,
1213                                      forward_iterator_tag)
1214 {
1215   if (__first != __last) {
1216     size_type __n = distance(__first, __last);
1217     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
1218       const size_type __elems_after = end() - __position;
1219       iterator __old_finish(_M_finish);
1220       if (__elems_after > __n) {
1221         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
1222         _M_finish += __n;
1223         copy_backward(__position, __old_finish - __n, __old_finish);
1224         copy(__first, __last, __position);
1225       }
1226       else {
1227         _ForwardIterator __mid = __first;
1228         advance(__mid, __elems_after);
1229         uninitialized_copy(__mid, __last, _M_finish);
1230         _M_finish += __n - __elems_after;
1231         uninitialized_copy(__position, __old_finish, _M_finish);
1232         _M_finish += __elems_after;
1233         copy(__first, __mid, __position);
1234       }
1235     }
1236     else {
1237       const size_type __old_size = size();
1238       const size_type __len = __old_size + max(__old_size, __n);
1239       iterator __new_start(_M_allocate(__len));
1240       iterator __new_finish(__new_start);
1241       try {
1242         __new_finish = uninitialized_copy(iterator(_M_start),
1243                                           __position, __new_start);
1244         __new_finish = uninitialized_copy(__first, __last, __new_finish);
1245         __new_finish
1246           = uninitialized_copy(__position, iterator(_M_finish), __new_finish);
1247       }
1248       catch(...)
1249         {
1250           _Destroy(__new_start,__new_finish);
1251           _M_deallocate(__new_start.base(), __len);
1252           __throw_exception_again;
1253         }
1254       _Destroy(_M_start, _M_finish);
1255       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1256       _M_start = __new_start.base();
1257       _M_finish = __new_finish.base();
1258       _M_end_of_storage = __new_start.base() + __len;
1259     }
1260   }
1261 }
1262
1263 } // namespace std
1264
1265 #endif /* __GLIBCPP_INTERNAL_VECTOR_H */
1266