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