OSDN Git Service

2000-10-05 Benjamin Kosnik <bkoz@cygnus.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / stl_deque.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) 1997
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 #include <bits/concept_checks.h>
32
33 #ifndef __SGI_STL_INTERNAL_DEQUE_H
34 #define __SGI_STL_INTERNAL_DEQUE_H
35
36 /* Class invariants:
37  *  For any nonsingular iterator i:
38  *    i.node is the address of an element in the map array.  The
39  *      contents of i.node is a pointer to the beginning of a node.
40  *    i.first == *(i.node) 
41  *    i.last  == i.first + node_size
42  *    i.cur is a pointer in the range [i.first, i.last).  NOTE:
43  *      the implication of this is that i.cur is always a dereferenceable
44  *      pointer, even if i is a past-the-end iterator.
45  *  Start and Finish are always nonsingular iterators.  NOTE: this means
46  *    that an empty deque must have one node, and that a deque
47  *    with N elements, where N is the buffer size, must have two nodes.
48  *  For every node other than start.node and finish.node, every element
49  *    in the node is an initialized object.  If start.node == finish.node,
50  *    then [start.cur, finish.cur) are initialized objects, and
51  *    the elements outside that range are uninitialized storage.  Otherwise,
52  *    [start.cur, start.last) and [finish.first, finish.cur) are initialized
53  *    objects, and [start.first, start.cur) and [finish.cur, finish.last)
54  *    are uninitialized storage.
55  *  [map, map + map_size) is a valid, non-empty range.  
56  *  [start.node, finish.node] is a valid range contained within 
57  *    [map, map + map_size).  
58  *  A pointer in the range [map, map + map_size) points to an allocated node
59  *    if and only if the pointer is in the range [start.node, finish.node].
60  */
61
62
63 /*
64  * In previous versions of deque, there was an extra template 
65  * parameter so users could control the node size.  This extension
66  * turns out to violate the C++ standard (it can be detected using
67  * template template parameters), and it has been removed.
68  */
69
70 __STL_BEGIN_NAMESPACE 
71
72 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
73 #pragma set woff 1174
74 #pragma set woff 1375
75 #endif
76
77 // Note: this function is simply a kludge to work around several compilers'
78 //  bugs in handling constant expressions.
79 inline size_t __deque_buf_size(size_t __size) {
80   return __size < 512 ? size_t(512 / __size) : size_t(1);
81 }
82
83 template <class _Tp, class _Ref, class _Ptr>
84 struct _Deque_iterator {
85   typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
86   typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
87   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
88
89   typedef random_access_iterator_tag iterator_category;
90   typedef _Tp value_type;
91   typedef _Ptr pointer;
92   typedef _Ref reference;
93   typedef size_t size_type;
94   typedef ptrdiff_t difference_type;
95   typedef _Tp** _Map_pointer;
96
97   typedef _Deque_iterator _Self;
98
99   _Tp* _M_cur;
100   _Tp* _M_first;
101   _Tp* _M_last;
102   _Map_pointer _M_node;
103
104   _Deque_iterator(_Tp* __x, _Map_pointer __y) 
105     : _M_cur(__x), _M_first(*__y),
106       _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
107   _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
108   _Deque_iterator(const iterator& __x)
109     : _M_cur(__x._M_cur), _M_first(__x._M_first), 
110       _M_last(__x._M_last), _M_node(__x._M_node) {}
111
112   reference operator*() const { return *_M_cur; }
113 #ifndef __SGI_STL_NO_ARROW_OPERATOR
114   pointer operator->() const { return _M_cur; }
115 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
116
117   difference_type operator-(const _Self& __x) const {
118     return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
119       (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
120   }
121
122   _Self& operator++() {
123     ++_M_cur;
124     if (_M_cur == _M_last) {
125       _M_set_node(_M_node + 1);
126       _M_cur = _M_first;
127     }
128     return *this; 
129   }
130   _Self operator++(int)  {
131     _Self __tmp = *this;
132     ++*this;
133     return __tmp;
134   }
135
136   _Self& operator--() {
137     if (_M_cur == _M_first) {
138       _M_set_node(_M_node - 1);
139       _M_cur = _M_last;
140     }
141     --_M_cur;
142     return *this;
143   }
144   _Self operator--(int) {
145     _Self __tmp = *this;
146     --*this;
147     return __tmp;
148   }
149
150   _Self& operator+=(difference_type __n)
151   {
152     difference_type __offset = __n + (_M_cur - _M_first);
153     if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
154       _M_cur += __n;
155     else {
156       difference_type __node_offset =
157         __offset > 0 ? __offset / difference_type(_S_buffer_size())
158                    : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
159       _M_set_node(_M_node + __node_offset);
160       _M_cur = _M_first + 
161         (__offset - __node_offset * difference_type(_S_buffer_size()));
162     }
163     return *this;
164   }
165
166   _Self operator+(difference_type __n) const
167   {
168     _Self __tmp = *this;
169     return __tmp += __n;
170   }
171
172   _Self& operator-=(difference_type __n) { return *this += -__n; }
173  
174   _Self operator-(difference_type __n) const {
175     _Self __tmp = *this;
176     return __tmp -= __n;
177   }
178
179   reference operator[](difference_type __n) const { return *(*this + __n); }
180
181   bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
182   bool operator!=(const _Self& __x) const { return !(*this == __x); }
183   bool operator<(const _Self& __x) const {
184     return (_M_node == __x._M_node) ? 
185       (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
186   }
187   bool operator>(const _Self& __x) const  { return __x < *this; }
188   bool operator<=(const _Self& __x) const { return !(__x < *this); }
189   bool operator>=(const _Self& __x) const { return !(*this < __x); }
190
191   void _M_set_node(_Map_pointer __new_node) {
192     _M_node = __new_node;
193     _M_first = *__new_node;
194     _M_last = _M_first + difference_type(_S_buffer_size());
195   }
196 };
197
198 template <class _Tp, class _Ref, class _Ptr>
199 inline _Deque_iterator<_Tp, _Ref, _Ptr>
200 operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
201 {
202   return __x + __n;
203 }
204
205 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
206
207 template <class _Tp, class _Ref, class _Ptr>
208 inline random_access_iterator_tag
209 iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&)
210 {
211   return random_access_iterator_tag();
212 }
213
214 template <class _Tp, class _Ref, class _Ptr>
215 inline _Tp* value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; }
216
217 template <class _Tp, class _Ref, class _Ptr>
218 inline ptrdiff_t* distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) {
219   return 0;
220 }
221
222 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
223
224 // Deque base class.  It has two purposes.  First, its constructor
225 //  and destructor allocate (but don't initialize) storage.  This makes
226 //  exception safety easier.  Second, the base class encapsulates all of
227 //  the differences between SGI-style allocators and standard-conforming
228 //  allocators.
229
230 #ifdef __STL_USE_STD_ALLOCATORS
231
232 // Base class for ordinary allocators.
233 template <class _Tp, class _Alloc, bool __is_static>
234 class _Deque_alloc_base {
235 public:
236   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
237   allocator_type get_allocator() const { return _M_node_allocator; }
238
239   _Deque_alloc_base(const allocator_type& __a)
240     : _M_node_allocator(__a), _M_map_allocator(__a),
241       _M_map(0), _M_map_size(0)
242   {}
243   
244 protected:
245   typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
246           _Map_allocator_type;
247
248   allocator_type      _M_node_allocator;
249   _Map_allocator_type _M_map_allocator;
250
251   _Tp* _M_allocate_node() {
252     return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
253   }
254   void _M_deallocate_node(_Tp* __p) {
255     _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
256   }
257   _Tp** _M_allocate_map(size_t __n) 
258     { return _M_map_allocator.allocate(__n); }
259   void _M_deallocate_map(_Tp** __p, size_t __n) 
260     { _M_map_allocator.deallocate(__p, __n); }
261
262   _Tp** _M_map;
263   size_t _M_map_size;
264 };
265
266 // Specialization for instanceless allocators.
267 template <class _Tp, class _Alloc>
268 class _Deque_alloc_base<_Tp, _Alloc, true>
269 {
270 public:
271   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
272   allocator_type get_allocator() const { return allocator_type(); }
273
274   _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
275   
276 protected:
277   typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
278   typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
279
280   _Tp* _M_allocate_node() {
281     return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
282   }
283   void _M_deallocate_node(_Tp* __p) {
284     _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
285   }
286   _Tp** _M_allocate_map(size_t __n) 
287     { return _Map_alloc_type::allocate(__n); }
288   void _M_deallocate_map(_Tp** __p, size_t __n) 
289     { _Map_alloc_type::deallocate(__p, __n); }
290
291   _Tp** _M_map;
292   size_t _M_map_size;
293 };
294
295 template <class _Tp, class _Alloc>
296 class _Deque_base
297   : public _Deque_alloc_base<_Tp,_Alloc,
298                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
299 {
300 public:
301   typedef _Deque_alloc_base<_Tp,_Alloc,
302                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
303           _Base;
304   typedef typename _Base::allocator_type allocator_type;
305   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
306   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
307
308   _Deque_base(const allocator_type& __a, size_t __num_elements)
309     : _Base(__a), _M_start(), _M_finish()
310     { _M_initialize_map(__num_elements); }
311   _Deque_base(const allocator_type& __a) 
312     : _Base(__a), _M_start(), _M_finish() {}
313   ~_Deque_base();    
314
315 protected:
316   void _M_initialize_map(size_t);
317   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
318   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
319   enum { _S_initial_map_size = 8 };
320
321 protected:
322   iterator _M_start;
323   iterator _M_finish;
324 };
325
326 #else /* __STL_USE_STD_ALLOCATORS */
327
328 template <class _Tp, class _Alloc>
329 class _Deque_base {
330 public:
331   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
332   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
333
334   typedef _Alloc allocator_type;
335   allocator_type get_allocator() const { return allocator_type(); }
336
337   _Deque_base(const allocator_type&, size_t __num_elements)
338     : _M_map(0), _M_map_size(0),  _M_start(), _M_finish() {
339     _M_initialize_map(__num_elements);
340   }
341   _Deque_base(const allocator_type&)
342     : _M_map(0), _M_map_size(0),  _M_start(), _M_finish() {}
343   ~_Deque_base();    
344
345 protected:
346   void _M_initialize_map(size_t);
347   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
348   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
349   enum { _S_initial_map_size = 8 };
350
351 protected:
352   _Tp** _M_map;
353   size_t _M_map_size;  
354   iterator _M_start;
355   iterator _M_finish;
356
357   typedef simple_alloc<_Tp, _Alloc>  _Node_alloc_type;
358   typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type;
359
360   _Tp* _M_allocate_node()
361     { return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); }
362   void _M_deallocate_node(_Tp* __p)
363     { _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); }
364   _Tp** _M_allocate_map(size_t __n) 
365     { return _Map_alloc_type::allocate(__n); }
366   void _M_deallocate_map(_Tp** __p, size_t __n) 
367     { _Map_alloc_type::deallocate(__p, __n); }
368 };
369
370 #endif /* __STL_USE_STD_ALLOCATORS */
371
372 // Non-inline member functions from _Deque_base.
373
374 template <class _Tp, class _Alloc>
375 _Deque_base<_Tp,_Alloc>::~_Deque_base() {
376   if (_M_map) {
377     _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
378     _M_deallocate_map(_M_map, _M_map_size);
379   }
380 }
381
382 template <class _Tp, class _Alloc>
383 void
384 _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
385 {
386   size_t __num_nodes = 
387     __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
388
389   _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
390   _M_map = _M_allocate_map(_M_map_size);
391
392   _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
393   _Tp** __nfinish = __nstart + __num_nodes;
394     
395   __STL_TRY {
396     _M_create_nodes(__nstart, __nfinish);
397   }
398   __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), 
399                 _M_map = 0, _M_map_size = 0));
400   _M_start._M_set_node(__nstart);
401   _M_finish._M_set_node(__nfinish - 1);
402   _M_start._M_cur = _M_start._M_first;
403   _M_finish._M_cur = _M_finish._M_first +
404                __num_elements % __deque_buf_size(sizeof(_Tp));
405 }
406
407 template <class _Tp, class _Alloc>
408 void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
409 {
410   _Tp** __cur;
411   __STL_TRY {
412     for (__cur = __nstart; __cur < __nfinish; ++__cur)
413       *__cur = _M_allocate_node();
414   }
415   __STL_UNWIND(_M_destroy_nodes(__nstart, __cur));
416 }
417
418 template <class _Tp, class _Alloc>
419 void
420 _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
421 {
422   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
423     _M_deallocate_node(*__n);
424 }
425
426 template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
427 class deque : protected _Deque_base<_Tp, _Alloc> {
428
429   // requirements:
430
431   __STL_CLASS_REQUIRES(_Tp, _Assignable);
432
433   typedef _Deque_base<_Tp, _Alloc> _Base;
434 public:                         // Basic types
435   typedef _Tp value_type;
436   typedef value_type* pointer;
437   typedef const value_type* const_pointer;
438   typedef value_type& reference;
439   typedef const value_type& const_reference;
440   typedef size_t size_type;
441   typedef ptrdiff_t difference_type;
442
443   typedef typename _Base::allocator_type allocator_type;
444   allocator_type get_allocator() const { return _Base::get_allocator(); }
445
446 public:                         // Iterators
447   typedef typename _Base::iterator       iterator;
448   typedef typename _Base::const_iterator const_iterator;
449
450 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
451   typedef reverse_iterator<const_iterator> const_reverse_iterator;
452   typedef reverse_iterator<iterator> reverse_iterator;
453 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
454   typedef reverse_iterator<const_iterator, value_type, const_reference, 
455                            difference_type>  
456           const_reverse_iterator;
457   typedef reverse_iterator<iterator, value_type, reference, difference_type>
458           reverse_iterator; 
459 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
460
461 protected:                      // Internal typedefs
462   typedef pointer* _Map_pointer;
463   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
464
465 protected:
466 #ifdef __STL_USE_NAMESPACES
467   using _Base::_M_initialize_map;
468   using _Base::_M_create_nodes;
469   using _Base::_M_destroy_nodes;
470   using _Base::_M_allocate_node;
471   using _Base::_M_deallocate_node;
472   using _Base::_M_allocate_map;
473   using _Base::_M_deallocate_map;
474
475   using _Base::_M_map;
476   using _Base::_M_map_size;
477   using _Base::_M_start;
478   using _Base::_M_finish;
479 #endif /* __STL_USE_NAMESPACES */
480
481 public:                         // Basic accessors
482   iterator begin() { return _M_start; }
483   iterator end() { return _M_finish; }
484   const_iterator begin() const { return _M_start; }
485   const_iterator end() const { return _M_finish; }
486
487   reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
488   reverse_iterator rend() { return reverse_iterator(_M_start); }
489   const_reverse_iterator rbegin() const 
490     { return const_reverse_iterator(_M_finish); }
491   const_reverse_iterator rend() const 
492     { return const_reverse_iterator(_M_start); }
493
494   reference operator[](size_type __n)
495     { return _M_start[difference_type(__n)]; }
496   const_reference operator[](size_type __n) const 
497     { return _M_start[difference_type(__n)]; }
498
499 #ifdef __STL_THROW_RANGE_ERRORS
500   void _M_range_check(size_type __n) const {
501     if (__n >= this->size())
502       __stl_throw_range_error("deque");
503   }
504
505   reference at(size_type __n)
506     { _M_range_check(__n); return (*this)[__n]; }
507   const_reference at(size_type __n) const
508     { _M_range_check(__n); return (*this)[__n]; }
509 #endif /* __STL_THROW_RANGE_ERRORS */
510
511   reference front() { return *_M_start; }
512   reference back() {
513     iterator __tmp = _M_finish;
514     --__tmp;
515     return *__tmp;
516   }
517   const_reference front() const { return *_M_start; }
518   const_reference back() const {
519     const_iterator __tmp = _M_finish;
520     --__tmp;
521     return *__tmp;
522   }
523
524   size_type size() const { return _M_finish - _M_start; }
525   size_type max_size() const { return size_type(-1); }
526   bool empty() const { return _M_finish == _M_start; }
527
528 public:                         // Constructor, destructor.
529   explicit deque(const allocator_type& __a = allocator_type()) 
530     : _Base(__a, 0) {}
531   deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) 
532     { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
533   deque(size_type __n, const value_type& __value,
534         const allocator_type& __a = allocator_type()) : _Base(__a, __n)
535     { _M_fill_initialize(__value); }
536   explicit deque(size_type __n) : _Base(allocator_type(), __n)
537     { _M_fill_initialize(value_type()); }
538
539 #ifdef __STL_MEMBER_TEMPLATES
540
541   // Check whether it's an integral type.  If so, it's not an iterator.
542   template <class _InputIterator>
543   deque(_InputIterator __first, _InputIterator __last,
544         const allocator_type& __a = allocator_type()) : _Base(__a) {
545     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
546     _M_initialize_dispatch(__first, __last, _Integral());
547   }
548
549   template <class _Integer>
550   void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
551     _M_initialize_map(__n);
552     _M_fill_initialize(__x);
553   }
554
555   template <class _InputIter>
556   void _M_initialize_dispatch(_InputIter __first, _InputIter __last,
557                               __false_type) {
558     _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
559   }
560
561 #else /* __STL_MEMBER_TEMPLATES */
562
563   deque(const value_type* __first, const value_type* __last,
564         const allocator_type& __a = allocator_type()) 
565     : _Base(__a, __last - __first)
566     { uninitialized_copy(__first, __last, _M_start); }
567   deque(const_iterator __first, const_iterator __last,
568         const allocator_type& __a = allocator_type()) 
569     : _Base(__a, __last - __first)
570     { uninitialized_copy(__first, __last, _M_start); }
571
572 #endif /* __STL_MEMBER_TEMPLATES */
573
574   ~deque() { destroy(_M_start, _M_finish); }
575
576   deque& operator= (const deque& __x) {
577     const size_type __len = size();
578     if (&__x != this) {
579       if (__len >= __x.size())
580         erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
581       else {
582         const_iterator __mid = __x.begin() + difference_type(__len);
583         copy(__x.begin(), __mid, _M_start);
584         insert(_M_finish, __mid, __x.end());
585       }
586     }
587     return *this;
588   }        
589
590   void swap(deque& __x) {
591     __STD::swap(_M_start, __x._M_start);
592     __STD::swap(_M_finish, __x._M_finish);
593     __STD::swap(_M_map, __x._M_map);
594     __STD::swap(_M_map_size, __x._M_map_size);
595   }
596
597 public: 
598   // assign(), a generalized assignment member function.  Two
599   // versions: one that takes a count, and one that takes a range.
600   // The range version is a member template, so we dispatch on whether
601   // or not the type is an integer.
602
603   void _M_fill_assign(size_type __n, const _Tp& __val) {
604     if (__n > size()) {
605       fill(begin(), end(), __val);
606       insert(end(), __n - size(), __val);
607     }
608     else {
609       erase(begin() + __n, end());
610       fill(begin(), end(), __val);
611     }
612   }
613
614   void assign(size_type __n, const _Tp& __val) {
615     _M_fill_assign(__n, __val);
616   }
617
618 #ifdef __STL_MEMBER_TEMPLATES
619
620   template <class _InputIterator>
621   void assign(_InputIterator __first, _InputIterator __last) {
622     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
623     _M_assign_dispatch(__first, __last, _Integral());
624   }
625
626 private:                        // helper functions for assign() 
627
628   template <class _Integer>
629   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
630     { _M_fill_assign((size_type) __n, (_Tp) __val); }
631
632   template <class _InputIterator>
633   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
634                           __false_type) {
635     _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first));
636   }
637
638   template <class _InputIterator>
639   void _M_assign_aux(_InputIterator __first, _InputIterator __last,
640                      input_iterator_tag);
641
642   template <class _ForwardIterator>
643   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
644                      forward_iterator_tag) {
645     size_type __len = 0;
646     distance(__first, __last, __len);
647     if (__len > size()) {
648       _ForwardIterator __mid = __first;
649       advance(__mid, size());
650       copy(__first, __mid, begin());
651       insert(end(), __mid, __last);
652     }
653     else
654       erase(copy(__first, __last, begin()), end());
655   }
656
657 #endif /* __STL_MEMBER_TEMPLATES */
658
659 public:                         // push_* and pop_*
660   
661   void push_back(const value_type& __t) {
662     if (_M_finish._M_cur != _M_finish._M_last - 1) {
663       construct(_M_finish._M_cur, __t);
664       ++_M_finish._M_cur;
665     }
666     else
667       _M_push_back_aux(__t);
668   }
669
670   void push_back() {
671     if (_M_finish._M_cur != _M_finish._M_last - 1) {
672       construct(_M_finish._M_cur);
673       ++_M_finish._M_cur;
674     }
675     else
676       _M_push_back_aux();
677   }
678
679   void push_front(const value_type& __t) {
680     if (_M_start._M_cur != _M_start._M_first) {
681       construct(_M_start._M_cur - 1, __t);
682       --_M_start._M_cur;
683     }
684     else
685       _M_push_front_aux(__t);
686   }
687
688   void push_front() {
689     if (_M_start._M_cur != _M_start._M_first) {
690       construct(_M_start._M_cur - 1);
691       --_M_start._M_cur;
692     }
693     else
694       _M_push_front_aux();
695   }
696
697
698   void pop_back() {
699     if (_M_finish._M_cur != _M_finish._M_first) {
700       --_M_finish._M_cur;
701       destroy(_M_finish._M_cur);
702     }
703     else
704       _M_pop_back_aux();
705   }
706
707   void pop_front() {
708     if (_M_start._M_cur != _M_start._M_last - 1) {
709       destroy(_M_start._M_cur);
710       ++_M_start._M_cur;
711     }
712     else 
713       _M_pop_front_aux();
714   }
715
716 public:                         // Insert
717
718   iterator insert(iterator position, const value_type& __x) {
719     if (position._M_cur == _M_start._M_cur) {
720       push_front(__x);
721       return _M_start;
722     }
723     else if (position._M_cur == _M_finish._M_cur) {
724       push_back(__x);
725       iterator __tmp = _M_finish;
726       --__tmp;
727       return __tmp;
728     }
729     else {
730       return _M_insert_aux(position, __x);
731     }
732   }
733
734   iterator insert(iterator __position)
735     { return insert(__position, value_type()); }
736
737   void insert(iterator __pos, size_type __n, const value_type& __x)
738     { _M_fill_insert(__pos, __n, __x); }
739
740   void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
741
742 #ifdef __STL_MEMBER_TEMPLATES  
743
744   // Check whether it's an integral type.  If so, it's not an iterator.
745   template <class _InputIterator>
746   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
747     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
748     _M_insert_dispatch(__pos, __first, __last, _Integral());
749   }
750
751   template <class _Integer>
752   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
753                           __true_type) {
754     _M_fill_insert(__pos, (size_type) __n, (value_type) __x);
755   }
756
757   template <class _InputIterator>
758   void _M_insert_dispatch(iterator __pos,
759                           _InputIterator __first, _InputIterator __last,
760                           __false_type) {
761     insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
762   }
763
764 #else /* __STL_MEMBER_TEMPLATES */
765
766   void insert(iterator __pos,
767               const value_type* __first, const value_type* __last);
768   void insert(iterator __pos,
769               const_iterator __first, const_iterator __last);
770
771 #endif /* __STL_MEMBER_TEMPLATES */
772
773   void resize(size_type __new_size, const value_type& __x) {
774     const size_type __len = size();
775     if (__new_size < __len) 
776       erase(_M_start + __new_size, _M_finish);
777     else
778       insert(_M_finish, __new_size - __len, __x);
779   }
780
781   void resize(size_type new_size) { resize(new_size, value_type()); }
782
783 public:                         // Erase
784   iterator erase(iterator __pos) {
785     iterator __next = __pos;
786     ++__next;
787     size_type __index = __pos - _M_start;
788     if (__index < (size() >> 1)) {
789       copy_backward(_M_start, __pos, __next);
790       pop_front();
791     }
792     else {
793       copy(__next, _M_finish, __pos);
794       pop_back();
795     }
796     return _M_start + __index;
797   }
798
799   iterator erase(iterator __first, iterator __last);
800   void clear(); 
801
802 protected:                        // Internal construction/destruction
803
804   void _M_fill_initialize(const value_type& __value);
805
806 #ifdef __STL_MEMBER_TEMPLATES  
807
808   template <class _InputIterator>
809   void _M_range_initialize(_InputIterator __first, _InputIterator __last,
810                         input_iterator_tag);
811
812   template <class _ForwardIterator>
813   void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
814                         forward_iterator_tag);
815
816 #endif /* __STL_MEMBER_TEMPLATES */
817
818 protected:                        // Internal push_* and pop_*
819
820   void _M_push_back_aux(const value_type&);
821   void _M_push_back_aux();
822   void _M_push_front_aux(const value_type&);
823   void _M_push_front_aux();
824   void _M_pop_back_aux();
825   void _M_pop_front_aux();
826
827 protected:                        // Internal insert functions
828
829 #ifdef __STL_MEMBER_TEMPLATES  
830
831   template <class _InputIterator>
832   void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
833               input_iterator_tag);
834
835   template <class _ForwardIterator>
836   void insert(iterator __pos,
837               _ForwardIterator __first, _ForwardIterator __last,
838               forward_iterator_tag);
839
840 #endif /* __STL_MEMBER_TEMPLATES */
841
842   iterator _M_insert_aux(iterator __pos, const value_type& __x);
843   iterator _M_insert_aux(iterator __pos);
844   void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
845
846 #ifdef __STL_MEMBER_TEMPLATES  
847
848   template <class _ForwardIterator>
849   void _M_insert_aux(iterator __pos, 
850                      _ForwardIterator __first, _ForwardIterator __last,
851                      size_type __n);
852
853 #else /* __STL_MEMBER_TEMPLATES */
854   
855   void _M_insert_aux(iterator __pos,
856                      const value_type* __first, const value_type* __last,
857                      size_type __n);
858
859   void _M_insert_aux(iterator __pos, 
860                      const_iterator __first, const_iterator __last,
861                      size_type __n);
862  
863 #endif /* __STL_MEMBER_TEMPLATES */
864
865   iterator _M_reserve_elements_at_front(size_type __n) {
866     size_type __vacancies = _M_start._M_cur - _M_start._M_first;
867     if (__n > __vacancies) 
868       _M_new_elements_at_front(__n - __vacancies);
869     return _M_start - difference_type(__n);
870   }
871
872   iterator _M_reserve_elements_at_back(size_type __n) {
873     size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
874     if (__n > __vacancies)
875       _M_new_elements_at_back(__n - __vacancies);
876     return _M_finish + difference_type(__n);
877   }
878
879   void _M_new_elements_at_front(size_type __new_elements);
880   void _M_new_elements_at_back(size_type __new_elements);
881
882 protected:                      // Allocation of _M_map and nodes
883
884   // Makes sure the _M_map has space for new nodes.  Does not actually
885   //  add the nodes.  Can invalidate _M_map pointers.  (And consequently, 
886   //  deque iterators.)
887
888   void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
889     if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
890       _M_reallocate_map(__nodes_to_add, false);
891   }
892
893   void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
894     if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
895       _M_reallocate_map(__nodes_to_add, true);
896   }
897
898   void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
899 };
900
901 // Non-inline member functions
902
903 #ifdef __STL_MEMBER_TEMPLATES
904
905 template <class _Tp, class _Alloc>
906 template <class _InputIter>
907 void deque<_Tp, _Alloc>
908   ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
909 {
910   iterator __cur = begin();
911   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
912     *__cur = *__first;
913   if (__first == __last)
914     erase(__cur, end());
915   else
916     insert(end(), __first, __last);
917 }
918
919 #endif /* __STL_MEMBER_TEMPLATES */
920
921 template <class _Tp, class _Alloc>
922 void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
923                                         size_type __n, const value_type& __x)
924 {
925   if (__pos._M_cur == _M_start._M_cur) {
926     iterator __new_start = _M_reserve_elements_at_front(__n);
927     __STL_TRY {
928       uninitialized_fill(__new_start, _M_start, __x);
929       _M_start = __new_start;
930     }
931     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
932   }
933   else if (__pos._M_cur == _M_finish._M_cur) {
934     iterator __new_finish = _M_reserve_elements_at_back(__n);
935     __STL_TRY {
936       uninitialized_fill(_M_finish, __new_finish, __x);
937       _M_finish = __new_finish;
938     }
939     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
940                                   __new_finish._M_node + 1));    
941   }
942   else 
943     _M_insert_aux(__pos, __n, __x);
944 }
945
946 #ifndef __STL_MEMBER_TEMPLATES  
947
948 template <class _Tp, class _Alloc>
949 void deque<_Tp, _Alloc>::insert(iterator __pos,
950                                 const value_type* __first,
951                                 const value_type* __last) {
952   size_type __n = __last - __first;
953   if (__pos._M_cur == _M_start._M_cur) {
954     iterator __new_start = _M_reserve_elements_at_front(__n);
955     __STL_TRY {
956       uninitialized_copy(__first, __last, __new_start);
957       _M_start = __new_start;
958     }
959     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
960   }
961   else if (__pos._M_cur == _M_finish._M_cur) {
962     iterator __new_finish = _M_reserve_elements_at_back(__n);
963     __STL_TRY {
964       uninitialized_copy(__first, __last, _M_finish);
965       _M_finish = __new_finish;
966     }
967     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
968                                   __new_finish._M_node + 1));
969   }
970   else
971     _M_insert_aux(__pos, __first, __last, __n);
972 }
973
974 template <class _Tp, class _Alloc>
975 void deque<_Tp,_Alloc>::insert(iterator __pos,
976                                const_iterator __first, const_iterator __last)
977 {
978   size_type __n = __last - __first;
979   if (__pos._M_cur == _M_start._M_cur) {
980     iterator __new_start = _M_reserve_elements_at_front(__n);
981     __STL_TRY {
982       uninitialized_copy(__first, __last, __new_start);
983       _M_start = __new_start;
984     }
985     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
986   }
987   else if (__pos._M_cur == _M_finish._M_cur) {
988     iterator __new_finish = _M_reserve_elements_at_back(__n);
989     __STL_TRY {
990       uninitialized_copy(__first, __last, _M_finish);
991       _M_finish = __new_finish;
992     }
993     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
994                  __new_finish._M_node + 1));
995   }
996   else
997     _M_insert_aux(__pos, __first, __last, __n);
998 }
999
1000 #endif /* __STL_MEMBER_TEMPLATES */
1001
1002 template <class _Tp, class _Alloc>
1003 typename deque<_Tp,_Alloc>::iterator 
1004 deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
1005 {
1006   if (__first == _M_start && __last == _M_finish) {
1007     clear();
1008     return _M_finish;
1009   }
1010   else {
1011     difference_type __n = __last - __first;
1012     difference_type __elems_before = __first - _M_start;
1013     if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) {
1014       copy_backward(_M_start, __first, __last);
1015       iterator __new_start = _M_start + __n;
1016       destroy(_M_start, __new_start);
1017       _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
1018       _M_start = __new_start;
1019     }
1020     else {
1021       copy(__last, _M_finish, __first);
1022       iterator __new_finish = _M_finish - __n;
1023       destroy(__new_finish, _M_finish);
1024       _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
1025       _M_finish = __new_finish;
1026     }
1027     return _M_start + __elems_before;
1028   }
1029 }
1030
1031 template <class _Tp, class _Alloc> 
1032 void deque<_Tp,_Alloc>::clear()
1033 {
1034   for (_Map_pointer __node = _M_start._M_node + 1;
1035        __node < _M_finish._M_node;
1036        ++__node) {
1037     destroy(*__node, *__node + _S_buffer_size());
1038     _M_deallocate_node(*__node);
1039   }
1040
1041   if (_M_start._M_node != _M_finish._M_node) {
1042     destroy(_M_start._M_cur, _M_start._M_last);
1043     destroy(_M_finish._M_first, _M_finish._M_cur);
1044     _M_deallocate_node(_M_finish._M_first);
1045   }
1046   else
1047     destroy(_M_start._M_cur, _M_finish._M_cur);
1048
1049   _M_finish = _M_start;
1050 }
1051
1052 // Precondition: _M_start and _M_finish have already been initialized,
1053 // but none of the deque's elements have yet been constructed.
1054 template <class _Tp, class _Alloc>
1055 void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value) {
1056   _Map_pointer __cur;
1057   __STL_TRY {
1058     for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
1059       uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
1060     uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
1061   }
1062   __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur)));
1063 }
1064
1065 #ifdef __STL_MEMBER_TEMPLATES  
1066
1067 template <class _Tp, class _Alloc> template <class _InputIterator>
1068 void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
1069                                             _InputIterator __last,
1070                                             input_iterator_tag)
1071 {
1072   _M_initialize_map(0);
1073   __STL_TRY {
1074     for ( ; __first != __last; ++__first)
1075       push_back(*__first);
1076   }
1077   __STL_UNWIND(clear());
1078 }
1079
1080 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1081 void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
1082                                             _ForwardIterator __last,
1083                                             forward_iterator_tag)
1084 {
1085   size_type __n = 0;
1086   distance(__first, __last, __n);
1087   _M_initialize_map(__n);
1088
1089   _Map_pointer __cur_node;
1090   __STL_TRY {
1091     for (__cur_node = _M_start._M_node; 
1092          __cur_node < _M_finish._M_node; 
1093          ++__cur_node) {
1094       _ForwardIterator __mid = __first;
1095       advance(__mid, _S_buffer_size());
1096       uninitialized_copy(__first, __mid, *__cur_node);
1097       __first = __mid;
1098     }
1099     uninitialized_copy(__first, __last, _M_finish._M_first);
1100   }
1101   __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node)));
1102 }
1103
1104 #endif /* __STL_MEMBER_TEMPLATES */
1105
1106 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
1107 template <class _Tp, class _Alloc>
1108 void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
1109 {
1110   value_type __t_copy = __t;
1111   _M_reserve_map_at_back();
1112   *(_M_finish._M_node + 1) = _M_allocate_node();
1113   __STL_TRY {
1114     construct(_M_finish._M_cur, __t_copy);
1115     _M_finish._M_set_node(_M_finish._M_node + 1);
1116     _M_finish._M_cur = _M_finish._M_first;
1117   }
1118   __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
1119 }
1120
1121 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
1122 template <class _Tp, class _Alloc>
1123 void deque<_Tp,_Alloc>::_M_push_back_aux()
1124 {
1125   _M_reserve_map_at_back();
1126   *(_M_finish._M_node + 1) = _M_allocate_node();
1127   __STL_TRY {
1128     construct(_M_finish._M_cur);
1129     _M_finish._M_set_node(_M_finish._M_node + 1);
1130     _M_finish._M_cur = _M_finish._M_first;
1131   }
1132   __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
1133 }
1134
1135 // Called only if _M_start._M_cur == _M_start._M_first.
1136 template <class _Tp, class _Alloc>
1137 void  deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
1138 {
1139   value_type __t_copy = __t;
1140   _M_reserve_map_at_front();
1141   *(_M_start._M_node - 1) = _M_allocate_node();
1142   __STL_TRY {
1143     _M_start._M_set_node(_M_start._M_node - 1);
1144     _M_start._M_cur = _M_start._M_last - 1;
1145     construct(_M_start._M_cur, __t_copy);
1146   }
1147   __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
1148
1149
1150 // Called only if _M_start._M_cur == _M_start._M_first.
1151 template <class _Tp, class _Alloc>
1152 void deque<_Tp,_Alloc>::_M_push_front_aux()
1153 {
1154   _M_reserve_map_at_front();
1155   *(_M_start._M_node - 1) = _M_allocate_node();
1156   __STL_TRY {
1157     _M_start._M_set_node(_M_start._M_node - 1);
1158     _M_start._M_cur = _M_start._M_last - 1;
1159     construct(_M_start._M_cur);
1160   }
1161   __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
1162
1163
1164 // Called only if _M_finish._M_cur == _M_finish._M_first.
1165 template <class _Tp, class _Alloc>
1166 void deque<_Tp,_Alloc>::_M_pop_back_aux()
1167 {
1168   _M_deallocate_node(_M_finish._M_first);
1169   _M_finish._M_set_node(_M_finish._M_node - 1);
1170   _M_finish._M_cur = _M_finish._M_last - 1;
1171   destroy(_M_finish._M_cur);
1172 }
1173
1174 // Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
1175 // if the deque has at least one element (a precondition for this member 
1176 // function), and if _M_start._M_cur == _M_start._M_last, then the deque 
1177 // must have at least two nodes.
1178 template <class _Tp, class _Alloc>
1179 void deque<_Tp,_Alloc>::_M_pop_front_aux()
1180 {
1181   destroy(_M_start._M_cur);
1182   _M_deallocate_node(_M_start._M_first);
1183   _M_start._M_set_node(_M_start._M_node + 1);
1184   _M_start._M_cur = _M_start._M_first;
1185 }      
1186
1187 #ifdef __STL_MEMBER_TEMPLATES  
1188
1189 template <class _Tp, class _Alloc> template <class _InputIterator>
1190 void deque<_Tp,_Alloc>::insert(iterator __pos,
1191                                _InputIterator __first, _InputIterator __last,
1192                                input_iterator_tag)
1193 {
1194   copy(__first, __last, inserter(*this, __pos));
1195 }
1196
1197 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1198 void
1199 deque<_Tp,_Alloc>::insert(iterator __pos,
1200                           _ForwardIterator __first, _ForwardIterator __last,
1201                           forward_iterator_tag) {
1202   size_type __n = 0;
1203   distance(__first, __last, __n);
1204   if (__pos._M_cur == _M_start._M_cur) {
1205     iterator __new_start = _M_reserve_elements_at_front(__n);
1206     __STL_TRY {
1207       uninitialized_copy(__first, __last, __new_start);
1208       _M_start = __new_start;
1209     }
1210     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1211   }
1212   else if (__pos._M_cur == _M_finish._M_cur) {
1213     iterator __new_finish = _M_reserve_elements_at_back(__n);
1214     __STL_TRY {
1215       uninitialized_copy(__first, __last, _M_finish);
1216       _M_finish = __new_finish;
1217     }
1218     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
1219                                   __new_finish._M_node + 1));
1220   }
1221   else
1222     _M_insert_aux(__pos, __first, __last, __n);
1223 }
1224
1225 #endif /* __STL_MEMBER_TEMPLATES */
1226
1227 template <class _Tp, class _Alloc>
1228 typename deque<_Tp, _Alloc>::iterator
1229 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
1230 {
1231   difference_type __index = __pos - _M_start;
1232   value_type __x_copy = __x;
1233   if (static_cast<size_type>(__index) < size() / 2) {
1234     push_front(front());
1235     iterator __front1 = _M_start;
1236     ++__front1;
1237     iterator __front2 = __front1;
1238     ++__front2;
1239     __pos = _M_start + __index;
1240     iterator __pos1 = __pos;
1241     ++__pos1;
1242     copy(__front2, __pos1, __front1);
1243   }
1244   else {
1245     push_back(back());
1246     iterator __back1 = _M_finish;
1247     --__back1;
1248     iterator __back2 = __back1;
1249     --__back2;
1250     __pos = _M_start + __index;
1251     copy_backward(__pos, __back2, __back1);
1252   }
1253   *__pos = __x_copy;
1254   return __pos;
1255 }
1256
1257 template <class _Tp, class _Alloc>
1258 typename deque<_Tp,_Alloc>::iterator 
1259 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
1260 {
1261   difference_type __index = __pos - _M_start;
1262   if (static_cast<size_type>(__index) < size() / 2) {
1263     push_front(front());
1264     iterator __front1 = _M_start;
1265     ++__front1;
1266     iterator __front2 = __front1;
1267     ++__front2;
1268     __pos = _M_start + __index;
1269     iterator __pos1 = __pos;
1270     ++__pos1;
1271     copy(__front2, __pos1, __front1);
1272   }
1273   else {
1274     push_back(back());
1275     iterator __back1 = _M_finish;
1276     --__back1;
1277     iterator __back2 = __back1;
1278     --__back2;
1279     __pos = _M_start + __index;
1280     copy_backward(__pos, __back2, __back1);
1281   }
1282   *__pos = value_type();
1283   return __pos;
1284 }
1285
1286 template <class _Tp, class _Alloc>
1287 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
1288                                       size_type __n,
1289                                       const value_type& __x)
1290 {
1291   const difference_type __elems_before = __pos - _M_start;
1292   size_type __length = this->size();
1293   value_type __x_copy = __x;
1294   if (__elems_before < difference_type(__length / 2)) {
1295     iterator __new_start = _M_reserve_elements_at_front(__n);
1296     iterator __old_start = _M_start;
1297     __pos = _M_start + __elems_before;
1298     __STL_TRY {
1299       if (__elems_before >= difference_type(__n)) {
1300         iterator __start_n = _M_start + difference_type(__n);
1301         uninitialized_copy(_M_start, __start_n, __new_start);
1302         _M_start = __new_start;
1303         copy(__start_n, __pos, __old_start);
1304         fill(__pos - difference_type(__n), __pos, __x_copy);
1305       }
1306       else {
1307         __uninitialized_copy_fill(_M_start, __pos, __new_start, 
1308                                   _M_start, __x_copy);
1309         _M_start = __new_start;
1310         fill(__old_start, __pos, __x_copy);
1311       }
1312     }
1313     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1314   }
1315   else {
1316     iterator __new_finish = _M_reserve_elements_at_back(__n);
1317     iterator __old_finish = _M_finish;
1318     const difference_type __elems_after = 
1319       difference_type(__length) - __elems_before;
1320     __pos = _M_finish - __elems_after;
1321     __STL_TRY {
1322       if (__elems_after > difference_type(__n)) {
1323         iterator __finish_n = _M_finish - difference_type(__n);
1324         uninitialized_copy(__finish_n, _M_finish, _M_finish);
1325         _M_finish = __new_finish;
1326         copy_backward(__pos, __finish_n, __old_finish);
1327         fill(__pos, __pos + difference_type(__n), __x_copy);
1328       }
1329       else {
1330         __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
1331                                   __x_copy, __pos, _M_finish);
1332         _M_finish = __new_finish;
1333         fill(__pos, __old_finish, __x_copy);
1334       }
1335     }
1336     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
1337                                   __new_finish._M_node + 1));
1338   }
1339 }
1340
1341 #ifdef __STL_MEMBER_TEMPLATES  
1342
1343 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1344 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
1345                                       _ForwardIterator __first,
1346                                       _ForwardIterator __last,
1347                                       size_type __n)
1348 {
1349   const difference_type __elemsbefore = __pos - _M_start;
1350   size_type __length = size();
1351   if (static_cast<size_type>(__elemsbefore) < __length / 2) {
1352     iterator __new_start = _M_reserve_elements_at_front(__n);
1353     iterator __old_start = _M_start;
1354     __pos = _M_start + __elemsbefore;
1355     __STL_TRY {
1356       if (__elemsbefore >= difference_type(__n)) {
1357         iterator __start_n = _M_start + difference_type(__n); 
1358         uninitialized_copy(_M_start, __start_n, __new_start);
1359         _M_start = __new_start;
1360         copy(__start_n, __pos, __old_start);
1361         copy(__first, __last, __pos - difference_type(__n));
1362       }
1363       else {
1364         _ForwardIterator __mid = __first;
1365         advance(__mid, difference_type(__n) - __elemsbefore);
1366         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1367                                   __new_start);
1368         _M_start = __new_start;
1369         copy(__mid, __last, __old_start);
1370       }
1371     }
1372     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1373   }
1374   else {
1375     iterator __new_finish = _M_reserve_elements_at_back(__n);
1376     iterator __old_finish = _M_finish;
1377     const difference_type __elemsafter = 
1378       difference_type(__length) - __elemsbefore;
1379     __pos = _M_finish - __elemsafter;
1380     __STL_TRY {
1381       if (__elemsafter > difference_type(__n)) {
1382         iterator __finish_n = _M_finish - difference_type(__n);
1383         uninitialized_copy(__finish_n, _M_finish, _M_finish);
1384         _M_finish = __new_finish;
1385         copy_backward(__pos, __finish_n, __old_finish);
1386         copy(__first, __last, __pos);
1387       }
1388       else {
1389         _ForwardIterator __mid = __first;
1390         advance(__mid, __elemsafter);
1391         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1392         _M_finish = __new_finish;
1393         copy(__first, __mid, __pos);
1394       }
1395     }
1396     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
1397                                   __new_finish._M_node + 1));
1398   }
1399 }
1400
1401 #else /* __STL_MEMBER_TEMPLATES */
1402
1403 template <class _Tp, class _Alloc>
1404 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
1405                                       const value_type* __first,
1406                                       const value_type* __last,
1407                                       size_type __n)
1408 {
1409   const difference_type __elemsbefore = __pos - _M_start;
1410   size_type __length = size();
1411   if (__elemsbefore < __length / 2) {
1412     iterator __new_start = _M_reserve_elements_at_front(__n);
1413     iterator __old_start = _M_start;
1414     __pos = _M_start + __elemsbefore;
1415     __STL_TRY {
1416       if (__elemsbefore >= difference_type(__n)) {
1417         iterator __start_n = _M_start + difference_type(__n);
1418         uninitialized_copy(_M_start, __start_n, __new_start);
1419         _M_start = __new_start;
1420         copy(__start_n, __pos, __old_start);
1421         copy(__first, __last, __pos - difference_type(__n));
1422       }
1423       else {
1424         const value_type* __mid = 
1425           __first + (difference_type(__n) - __elemsbefore);
1426         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1427                                   __new_start);
1428         _M_start = __new_start;
1429         copy(__mid, __last, __old_start);
1430       }
1431     }
1432     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1433   }
1434   else {
1435     iterator __new_finish = _M_reserve_elements_at_back(__n);
1436     iterator __old_finish = _M_finish;
1437     const difference_type __elemsafter = 
1438       difference_type(__length) - __elemsbefore;
1439     __pos = _M_finish - __elemsafter;
1440     __STL_TRY {
1441       if (__elemsafter > difference_type(__n)) {
1442         iterator __finish_n = _M_finish - difference_type(__n);
1443         uninitialized_copy(__finish_n, _M_finish, _M_finish);
1444         _M_finish = __new_finish;
1445         copy_backward(__pos, __finish_n, __old_finish);
1446         copy(__first, __last, __pos);
1447       }
1448       else {
1449         const value_type* __mid = __first + __elemsafter;
1450         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1451         _M_finish = __new_finish;
1452         copy(__first, __mid, __pos);
1453       }
1454     }
1455     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
1456                                   __new_finish._M_node + 1));
1457   }
1458 }
1459
1460 template <class _Tp, class _Alloc>
1461 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
1462                                       const_iterator __first,
1463                                       const_iterator __last,
1464                                       size_type __n)
1465 {
1466   const difference_type __elemsbefore = __pos - _M_start;
1467   size_type __length = size();
1468   if (__elemsbefore < __length / 2) {
1469     iterator __new_start = _M_reserve_elements_at_front(__n);
1470     iterator __old_start = _M_start;
1471     __pos = _M_start + __elemsbefore;
1472     __STL_TRY {
1473       if (__elemsbefore >= __n) {
1474         iterator __start_n = _M_start + __n;
1475         uninitialized_copy(_M_start, __start_n, __new_start);
1476         _M_start = __new_start;
1477         copy(__start_n, __pos, __old_start);
1478         copy(__first, __last, __pos - difference_type(__n));
1479       }
1480       else {
1481         const_iterator __mid = __first + (__n - __elemsbefore);
1482         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1483                                   __new_start);
1484         _M_start = __new_start;
1485         copy(__mid, __last, __old_start);
1486       }
1487     }
1488     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1489   }
1490   else {
1491     iterator __new_finish = _M_reserve_elements_at_back(__n);
1492     iterator __old_finish = _M_finish;
1493     const difference_type __elemsafter = __length - __elemsbefore;
1494     __pos = _M_finish - __elemsafter;
1495     __STL_TRY {
1496       if (__elemsafter > __n) {
1497         iterator __finish_n = _M_finish - difference_type(__n);
1498         uninitialized_copy(__finish_n, _M_finish, _M_finish);
1499         _M_finish = __new_finish;
1500         copy_backward(__pos, __finish_n, __old_finish);
1501         copy(__first, __last, __pos);
1502       }
1503       else {
1504         const_iterator __mid = __first + __elemsafter;
1505         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1506         _M_finish = __new_finish;
1507         copy(__first, __mid, __pos);
1508       }
1509     }
1510     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
1511                  __new_finish._M_node + 1));
1512   }
1513 }
1514
1515 #endif /* __STL_MEMBER_TEMPLATES */
1516
1517 template <class _Tp, class _Alloc>
1518 void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
1519 {
1520   size_type __new_nodes
1521       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
1522   _M_reserve_map_at_front(__new_nodes);
1523   size_type __i;
1524   __STL_TRY {
1525     for (__i = 1; __i <= __new_nodes; ++__i)
1526       *(_M_start._M_node - __i) = _M_allocate_node();
1527   }
1528 #       ifdef __STL_USE_EXCEPTIONS
1529   catch(...) {
1530     for (size_type __j = 1; __j < __i; ++__j)
1531       _M_deallocate_node(*(_M_start._M_node - __j));      
1532     throw;
1533   }
1534 #       endif /* __STL_USE_EXCEPTIONS */
1535 }
1536
1537 template <class _Tp, class _Alloc>
1538 void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
1539 {
1540   size_type __new_nodes
1541       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
1542   _M_reserve_map_at_back(__new_nodes);
1543   size_type __i;
1544   __STL_TRY {
1545     for (__i = 1; __i <= __new_nodes; ++__i)
1546       *(_M_finish._M_node + __i) = _M_allocate_node();
1547   }
1548 #       ifdef __STL_USE_EXCEPTIONS
1549   catch(...) {
1550     for (size_type __j = 1; __j < __i; ++__j)
1551       _M_deallocate_node(*(_M_finish._M_node + __j));      
1552     throw;
1553   }
1554 #       endif /* __STL_USE_EXCEPTIONS */
1555 }
1556
1557 template <class _Tp, class _Alloc>
1558 void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
1559                                           bool __add_at_front)
1560 {
1561   size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
1562   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
1563
1564   _Map_pointer __new_nstart;
1565   if (_M_map_size > 2 * __new_num_nodes) {
1566     __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
1567                      + (__add_at_front ? __nodes_to_add : 0);
1568     if (__new_nstart < _M_start._M_node)
1569       copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
1570     else
1571       copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
1572                     __new_nstart + __old_num_nodes);
1573   }
1574   else {
1575     size_type __new_map_size = 
1576       _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
1577
1578     _Map_pointer __new_map = _M_allocate_map(__new_map_size);
1579     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
1580                          + (__add_at_front ? __nodes_to_add : 0);
1581     copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
1582     _M_deallocate_map(_M_map, _M_map_size);
1583
1584     _M_map = __new_map;
1585     _M_map_size = __new_map_size;
1586   }
1587
1588   _M_start._M_set_node(__new_nstart);
1589   _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
1590 }
1591
1592
1593 // Nonmember functions.
1594
1595 template <class _Tp, class _Alloc>
1596 inline bool operator==(const deque<_Tp, _Alloc>& __x,
1597                        const deque<_Tp, _Alloc>& __y) {
1598   return __x.size() == __y.size() &&
1599          equal(__x.begin(), __x.end(), __y.begin());
1600 }
1601
1602 template <class _Tp, class _Alloc>
1603 inline bool operator<(const deque<_Tp, _Alloc>& __x,
1604                       const deque<_Tp, _Alloc>& __y) {
1605   return lexicographical_compare(__x.begin(), __x.end(), 
1606                                  __y.begin(), __y.end());
1607 }
1608
1609 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
1610
1611 template <class _Tp, class _Alloc>
1612 inline bool operator!=(const deque<_Tp, _Alloc>& __x,
1613                        const deque<_Tp, _Alloc>& __y) {
1614   return !(__x == __y);
1615 }
1616
1617 template <class _Tp, class _Alloc>
1618 inline bool operator>(const deque<_Tp, _Alloc>& __x,
1619                       const deque<_Tp, _Alloc>& __y) {
1620   return __y < __x;
1621 }
1622
1623 template <class _Tp, class _Alloc>
1624 inline bool operator<=(const deque<_Tp, _Alloc>& __x,
1625                        const deque<_Tp, _Alloc>& __y) {
1626   return !(__y < __x);
1627 }
1628 template <class _Tp, class _Alloc>
1629 inline bool operator>=(const deque<_Tp, _Alloc>& __x,
1630                        const deque<_Tp, _Alloc>& __y) {
1631   return !(__x < __y);
1632 }
1633
1634 template <class _Tp, class _Alloc>
1635 inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
1636   __x.swap(__y);
1637 }
1638
1639 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
1640
1641 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
1642 #pragma reset woff 1174
1643 #pragma reset woff 1375
1644 #endif
1645           
1646 __STL_END_NAMESPACE 
1647   
1648 #endif /* __SGI_STL_INTERNAL_DEQUE_H */
1649
1650 // Local Variables:
1651 // mode:C++
1652 // End: