xref: /haiku/headers/cpp/stl_vector.h (revision 4bd0c1066b227cec4b79883bdef697c7a27f2e90)
1 /*
2  *
3  * Copyright (c) 1994
4  * Hewlett-Packard Company
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Hewlett-Packard Company makes no
11  * representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  *
15  * Copyright (c) 1996
16  * Silicon Graphics Computer Systems, Inc.
17  *
18  * Permission to use, copy, modify, distribute and sell this software
19  * and its documentation for any purpose is hereby granted without fee,
20  * provided that the above copyright notice appear in all copies and
21  * that both that copyright notice and this permission notice appear
22  * in supporting documentation.  Silicon Graphics makes no
23  * representations about the suitability of this software for any
24  * purpose.  It is provided "as is" without express or implied warranty.
25  */
26 
27 /* NOTE: This is an internal header file, included by other STL headers.
28  *   You should not attempt to use it directly.
29  */
30 
31 #ifndef __SGI_STL_INTERNAL_VECTOR_H
32 #define __SGI_STL_INTERNAL_VECTOR_H
33 
34 #include <stdexcept>
35 
36 __STL_BEGIN_NAMESPACE
37 
38 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
39 #pragma set woff 1174
40 #pragma set woff 1375
41 #endif
42 
43 // The vector base class serves two purposes.  First, its constructor
44 // and destructor allocate (but don't initialize) storage.  This makes
45 // exception safety easier.  Second, the base class encapsulates all of
46 // the differences between SGI-style allocators and standard-conforming
47 // allocators.
48 
49 #ifdef __STL_USE_STD_ALLOCATORS
50 
51 // Base class for ordinary allocators.
52 template <class _Tp, class _Allocator, bool _IsStatic>
53 class _Vector_alloc_base {
54 public:
55   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
56           allocator_type;
57   allocator_type get_allocator() const { return _M_data_allocator; }
58 
59   _Vector_alloc_base(const allocator_type& __a)
60     : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
61   {}
62 
63 protected:
64   allocator_type _M_data_allocator;
65   _Tp* _M_start;
66   _Tp* _M_finish;
67   _Tp* _M_end_of_storage;
68 
69   _Tp* _M_allocate(size_t __n)
70     { return _M_data_allocator.allocate(__n); }
71   void _M_deallocate(_Tp* __p, size_t __n)
72     { if (__p) _M_data_allocator.deallocate(__p, __n); }
73 };
74 
75 // Specialization for allocators that have the property that we don't
76 // actually have to store an allocator object.
77 template <class _Tp, class _Allocator>
78 class _Vector_alloc_base<_Tp, _Allocator, true> {
79 public:
80   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
81           allocator_type;
82   allocator_type get_allocator() const { return allocator_type(); }
83 
84   _Vector_alloc_base(const allocator_type&)
85     : _M_start(0), _M_finish(0), _M_end_of_storage(0)
86   {}
87 
88 protected:
89   _Tp* _M_start;
90   _Tp* _M_finish;
91   _Tp* _M_end_of_storage;
92 
93   typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
94   _Tp* _M_allocate(size_t __n)
95     { return _Alloc_type::allocate(__n); }
96   void _M_deallocate(_Tp* __p, size_t __n)
97     { _Alloc_type::deallocate(__p, __n);}
98 };
99 
100 template <class _Tp, class _Alloc>
101 struct _Vector_base
102   : public _Vector_alloc_base<_Tp, _Alloc,
103                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
104 {
105   typedef _Vector_alloc_base<_Tp, _Alloc,
106                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
107           _Base;
108   typedef typename _Base::allocator_type allocator_type;
109 
110   _Vector_base(const allocator_type& __a) : _Base(__a) {}
111   _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
112     _M_start = _M_allocate(__n);
113     _M_finish = _M_start;
114     _M_end_of_storage = _M_start + __n;
115   }
116 
117   ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
118 };
119 
120 #else /* __STL_USE_STD_ALLOCATORS */
121 
122 template <class _Tp, class _Alloc>
123 class _Vector_base {
124 public:
125   typedef _Alloc allocator_type;
126   allocator_type get_allocator() const { return allocator_type(); }
127 
128   _Vector_base(const _Alloc&)
129     : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
130   _Vector_base(size_t __n, const _Alloc&)
131     : _M_start(0), _M_finish(0), _M_end_of_storage(0)
132   {
133     _M_start = _M_allocate(__n);
134     _M_finish = _M_start;
135     _M_end_of_storage = _M_start + __n;
136   }
137 
138   ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
139 
140 protected:
141   _Tp* _M_start;
142   _Tp* _M_finish;
143   _Tp* _M_end_of_storage;
144 
145   typedef simple_alloc<_Tp, _Alloc> _M_data_allocator;
146   _Tp* _M_allocate(size_t __n)
147     { return _M_data_allocator::allocate(__n); }
148   void _M_deallocate(_Tp* __p, size_t __n)
149     { _M_data_allocator::deallocate(__p, __n); }
150 };
151 
152 #endif /* __STL_USE_STD_ALLOCATORS */
153 
154 template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
155 class vector : protected _Vector_base<_Tp, _Alloc>
156 {
157 private:
158   typedef _Vector_base<_Tp, _Alloc> _Base;
159 public:
160   typedef _Tp value_type;
161   typedef value_type* pointer;
162   typedef const value_type* const_pointer;
163   typedef value_type* iterator;
164   typedef const value_type* const_iterator;
165   typedef value_type& reference;
166   typedef const value_type& const_reference;
167   typedef size_t size_type;
168   typedef ptrdiff_t difference_type;
169 
170   typedef typename _Base::allocator_type allocator_type;
171   allocator_type get_allocator() const { return _Base::get_allocator(); }
172 
173 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
174   typedef reverse_iterator<const_iterator> const_reverse_iterator;
175   typedef reverse_iterator<iterator> reverse_iterator;
176 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
177   typedef reverse_iterator<const_iterator, value_type, const_reference,
178                            difference_type>  const_reverse_iterator;
179   typedef reverse_iterator<iterator, value_type, reference, difference_type>
180           reverse_iterator;
181 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
182 
183 protected:
184 #ifdef __STL_HAS_NAMESPACES
185   using _Base::_M_allocate;
186   using _Base::_M_deallocate;
187   using _Base::_M_start;
188   using _Base::_M_finish;
189   using _Base::_M_end_of_storage;
190 #endif /* __STL_HAS_NAMESPACES */
191 
192 protected:
193   void _M_insert_aux(iterator __position, const _Tp& __x);
194   void _M_insert_aux(iterator __position);
195 
196 public:
197   iterator begin() { return _M_start; }
198   const_iterator begin() const { return _M_start; }
199   iterator end() { return _M_finish; }
200   const_iterator end() const { return _M_finish; }
201 
202   reverse_iterator rbegin()
203     { return reverse_iterator(end()); }
204   const_reverse_iterator rbegin() const
205     { return const_reverse_iterator(end()); }
206   reverse_iterator rend()
207     { return reverse_iterator(begin()); }
208   const_reverse_iterator rend() const
209     { return const_reverse_iterator(begin()); }
210 
211   size_type size() const
212     { return size_type(end() - begin()); }
213   size_type max_size() const
214     { return size_type(-1) / sizeof(_Tp); }
215   size_type capacity() const
216     { return size_type(_M_end_of_storage - begin()); }
217   bool empty() const
218     { return begin() == end(); }
219 
220   reference operator[](size_type __n) { return *(begin() + __n); }
221   const_reference operator[](size_type __n) const { return *(begin() + __n); }
222 
223   reference at(size_type __n) {
224 	  if (__n >= size())
225 		  throw std::out_of_range("vector::at() out_of_range");
226 	  return *(begin() + __n);
227   }
228 
229   const_reference at(size_type __n) const {
230 	  if (__n >= size())
231 		  throw std::out_of_range("vector::at() out_of_range");
232 	  return *(begin() + __n);
233   }
234 
235   explicit vector(const allocator_type& __a = allocator_type())
236     : _Base(__a) {}
237 
238   vector(size_type __n, const _Tp& __value,
239          const allocator_type& __a = allocator_type())
240     : _Base(__n, __a)
241     { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
242 
243   explicit vector(size_type __n)
244     : _Base(__n, allocator_type())
245     { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
246 
247   vector(const vector<_Tp, _Alloc>& __x)
248     : _Base(__x.size(), __x.get_allocator())
249     { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
250 
251 #ifdef __STL_MEMBER_TEMPLATES
252   // Check whether it's an integral type.  If so, it's not an iterator.
253   template <class _InputIterator>
254   vector(_InputIterator __first, _InputIterator __last,
255          const allocator_type& __a = allocator_type()) : _Base(__a) {
256     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
257     _M_initialize_aux(__first, __last, _Integral());
258   }
259 
260   template <class _Integer>
261   void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
262     _M_start = _M_allocate(__n);
263     _M_end_of_storage = _M_start + __n;
264     _M_finish = uninitialized_fill_n(_M_start, __n, __value);
265   }
266 
267   template <class _InputIterator>
268   void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
269                          __false_type) {
270     _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
271   }
272 
273 #else
274   vector(const _Tp* __first, const _Tp* __last,
275          const allocator_type& __a = allocator_type())
276     : _Base(__last - __first, __a)
277     { _M_finish = uninitialized_copy(__first, __last, _M_start); }
278 #endif /* __STL_MEMBER_TEMPLATES */
279 
280   ~vector() { destroy(_M_start, _M_finish); }
281 
282   vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
283   void reserve(size_type __n) {
284     if (capacity() < __n) {
285       const size_type __old_size = size();
286       iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
287       destroy(_M_start, _M_finish);
288       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
289       _M_start = __tmp;
290       _M_finish = __tmp + __old_size;
291       _M_end_of_storage = _M_start + __n;
292     }
293   }
294 
295   // assign(), a generalized assignment member function.  Two
296   // versions: one that takes a count, and one that takes a range.
297   // The range version is a member template, so we dispatch on whether
298   // or not the type is an integer.
299 
300   void assign(size_type __n, const _Tp& __val);
301 
302 #ifdef __STL_MEMBER_TEMPLATES
303 
304   template <class _InputIterator>
305   void assign(_InputIterator __first, _InputIterator __last) {
306     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
307     _M_assign_dispatch(__first, __last, _Integral());
308   }
309 
310   template <class _Integer>
311   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
312     { assign((size_type) __n, (_Tp) __val); }
313 
314   template <class _InputIter>
315   void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
316     { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); }
317 
318   template <class _InputIterator>
319   void _M_assign_aux(_InputIterator __first, _InputIterator __last,
320                      input_iterator_tag);
321 
322   template <class _ForwardIterator>
323   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
324                      forward_iterator_tag);
325 
326 #endif /* __STL_MEMBER_TEMPLATES */
327 
328   reference front() { return *begin(); }
329   const_reference front() const { return *begin(); }
330   reference back() { return *(end() - 1); }
331   const_reference back() const { return *(end() - 1); }
332 
333   void push_back(const _Tp& __x) {
334     if (_M_finish != _M_end_of_storage) {
335       construct(_M_finish, __x);
336       ++_M_finish;
337     }
338     else
339       _M_insert_aux(end(), __x);
340   }
341   void push_back() {
342     if (_M_finish != _M_end_of_storage) {
343       construct(_M_finish);
344       ++_M_finish;
345     }
346     else
347       _M_insert_aux(end());
348   }
349   void swap(vector<_Tp, _Alloc>& __x) {
350     __STD::swap(_M_start, __x._M_start);
351     __STD::swap(_M_finish, __x._M_finish);
352     __STD::swap(_M_end_of_storage, __x._M_end_of_storage);
353   }
354 
355   iterator insert(iterator __position, const _Tp& __x) {
356     size_type __n = __position - begin();
357     if (_M_finish != _M_end_of_storage && __position == end()) {
358       construct(_M_finish, __x);
359       ++_M_finish;
360     }
361     else
362       _M_insert_aux(__position, __x);
363     return begin() + __n;
364   }
365   iterator insert(iterator __position) {
366     size_type __n = __position - begin();
367     if (_M_finish != _M_end_of_storage && __position == end()) {
368       construct(_M_finish);
369       ++_M_finish;
370     }
371     else
372       _M_insert_aux(__position);
373     return begin() + __n;
374   }
375 #ifdef __STL_MEMBER_TEMPLATES
376   // Check whether it's an integral type.  If so, it's not an iterator.
377   template <class _InputIterator>
378   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
379     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
380     _M_insert_dispatch(__pos, __first, __last, _Integral());
381   }
382 
383   template <class _Integer>
384   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
385                           __true_type) {
386     insert(__pos, (size_type) __n, (_Tp) __val);
387   }
388 
389   template <class _InputIterator>
390   void _M_insert_dispatch(iterator __pos,
391                           _InputIterator __first, _InputIterator __last,
392                           __false_type) {
393     _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
394   }
395 #else /* __STL_MEMBER_TEMPLATES */
396   void insert(iterator __position,
397               const_iterator __first, const_iterator __last);
398 #endif /* __STL_MEMBER_TEMPLATES */
399 
400   void insert (iterator __pos, size_type __n, const _Tp& __x);
401 
402   void pop_back() {
403     --_M_finish;
404     destroy(_M_finish);
405   }
406   iterator erase(iterator __position) {
407     if (__position + 1 != end())
408       copy(__position + 1, _M_finish, __position);
409     --_M_finish;
410     destroy(_M_finish);
411     return __position;
412   }
413   iterator erase(iterator __first, iterator __last) {
414     iterator __i = copy(__last, _M_finish, __first);
415     destroy(__i, _M_finish);
416     _M_finish = _M_finish - (__last - __first);
417     return __first;
418   }
419 
420   void resize(size_type __new_size, const _Tp& __x) {
421     if (__new_size < size())
422       erase(begin() + __new_size, end());
423     else
424       insert(end(), __new_size - size(), __x);
425   }
426   void resize(size_type __new_size) { resize(__new_size, _Tp()); }
427   void clear() { erase(begin(), end()); }
428 
429 protected:
430 
431 #ifdef __STL_MEMBER_TEMPLATES
432   template <class _ForwardIterator>
433   iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
434                                                _ForwardIterator __last)
435 {
436     iterator __result = _M_allocate(__n);
437     __STL_TRY {
438       uninitialized_copy(__first, __last, __result);
439       return __result;
440     }
441     __STL_UNWIND(_M_deallocate(__result, __n));
442   }
443 #else /* __STL_MEMBER_TEMPLATES */
444   iterator _M_allocate_and_copy(size_type __n, const_iterator __first,
445                                                const_iterator __last)
446   {
447     iterator __result = _M_allocate(__n);
448     __STL_TRY {
449       uninitialized_copy(__first, __last, __result);
450       return __result;
451     }
452     __STL_UNWIND(_M_deallocate(__result, __n));
453   }
454 #endif /* __STL_MEMBER_TEMPLATES */
455 
456 
457 #ifdef __STL_MEMBER_TEMPLATES
458   template <class _InputIterator>
459   void _M_range_initialize(_InputIterator __first,
460                            _InputIterator __last, input_iterator_tag)
461   {
462     for ( ; __first != __last; ++__first)
463       push_back(*__first);
464   }
465 
466   // This function is only called by the constructor.
467   template <class _ForwardIterator>
468   void _M_range_initialize(_ForwardIterator __first,
469                            _ForwardIterator __last, forward_iterator_tag)
470   {
471     size_type __n = 0;
472     distance(__first, __last, __n);
473     _M_start = _M_allocate(__n);
474     _M_end_of_storage = _M_start + __n;
475     _M_finish = uninitialized_copy(__first, __last, _M_start);
476   }
477 
478   template <class _InputIterator>
479   void _M_range_insert(iterator __pos,
480                        _InputIterator __first, _InputIterator __last,
481                        input_iterator_tag);
482 
483   template <class _ForwardIterator>
484   void _M_range_insert(iterator __pos,
485                        _ForwardIterator __first, _ForwardIterator __last,
486                        forward_iterator_tag);
487 
488 #endif /* __STL_MEMBER_TEMPLATES */
489 };
490 
491 template <class _Tp, class _Alloc>
492 inline bool
493 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
494 {
495   return __x.size() == __y.size() &&
496          equal(__x.begin(), __x.end(), __y.begin());
497 }
498 
499 template <class _Tp, class _Alloc>
500 inline bool
501 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
502 {
503   return lexicographical_compare(__x.begin(), __x.end(),
504                                  __y.begin(), __y.end());
505 }
506 
507 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
508 
509 template <class _Tp, class _Alloc>
510 inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
511 {
512   __x.swap(__y);
513 }
514 
515 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
516 
517 template <class _Tp, class _Alloc>
518 vector<_Tp,_Alloc>&
519 vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
520 {
521   if (&__x != this) {
522     const size_type __xlen = __x.size();
523     if (__xlen > capacity()) {
524       iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
525       destroy(_M_start, _M_finish);
526       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
527       _M_start = __tmp;
528       _M_end_of_storage = _M_start + __xlen;
529     }
530     else if (size() >= __xlen) {
531       iterator __i = copy(__x.begin(), __x.end(), begin());
532       destroy(__i, _M_finish);
533     }
534     else {
535       copy(__x.begin(), __x.begin() + size(), _M_start);
536       uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
537     }
538     _M_finish = _M_start + __xlen;
539   }
540   return *this;
541 }
542 
543 template <class _Tp, class _Alloc>
544 void vector<_Tp, _Alloc>::assign(size_t __n, const value_type& __val) {
545   if (__n > capacity()) {
546     vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
547     __tmp.swap(*this);
548   }
549   else if (__n > size()) {
550     fill(begin(), end(), __val);
551     _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
552   }
553   else
554     erase(fill_n(begin(), __n, __val), end());
555 }
556 
557 #ifdef __STL_MEMBER_TEMPLATES
558 
559 template <class _Tp, class _Alloc> template <class _InputIter>
560 void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
561                                         input_iterator_tag) {
562   iterator __cur = begin();
563   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
564     *__cur = *__first;
565   if (__first == __last)
566     erase(__cur, end());
567   else
568     insert(end(), __first, __last);
569 }
570 
571 template <class _Tp, class _Alloc> template <class _ForwardIter>
572 void
573 vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
574                                    forward_iterator_tag) {
575   size_type __len = 0;
576   distance(__first, __last, __len);
577 
578   if (__len > capacity()) {
579     iterator __tmp = _M_allocate_and_copy(__len, __first, __last);
580     destroy(_M_start, _M_finish);
581     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
582     _M_start = __tmp;
583     _M_end_of_storage = _M_finish = _M_start + __len;
584   }
585   else if (size() >= __len) {
586     iterator __new_finish = copy(__first, __last, _M_start);
587     destroy(__new_finish, _M_finish);
588     _M_finish = __new_finish;
589   }
590   else {
591     _ForwardIter __mid = __first;
592     advance(__mid, size());
593     copy(__first, __mid, _M_start);
594     _M_finish = uninitialized_copy(__mid, __last, _M_finish);
595   }
596 }
597 
598 #endif /* __STL_MEMBER_TEMPLATES */
599 
600 template <class _Tp, class _Alloc>
601 void
602 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
603 {
604   if (_M_finish != _M_end_of_storage) {
605     construct(_M_finish, *(_M_finish - 1));
606     ++_M_finish;
607     _Tp __x_copy = __x;
608     copy_backward(__position, _M_finish - 2, _M_finish - 1);
609     *__position = __x_copy;
610   }
611   else {
612     const size_type __old_size = size();
613     const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
614     iterator __new_start = _M_allocate(__len);
615     iterator __new_finish = __new_start;
616     __STL_TRY {
617       __new_finish = uninitialized_copy(_M_start, __position, __new_start);
618       construct(__new_finish, __x);
619       ++__new_finish;
620       __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
621     }
622     __STL_UNWIND((destroy(__new_start,__new_finish),
623                   _M_deallocate(__new_start,__len)));
624     destroy(begin(), end());
625     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
626     _M_start = __new_start;
627     _M_finish = __new_finish;
628     _M_end_of_storage = __new_start + __len;
629   }
630 }
631 
632 template <class _Tp, class _Alloc>
633 void
634 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
635 {
636   if (_M_finish != _M_end_of_storage) {
637     construct(_M_finish, *(_M_finish - 1));
638     ++_M_finish;
639     copy_backward(__position, _M_finish - 2, _M_finish - 1);
640     *__position = _Tp();
641   }
642   else {
643     const size_type __old_size = size();
644     const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
645     iterator __new_start = _M_allocate(__len);
646     iterator __new_finish = __new_start;
647     __STL_TRY {
648       __new_finish = uninitialized_copy(_M_start, __position, __new_start);
649       construct(__new_finish);
650       ++__new_finish;
651       __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
652     }
653     __STL_UNWIND((destroy(__new_start,__new_finish),
654                   _M_deallocate(__new_start,__len)));
655     destroy(begin(), end());
656     _M_deallocate(_M_start, _M_end_of_storage - _M_start);
657     _M_start = __new_start;
658     _M_finish = __new_finish;
659     _M_end_of_storage = __new_start + __len;
660   }
661 }
662 
663 template <class _Tp, class _Alloc>
664 void vector<_Tp, _Alloc>::insert(iterator __position, size_type __n,
665                                  const _Tp& __x)
666 {
667   if (__n != 0) {
668     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
669       _Tp __x_copy = __x;
670       const size_type __elems_after = _M_finish - __position;
671       iterator __old_finish = _M_finish;
672       if (__elems_after > __n) {
673         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
674         _M_finish += __n;
675         copy_backward(__position, __old_finish - __n, __old_finish);
676         fill(__position, __position + __n, __x_copy);
677       }
678       else {
679         uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
680         _M_finish += __n - __elems_after;
681         uninitialized_copy(__position, __old_finish, _M_finish);
682         _M_finish += __elems_after;
683         fill(__position, __old_finish, __x_copy);
684       }
685     }
686     else {
687       const size_type __old_size = size();
688       const size_type __len = __old_size + max(__old_size, __n);
689       iterator __new_start = _M_allocate(__len);
690       iterator __new_finish = __new_start;
691       __STL_TRY {
692         __new_finish = uninitialized_copy(_M_start, __position, __new_start);
693         __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
694         __new_finish
695           = uninitialized_copy(__position, _M_finish, __new_finish);
696       }
697       __STL_UNWIND((destroy(__new_start,__new_finish),
698                     _M_deallocate(__new_start,__len)));
699       destroy(_M_start, _M_finish);
700       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
701       _M_start = __new_start;
702       _M_finish = __new_finish;
703       _M_end_of_storage = __new_start + __len;
704     }
705   }
706 }
707 
708 #ifdef __STL_MEMBER_TEMPLATES
709 
710 template <class _Tp, class _Alloc> template <class _InputIterator>
711 void
712 vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
713                                      _InputIterator __first,
714                                      _InputIterator __last,
715                                      input_iterator_tag)
716 {
717   for ( ; __first != __last; ++__first) {
718     __pos = insert(__pos, *__first);
719     ++__pos;
720   }
721 }
722 
723 template <class _Tp, class _Alloc> template <class _ForwardIterator>
724 void
725 vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
726                                      _ForwardIterator __first,
727                                      _ForwardIterator __last,
728                                      forward_iterator_tag)
729 {
730   if (__first != __last) {
731     size_type __n = 0;
732     distance(__first, __last, __n);
733     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
734       const size_type __elems_after = _M_finish - __position;
735       iterator __old_finish = _M_finish;
736       if (__elems_after > __n) {
737         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
738         _M_finish += __n;
739         copy_backward(__position, __old_finish - __n, __old_finish);
740         copy(__first, __last, __position);
741       }
742       else {
743         _ForwardIterator __mid = __first;
744         advance(__mid, __elems_after);
745         uninitialized_copy(__mid, __last, _M_finish);
746         _M_finish += __n - __elems_after;
747         uninitialized_copy(__position, __old_finish, _M_finish);
748         _M_finish += __elems_after;
749         copy(__first, __mid, __position);
750       }
751     }
752     else {
753       const size_type __old_size = size();
754       const size_type __len = __old_size + max(__old_size, __n);
755       iterator __new_start = _M_allocate(__len);
756       iterator __new_finish = __new_start;
757       __STL_TRY {
758         __new_finish = uninitialized_copy(_M_start, __position, __new_start);
759         __new_finish = uninitialized_copy(__first, __last, __new_finish);
760         __new_finish
761           = uninitialized_copy(__position, _M_finish, __new_finish);
762       }
763       __STL_UNWIND((destroy(__new_start,__new_finish),
764                     _M_deallocate(__new_start,__len)));
765       destroy(_M_start, _M_finish);
766       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
767       _M_start = __new_start;
768       _M_finish = __new_finish;
769       _M_end_of_storage = __new_start + __len;
770     }
771   }
772 }
773 
774 #else /* __STL_MEMBER_TEMPLATES */
775 
776 template <class _Tp, class _Alloc>
777 void
778 vector<_Tp, _Alloc>::insert(iterator __position,
779                             const_iterator __first,
780                             const_iterator __last)
781 {
782   if (__first != __last) {
783     size_type __n = 0;
784     distance(__first, __last, __n);
785     if (size_type(_M_end_of_storage - _M_finish) >= __n) {
786       const size_type __elems_after = _M_finish - __position;
787       iterator __old_finish = _M_finish;
788       if (__elems_after > __n) {
789         uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
790         _M_finish += __n;
791         copy_backward(__position, __old_finish - __n, __old_finish);
792         copy(__first, __last, __position);
793       }
794       else {
795         uninitialized_copy(__first + __elems_after, __last, _M_finish);
796         _M_finish += __n - __elems_after;
797         uninitialized_copy(__position, __old_finish, _M_finish);
798         _M_finish += __elems_after;
799         copy(__first, __first + __elems_after, __position);
800       }
801     }
802     else {
803       const size_type __old_size = size();
804       const size_type __len = __old_size + max(__old_size, __n);
805       iterator __new_start = _M_allocate(__len);
806       iterator __new_finish = __new_start;
807       __STL_TRY {
808         __new_finish = uninitialized_copy(_M_start, __position, __new_start);
809         __new_finish = uninitialized_copy(__first, __last, __new_finish);
810         __new_finish
811           = uninitialized_copy(__position, _M_finish, __new_finish);
812       }
813       __STL_UNWIND((destroy(__new_start,__new_finish),
814                     _M_deallocate(__new_start,__len)));
815       destroy(_M_start, _M_finish);
816       _M_deallocate(_M_start, _M_end_of_storage - _M_start);
817       _M_start = __new_start;
818       _M_finish = __new_finish;
819       _M_end_of_storage = __new_start + __len;
820     }
821   }
822 }
823 
824 #endif /* __STL_MEMBER_TEMPLATES */
825 
826 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
827 #pragma reset woff 1174
828 #pragma reset woff 1375
829 #endif
830 
831 __STL_END_NAMESPACE
832 
833 #endif /* __SGI_STL_INTERNAL_VECTOR_H */
834 
835 // Local Variables:
836 // mode:C++
837 // End:
838