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 namespace std
69 {
70 
71 // The vector base class serves two purposes.  First, its constructor
72 // and destructor allocate (but don't initialize) storage.  This makes
73 // exception safety easier.  Second, the base class encapsulates all of
74 // the differences between SGI-style allocators and standard-conforming
75 // allocators.
76 
77 // Base class for ordinary allocators.
78 template <class _Tp, class _Allocator, bool _IsStatic>
79 class _Vector_alloc_base {
80 public:
81   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
82           allocator_type;
83   allocator_type get_allocator() const { return _M_data_allocator; }
84 
85   _Vector_alloc_base(const allocator_type& __a)
86     : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
87   {}
88 
89 protected:
90   allocator_type _M_data_allocator;
91   _Tp* _M_start;
92   _Tp* _M_finish;
93   _Tp* _M_end_of_storage;
94 
95   _Tp* _M_allocate(size_t __n)
96     { return _M_data_allocator.allocate(__n); }
97   void _M_deallocate(_Tp* __p, size_t __n)
98     { if (__p) _M_data_allocator.deallocate(__p, __n); }
99 };
100 
101 // Specialization for allocators that have the property that we don't
102 // actually have to store an allocator object.
103 template <class _Tp, class _Allocator>
104 class _Vector_alloc_base<_Tp, _Allocator, true> {
105 public:
106   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
107           allocator_type;
108   allocator_type get_allocator() const { return allocator_type(); }
109 
110   _Vector_alloc_base(const allocator_type&)
111     : _M_start(0), _M_finish(0), _M_end_of_storage(0)
112   {}
113 
114 protected:
115   _Tp* _M_start;
116   _Tp* _M_finish;
117   _Tp* _M_end_of_storage;
118 
119   typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
120   _Tp* _M_allocate(size_t __n)
121     { return _Alloc_type::allocate(__n); }
122   void _M_deallocate(_Tp* __p, size_t __n)
123     { _Alloc_type::deallocate(__p, __n);}
124 };
125 
126 template <class _Tp, class _Alloc>
127 struct _Vector_base
128   : public _Vector_alloc_base<_Tp, _Alloc,
129                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
130 {
131   typedef _Vector_alloc_base<_Tp, _Alloc,
132                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
133           _Base;
134   typedef typename _Base::allocator_type allocator_type;
135 
136   _Vector_base(const allocator_type& __a) : _Base(__a) {}
137   _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
138     _M_start = _M_allocate(__n);
139     _M_finish = _M_start;
140     _M_end_of_storage = _M_start + __n;
141   }
142 
143   ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
144 };
145 
146 
147 /**
148  *  @brief  A standard container which offers fixed time access to individual
149  *  elements in any order.
150  *
151  *  @ingroup Containers
152  *  @ingroup Sequences
153  *
154  *  Meets the requirements of a <a href="tables.html#65">container</a>, a
155  *  <a href="tables.html#66">reversible container</a>, and a
156  *  <a href="tables.html#67">sequence</a>, including the
157  *  <a href="tables.html#68">optional sequence requirements</a> with the
158  *  %exception of @c push_front and @c pop_front.
159  *
160  *  In some terminology a vector can be described as a dynamic C-style array,
161  *  it offers fast and efficient access to individual elements in any order
162  *  and saves the user from worrying about memory and size allocation.
163  *  Subscripting ( [] ) access is also provided as with C-style arrays.
164 */
165 template <class _Tp, class _Alloc = allocator<_Tp> >
166 class vector : protected _Vector_base<_Tp, _Alloc>
167 {
168   // concept requirements
169   __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
170 
171 private:
172   typedef _Vector_base<_Tp, _Alloc> _Base;
173   typedef vector<_Tp, _Alloc> vector_type;
174 public:
175   typedef _Tp 						value_type;
176   typedef value_type* 					pointer;
177   typedef const value_type* 				const_pointer;
178   typedef __gnu_cxx::__normal_iterator<pointer, vector_type> 	iterator;
179   typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
180                                                         const_iterator;
181   typedef value_type& 					reference;
182   typedef const value_type& 				const_reference;
183   typedef size_t 					size_type;
184   typedef ptrdiff_t 					difference_type;
185 
186   typedef typename _Base::allocator_type allocator_type;
187   allocator_type get_allocator() const { return _Base::get_allocator(); }
188 
189   typedef reverse_iterator<const_iterator> const_reverse_iterator;
190   typedef reverse_iterator<iterator> reverse_iterator;
191 
192 protected:
193   using _Base::_M_allocate;
194   using _Base::_M_deallocate;
195   using _Base::_M_start;
196   using _Base::_M_finish;
197   using _Base::_M_end_of_storage;
198 
199 protected:
200   void _M_insert_aux(iterator __position, const _Tp& __x);
201   void _M_insert_aux(iterator __position);
202 
203 public:
204   /**
205    *  Returns a read/write iterator that points to the first element in the
206    *  vector.  Iteration is done in ordinary element order.
207   */
208   iterator begin() { return iterator (_M_start); }
209 
210   /**
211    *  Returns a read-only (constant) iterator that points to the first element
212    *  in the vector.  Iteration is done in ordinary element order.
213   */
214   const_iterator begin() const
215     { return const_iterator (_M_start); }
216 
217   /**
218    *  Returns a read/write iterator that points one past the last element in
219    *  the vector.  Iteration is done in ordinary element order.
220   */
221   iterator end() { return iterator (_M_finish); }
222 
223   /**
224    *  Returns a read-only (constant) iterator that points one past the last
225    *  element in the vector.  Iteration is done in ordinary element order.
226   */
227   const_iterator end() const { return const_iterator (_M_finish); }
228 
229   /**
230    *  Returns a read/write reverse iterator that points to the last element in
231    *  the vector.  Iteration is done in reverse element order.
232   */
233   reverse_iterator rbegin()
234     { return reverse_iterator(end()); }
235 
236   /**
237    *  Returns a read-only (constant) reverse iterator that points to the last
238    *  element in the vector.  Iteration is done in reverse element order.
239   */
240   const_reverse_iterator rbegin() const
241     { return const_reverse_iterator(end()); }
242 
243   /**
244    *  Returns a read/write reverse iterator that points to one before the
245    *  first element in the vector.  Iteration is done in reverse element
246    *  order.
247   */
248   reverse_iterator rend()
249     { return reverse_iterator(begin()); }
250 
251   /**
252    *  Returns a read-only (constant) reverse iterator that points to one
253    *  before the first element in the vector.  Iteration is done in reverse
254    *  element order.
255   */
256   const_reverse_iterator rend() const
257     { return const_reverse_iterator(begin()); }
258 
259   /**  Returns the number of elements in the vector.  */
260   size_type size() const
261     { return size_type(end() - begin()); }
262 
263   /**  Returns the size of the largest possible vector.  */
264   size_type max_size() const
265     { return size_type(-1) / sizeof(_Tp); }
266 
267   /**
268    *  Returns the amount of memory that has been alocated for the current
269    *  elements (?).
270   */
271   size_type capacity() const
272     { return size_type(const_iterator(_M_end_of_storage) - begin()); }
273 
274   /**
275    *  Returns true if the vector is empty.  (Thus begin() would equal end().)
276   */
277   bool empty() const
278     { return begin() == end(); }
279 
280   /**
281    *  @brief  Subscript access to the data contained in the vector.
282    *  @param  n  The element for which data should be accessed.
283    *  @return  Read/write reference to data.
284    *
285    *  This operator allows for easy, array-style, data access.
286    *  Note that data access with this operator is unchecked and out_of_range
287    *  lookups are not defined. (For checked lookups see at().)
288   */
289   reference operator[](size_type __n) { return *(begin() + __n); }
290 
291   /**
292    *  @brief  Subscript access to the data contained in the vector.
293    *  @param  n  The element for which data should be accessed.
294    *  @return  Read-only (constant) reference to data.
295    *
296    *  This operator allows for easy, array-style, data access.
297    *  Note that data access with this operator is unchecked and out_of_range
298    *  lookups are not defined. (For checked lookups see at().)
299   */
300   const_reference operator[](size_type __n) const { return *(begin() + __n); }
301 
302   void _M_range_check(size_type __n) const {
303     if (__n >= this->size())
304       __throw_out_of_range("vector");
305   }
306 
307   /**
308    *  @brief  Provides access to the data contained in the vector.
309    *  @param  n  The element for which data should be accessed.
310    *  @return  Read/write reference to data.
311    *
312    *  This function provides for safer data access.  The parameter is first
313    *  checked that it is in the range of the vector.  The function throws
314    *  out_of_range if the check fails.
315   */
316   reference at(size_type __n)
317     { _M_range_check(__n); return (*this)[__n]; }
318 
319   /**
320    *  @brief  Provides access to the data contained in the vector.
321    *  @param  n  The element for which data should be accessed.
322    *  @return  Read-only (constant) reference to data.
323    *
324    *  This function provides for safer data access.  The parameter is first
325    *  checked that it is in the range of the vector.  The function throws
326    *  out_of_range if the check fails.
327   */
328   const_reference at(size_type __n) const
329     { _M_range_check(__n); return (*this)[__n]; }
330 
331 
332   explicit vector(const allocator_type& __a = allocator_type())
333     : _Base(__a) {}
334 
335   vector(size_type __n, const _Tp& __value,
336          const allocator_type& __a = allocator_type())
337     : _Base(__n, __a)
338     { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
339 
340   explicit vector(size_type __n)
341     : _Base(__n, allocator_type())
342     { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
343 
344   vector(const vector<_Tp, _Alloc>& __x)
345     : _Base(__x.size(), __x.get_allocator())
346     { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
347 
348   // Check whether it's an integral type.  If so, it's not an iterator.
349   template <class _InputIterator>
350     vector(_InputIterator __first, _InputIterator __last,
351            const allocator_type& __a = allocator_type())
352 	: _Base(__a)
353 	{
354       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
355       _M_initialize_aux(__first, __last, _Integral());
356     }
357 
358   template <class _Integer>
359     void _M_initialize_aux(_Integer __n, _Integer __value, __true_type)
360 	{
361       _M_start = _M_allocate(__n);
362       _M_end_of_storage = _M_start + __n;
363       _M_finish = uninitialized_fill_n(_M_start, __n, __value);
364     }
365 
366   template<class _InputIterator>
367     void
368 	_M_initialize_aux(_InputIterator __first, _InputIterator __last, __false_type)
369 	{
370 	  typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
371 	  _M_range_initialize(__first, __last, _IterCategory());
372 	}
373 
374   ~vector()
375   { _Destroy(_M_start, _M_finish); }
376 
377   vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
378 
379   /**
380    *  @brief  Attempt to preallocate enough memory for specified number of
381    *          elements.
382    *  @param  n  Number of elements required
383    *
384    *  This function attempts to reserve enough memory for the vector to hold
385    *  the specified number of elements.  If the number requested is more than
386    *  max_size() length_error is thrown.
387    *
388    *  The advantage of this function is that if optimal code is a necessity
389    *  and the user can determine the number of elements that will be required
390    *  the user can reserve the memory and thus prevent a possible
391    *  reallocation of memory and copy of vector data.
392   */
393   void reserve(size_type __n) {
394     if (__n > this->max_size())
395       __throw_length_error("vector::reserve");
396     if (this->capacity() < __n) {
397       const size_type __old_size = size();
398       pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
399       _Destroy(_M_start, _M_finish);
400       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
401       _M_start = __tmp;
402       _M_finish = __tmp + __old_size;
403       _M_end_of_storage = _M_start + __n;
404     }
405   }
406 
407   // assign(), a generalized assignment member function.  Two
408   // versions: one that takes a count, and one that takes a range.
409   // The range version is a member template, so we dispatch on whether
410   // or not the type is an integer.
411 
412   /**
413    *  @brief  Assigns a given value or range to a vector.
414    *  @param  n  Number of elements to be assigned.
415    *  @param  val  Value to be assigned.
416    *
417    *  This function can be used to assign a range to a vector or fill it
418    *  with a specified number of copies of the given value.
419    *  Note that the assignment completely changes the vector and that the
420    *  resulting vector's size is the same as the number of elements assigned.
421    *  Old data may be lost.
422   */
423   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
424   void _M_fill_assign(size_type __n, const _Tp& __val);
425 
426   template<class _InputIterator>
427     void
428     assign(_InputIterator __first, _InputIterator __last)
429     {
430       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
431       _M_assign_dispatch(__first, __last, _Integral());
432     }
433 
434   template<class _Integer>
435     void
436      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
437      { _M_fill_assign((size_type) __n, (_Tp) __val); }
438 
439   template<class _InputIter>
440     void
441     _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
442     {
443       typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
444       _M_assign_aux(__first, __last, _IterCategory());
445     }
446 
447   template <class _InputIterator>
448     void
449     _M_assign_aux(_InputIterator __first, _InputIterator __last,
450 		  input_iterator_tag);
451 
452   template <class _ForwardIterator>
453     void
454     _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
455 		  forward_iterator_tag);
456 
457   /**
458    *  Returns a read/write reference to the data at the first element of the
459    *  vector.
460   */
461   reference front() { return *begin(); }
462 
463   /**
464    *  Returns a read-only (constant) reference to the data at the first
465    *  element of the vector.
466   */
467   const_reference front() const { return *begin(); }
468 
469   /**
470    *  Returns a read/write reference to the data at the last element of the
471    *  vector.
472   */
473   reference back() { return *(end() - 1); }
474 
475   /**
476    *  Returns a read-only (constant) reference to the data at the first
477    *  element of the vector.
478   */
479   const_reference back() const { return *(end() - 1); }
480 
481   /**
482    *  @brief  Add data to the end of the vector.
483    *  @param  x  Data to be added.
484    *
485    *  This is a typical stack operation.  The function creates an element at
486    *  the end of the vector and assigns the given data to it.
487    *  Due to the nature of a vector this operation can be done in constant
488    *  time if the vector has preallocated space available.
489   */
490   void
491   push_back(const _Tp& __x)
492   {
493     if (_M_finish != _M_end_of_storage) {
494       _Construct(_M_finish, __x);
495       ++_M_finish;
496     }
497     else
498       _M_insert_aux(end(), __x);
499   }
500 
501 #ifdef _GLIBCPP_DEPRECATED
502   /**
503    *  Add an element to the end of the vector.  The element is
504    *  default-constructed.
505    *
506    *  @note You must define _GLIBCPP_DEPRECATED to make this visible; see
507    *        c++config.h.
508   */
509   void
510   push_back()
511   {
512     if (_M_finish != _M_end_of_storage) {
513       _Construct(_M_finish);
514       ++_M_finish;
515     }
516     else
517       _M_insert_aux(end());
518   }
519 #endif
520 
521   void
522   swap(vector<_Tp, _Alloc>& __x)
523   {
524     std::swap(_M_start, __x._M_start);
525     std::swap(_M_finish, __x._M_finish);
526     std::swap(_M_end_of_storage, __x._M_end_of_storage);
527   }
528 
529   /**
530    *  @brief  Inserts given value into vector at specified element.
531    *  @param  position  An iterator that points to the element where data
532    *                    should be inserted.
533    *  @param  x  Data to be inserted.
534    *  @return  An iterator that points to the inserted data.
535    *
536    *  This function will insert the given value into the specified location.
537    *  Note that this kind of operation could be expensive for a vector and if
538    *  it is frequently used the user should consider using std::list.
539   */
540   iterator
541   insert(iterator __position, const _Tp& __x)
542   {
543     size_type __n = __position - begin();
544     if (_M_finish != _M_end_of_storage && __position == end()) {
545       _Construct(_M_finish, __x);
546       ++_M_finish;
547     }
548     else
549       _M_insert_aux(iterator(__position), __x);
550     return begin() + __n;
551   }
552 
553   /**
554    *  @brief  Inserts an empty element into the vector.
555    *  @param  position  An iterator that points to the element where empty
556    *                    element should be inserted.
557    *  @param  x  Data to be inserted.
558    *  @return  An iterator that points to the inserted element.
559    *
560    *  This function will insert an empty element into the specified location.
561    *  Note that this kind of operation could be expensive for a vector and if
562    *  it is frequently used the user should consider using std::list.
563   */
564   iterator
565   insert(iterator __position)
566   {
567     size_type __n = __position - begin();
568     if (_M_finish != _M_end_of_storage && __position == end()) {
569       _Construct(_M_finish);
570       ++_M_finish;
571     }
572     else
573       _M_insert_aux(iterator(__position));
574     return begin() + __n;
575   }
576 
577   // Check whether it's an integral type.  If so, it's not an iterator.
578   template<class _InputIterator>
579     void
580 	insert(iterator __pos, _InputIterator __first, _InputIterator __last)
581 	{
582       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
583       _M_insert_dispatch(__pos, __first, __last, _Integral());
584     }
585 
586   template <class _Integer>
587     void
588 	_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type)
589     { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
590 
591   template<class _InputIterator>
592     void
593 	_M_insert_dispatch(iterator __pos,
594                        _InputIterator __first, _InputIterator __last,
595                        __false_type)
596 	{
597 	  typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
598       _M_range_insert(__pos, __first, __last, _IterCategory());
599     }
600 
601   /**
602    *  @brief  Inserts a number of copies of given data into the vector.
603    *  @param  position  An iterator that points to the element where data
604    *                    should be inserted.
605    *  @param  n  Amount of elements to be inserted.
606    *  @param  x  Data to be inserted.
607    *
608    *  This function will insert a specified number of copies of the given data
609    *  into the specified location.
610    *
611    *  Note that this kind of operation could be expensive for a vector and if
612    *  it is frequently used the user should consider using std::list.
613   */
614   void insert (iterator __pos, size_type __n, const _Tp& __x)
615     { _M_fill_insert(__pos, __n, __x); }
616 
617   void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
618 
619   /**
620    *  @brief  Removes last element from vector.
621    *
622    *  This is a typical stack operation. It allows us to shrink the vector by
623    *  one.
624    *
625    *  Note that no data is returned and if last element's data is needed it
626    *  should be retrieved before pop_back() is called.
627   */
628   void pop_back() {
629     --_M_finish;
630     _Destroy(_M_finish);
631   }
632 
633   /**
634    *  @brief  Remove element at given position
635    *  @param  position  Iterator pointing to element to be erased.
636    *  @return  Doc Me! (Iterator pointing to new element at old location?)
637    *
638    *  This function will erase the element at the given position and thus
639    *  shorten the vector by one.
640    *
641    *  Note This operation could be expensive and if it is frequently used the
642    *  user should consider using std::list.  The user is also cautioned that
643    *  this function only erases the element, and that if the element is itself
644    *  a pointer, the pointed-to memory is not touched in any way.  Managing
645    *  the pointer is the user's responsibilty.
646   */
647   iterator erase(iterator __position) {
648     if (__position + 1 != end())
649       copy(__position + 1, end(), __position);
650     --_M_finish;
651     _Destroy(_M_finish);
652     return __position;
653   }
654 
655   /**
656    *  @brief  Remove a range of elements from a vector.
657    *  @param  first  Iterator pointing to the first element to be erased.
658    *  @param  last  Iterator pointing to the last element to be erased.
659    *  @return  Doc Me! (Iterator pointing to new element at old location?)
660    *
661    *  This function will erase the elements in the given range and shorten the
662    *  vector accordingly.
663    *
664    *  Note This operation could be expensive and if it is frequently used the
665    *  user should consider using std::list.  The user is also cautioned that
666    *  this function only erases the elements, and that if the elements
667    *  themselves are pointers, the pointed-to memory is not touched in any
668    *  way.  Managing the pointer is the user's responsibilty.
669   */
670   iterator erase(iterator __first, iterator __last) {
671     iterator __i(copy(__last, end(), __first));
672     _Destroy(__i, end());
673     _M_finish = _M_finish - (__last - __first);
674     return __first;
675   }
676 
677   /**
678    *  @brief  Resizes the vector to the specified number of elements.
679    *  @param  new_size  Number of elements the vector should contain.
680    *  @param  x  Data with which new elements should be populated.
681    *
682    *  This function will resize the vector to the specified number of
683    *  elements.  If the number is smaller than the vector's current size the
684    *  vector is truncated, otherwise the vector is extended and new elements
685    *  are populated with given data.
686   */
687   void resize(size_type __new_size, const _Tp& __x) {
688     if (__new_size < size())
689       erase(begin() + __new_size, end());
690     else
691       insert(end(), __new_size - size(), __x);
692   }
693 
694   /**
695    *  @brief  Resizes the vector to the specified number of elements.
696    *  @param  new_size  Number of elements the vector should contain.
697    *
698    *  This function will resize the vector to the specified number of
699    *  elements.  If the number is smaller than the vector's current size the
700    *  vector is truncated, otherwise the vector is extended and new elements
701    *  are left uninitialized.
702   */
703   void resize(size_type __new_size) { resize(__new_size, _Tp()); }
704 
705   /**
706    *  Erases all elements in vector.  Note that this function only erases the
707    *  elements, and that if the elements themselves are pointers, the
708    *  pointed-to memory is not touched in any way.  Managing the pointer is
709    *  the user's responsibilty.
710   */
711   void clear() { erase(begin(), end()); }
712 
713 protected:
714 
715   template <class _ForwardIterator>
716   pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
717                                                _ForwardIterator __last)
718   {
719     pointer __result = _M_allocate(__n);
720     try {
721       uninitialized_copy(__first, __last, __result);
722       return __result;
723     }
724     catch(...)
725       {
726 	_M_deallocate(__result, __n);
727 	__throw_exception_again;
728       }
729   }
730 
731   template <class _InputIterator>
732   void _M_range_initialize(_InputIterator __first,
733                            _InputIterator __last, input_iterator_tag)
734   {
735     for ( ; __first != __last; ++__first)
736       push_back(*__first);
737   }
738 
739   // This function is only called by the constructor.
740   template <class _ForwardIterator>
741   void _M_range_initialize(_ForwardIterator __first,
742                            _ForwardIterator __last, forward_iterator_tag)
743   {
744     size_type __n = distance(__first, __last);
745     _M_start = _M_allocate(__n);
746     _M_end_of_storage = _M_start + __n;
747     _M_finish = uninitialized_copy(__first, __last, _M_start);
748   }
749 
750   template <class _InputIterator>
751   void _M_range_insert(iterator __pos,
752                        _InputIterator __first, _InputIterator __last,
753                        input_iterator_tag);
754 
755   template <class _ForwardIterator>
756   void _M_range_insert(iterator __pos,
757                        _ForwardIterator __first, _ForwardIterator __last,
758                        forward_iterator_tag);
759 };
760 
761 template <class _Tp, class _Alloc>
762 inline bool
763 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
764 {
765   return __x.size() == __y.size() &&
766          equal(__x.begin(), __x.end(), __y.begin());
767 }
768 
769 template <class _Tp, class _Alloc>
770 inline bool
771 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
772 {
773   return lexicographical_compare(__x.begin(), __x.end(),
774                                  __y.begin(), __y.end());
775 }
776 
777 template <class _Tp, class _Alloc>
778 inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
779 {
780   __x.swap(__y);
781 }
782 
783 template <class _Tp, class _Alloc>
784 inline bool
785 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
786   return !(__x == __y);
787 }
788 
789 template <class _Tp, class _Alloc>
790 inline bool
791 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
792   return __y < __x;
793 }
794 
795 template <class _Tp, class _Alloc>
796 inline bool
797 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
798   return !(__y < __x);
799 }
800 
801 template <class _Tp, class _Alloc>
802 inline bool
803 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
804   return !(__x < __y);
805 }
806 
807 template <class _Tp, class _Alloc>
808 vector<_Tp,_Alloc>&
809 vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
810 {
811   if (&__x != this) {
812     const size_type __xlen = __x.size();
813     if (__xlen > capacity()) {
814       pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
815       _Destroy(_M_start, _M_finish);
816       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
817       _M_start = __tmp;
818       _M_end_of_storage = _M_start + __xlen;
819     }
820     else if (size() >= __xlen) {
821       iterator __i(copy(__x.begin(), __x.end(), begin()));
822       _Destroy(__i, end());
823     }
824     else {
825       copy(__x.begin(), __x.begin() + size(), _M_start);
826       uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
827     }
828     _M_finish = _M_start + __xlen;
829   }
830   return *this;
831 }
832 
833 template <class _Tp, class _Alloc>
834 void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val)
835 {
836   if (__n > capacity()) {
837     vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
838     __tmp.swap(*this);
839   }
840   else if (__n > size()) {
841     fill(begin(), end(), __val);
842     _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
843   }
844   else
845     erase(fill_n(begin(), __n, __val), end());
846 }
847 
848 template <class _Tp, class _Alloc> template <class _InputIter>
849 void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
850                                         input_iterator_tag) {
851   iterator __cur(begin());
852   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
853     *__cur = *__first;
854   if (__first == __last)
855     erase(__cur, end());
856   else
857     insert(end(), __first, __last);
858 }
859 
860 template <class _Tp, class _Alloc> template <class _ForwardIter>
861 void
862 vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
863                                    forward_iterator_tag) {
864   size_type __len = distance(__first, __last);
865 
866   if (__len > capacity()) {
867     pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
868     _Destroy(_M_start, _M_finish);
869     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
870     _M_start = __tmp;
871     _M_end_of_storage = _M_finish = _M_start + __len;
872   }
873   else if (size() >= __len) {
874     iterator __new_finish(copy(__first, __last, _M_start));
875     _Destroy(__new_finish, end());
876     _M_finish = __new_finish.base();
877   }
878   else {
879     _ForwardIter __mid = __first;
880     advance(__mid, size());
881     copy(__first, __mid, _M_start);
882     _M_finish = uninitialized_copy(__mid, __last, _M_finish);
883   }
884 }
885 
886 template <class _Tp, class _Alloc>
887 void
888 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
889 {
890   if (_M_finish != _M_end_of_storage) {
891     _Construct(_M_finish, *(_M_finish - 1));
892     ++_M_finish;
893     _Tp __x_copy = __x;
894     copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
895     *__position = __x_copy;
896   }
897   else {
898     const size_type __old_size = size();
899     const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
900     iterator __new_start(_M_allocate(__len));
901     iterator __new_finish(__new_start);
902     try {
903       __new_finish = uninitialized_copy(iterator(_M_start), __position,
904                                         __new_start);
905       _Construct(__new_finish.base(), __x);
906       ++__new_finish;
907       __new_finish = uninitialized_copy(__position, iterator(_M_finish),
908                                         __new_finish);
909     }
910     catch(...)
911       {
912 	_Destroy(__new_start,__new_finish);
913 	_M_deallocate(__new_start.base(),__len);
914 	__throw_exception_again;
915       }
916     _Destroy(begin(), end());
917     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
918     _M_start = __new_start.base();
919     _M_finish = __new_finish.base();
920     _M_end_of_storage = __new_start.base() + __len;
921   }
922 }
923 
924 template <class _Tp, class _Alloc>
925 void
926 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
927 {
928   if (_M_finish != _M_end_of_storage) {
929     _Construct(_M_finish, *(_M_finish - 1));
930     ++_M_finish;
931     copy_backward(__position, iterator(_M_finish - 2),
932 		  iterator(_M_finish - 1));
933     *__position = _Tp();
934   }
935   else {
936     const size_type __old_size = size();
937     const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
938     pointer __new_start = _M_allocate(__len);
939     pointer __new_finish = __new_start;
940     try {
941       __new_finish = uninitialized_copy(iterator(_M_start), __position,
942 					__new_start);
943       _Construct(__new_finish);
944       ++__new_finish;
945       __new_finish = uninitialized_copy(__position, iterator(_M_finish),
946 					__new_finish);
947     }
948     catch(...)
949       {
950 	_Destroy(__new_start,__new_finish);
951 	_M_deallocate(__new_start,__len);
952 	__throw_exception_again;
953       }
954     _Destroy(begin(), end());
955     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
956     _M_start = __new_start;
957     _M_finish = __new_finish;
958     _M_end_of_storage = __new_start + __len;
959   }
960 }
961 
962 template <class _Tp, class _Alloc>
963 void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
964                                          const _Tp& __x)
965 {
966   if (__n != 0) {
967     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
968       _Tp __x_copy = __x;
969       const size_type __elems_after = end() - __position;
970       iterator __old_finish(_M_finish);
971       if (__elems_after > __n) {
972         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
973         _M_finish += __n;
974         copy_backward(__position, __old_finish - __n, __old_finish);
975         fill(__position, __position + __n, __x_copy);
976       }
977       else {
978         uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
979         _M_finish += __n - __elems_after;
980         uninitialized_copy(__position, __old_finish, _M_finish);
981         _M_finish += __elems_after;
982         fill(__position, __old_finish, __x_copy);
983       }
984     }
985     else {
986       const size_type __old_size = size();
987       const size_type __len = __old_size + max(__old_size, __n);
988       iterator __new_start(_M_allocate(__len));
989       iterator __new_finish(__new_start);
990       try {
991         __new_finish = uninitialized_copy(begin(), __position, __new_start);
992         __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
993         __new_finish
994           = uninitialized_copy(__position, end(), __new_finish);
995       }
996       catch(...)
997 	{
998 	  _Destroy(__new_start,__new_finish);
999 	  _M_deallocate(__new_start.base(),__len);
1000 	  __throw_exception_again;
1001 	}
1002       _Destroy(_M_start, _M_finish);
1003       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1004       _M_start = __new_start.base();
1005       _M_finish = __new_finish.base();
1006       _M_end_of_storage = __new_start.base() + __len;
1007     }
1008   }
1009 }
1010 
1011 template <class _Tp, class _Alloc> template <class _InputIterator>
1012 void
1013 vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
1014                                      _InputIterator __first,
1015                                      _InputIterator __last,
1016                                      input_iterator_tag)
1017 {
1018   for ( ; __first != __last; ++__first) {
1019     __pos = insert(__pos, *__first);
1020     ++__pos;
1021   }
1022 }
1023 
1024 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1025 void
1026 vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
1027                                      _ForwardIterator __first,
1028                                      _ForwardIterator __last,
1029                                      forward_iterator_tag)
1030 {
1031   if (__first != __last) {
1032     size_type __n = distance(__first, __last);
1033     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
1034       const size_type __elems_after = end() - __position;
1035       iterator __old_finish(_M_finish);
1036       if (__elems_after > __n) {
1037         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
1038         _M_finish += __n;
1039         copy_backward(__position, __old_finish - __n, __old_finish);
1040         copy(__first, __last, __position);
1041       }
1042       else {
1043         _ForwardIterator __mid = __first;
1044         advance(__mid, __elems_after);
1045         uninitialized_copy(__mid, __last, _M_finish);
1046         _M_finish += __n - __elems_after;
1047         uninitialized_copy(__position, __old_finish, _M_finish);
1048         _M_finish += __elems_after;
1049         copy(__first, __mid, __position);
1050       }
1051     }
1052     else {
1053       const size_type __old_size = size();
1054       const size_type __len = __old_size + max(__old_size, __n);
1055       iterator __new_start(_M_allocate(__len));
1056       iterator __new_finish(__new_start);
1057       try {
1058         __new_finish = uninitialized_copy(iterator(_M_start),
1059 					  __position, __new_start);
1060         __new_finish = uninitialized_copy(__first, __last, __new_finish);
1061         __new_finish
1062           = uninitialized_copy(__position, iterator(_M_finish), __new_finish);
1063       }
1064       catch(...)
1065 	{
1066 	  _Destroy(__new_start,__new_finish);
1067 	  _M_deallocate(__new_start.base(), __len);
1068 	  __throw_exception_again;
1069 	}
1070       _Destroy(_M_start, _M_finish);
1071       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1072       _M_start = __new_start.base();
1073       _M_finish = __new_finish.base();
1074       _M_end_of_storage = __new_start.base() + __len;
1075     }
1076   }
1077 }
1078 
1079 } // namespace std
1080 
1081 #endif /* __GLIBCPP_INTERNAL_VECTOR_H */
1082 
1083 // Local Variables:
1084 // mode:C++
1085 // End:
1086