]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libstdc++/include/bits/stl_deque.h
Gcc 3.2.1-prerelease libf2c bits from the FSF anoncvs repo gcc-3_2-branch on 1-Sep...
[FreeBSD/FreeBSD.git] / contrib / libstdc++ / include / bits / stl_deque.h
1 // deque implementation -*- C++ -*-
2
3 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /*
31  *
32  * Copyright (c) 1994
33  * Hewlett-Packard Company
34  *
35  * Permission to use, copy, modify, distribute and sell this software
36  * and its documentation for any purpose is hereby granted without fee,
37  * provided that the above copyright notice appear in all copies and
38  * that both that copyright notice and this permission notice appear
39  * in supporting documentation.  Hewlett-Packard Company makes no
40  * representations about the suitability of this software for any
41  * purpose.  It is provided "as is" without express or implied warranty.
42  *
43  *
44  * Copyright (c) 1997
45  * Silicon Graphics Computer Systems, Inc.
46  *
47  * Permission to use, copy, modify, distribute and sell this software
48  * and its documentation for any purpose is hereby granted without fee,
49  * provided that the above copyright notice appear in all copies and
50  * that both that copyright notice and this permission notice appear
51  * in supporting documentation.  Silicon Graphics makes no
52  * representations about the suitability of this software for any
53  * purpose.  It is provided "as is" without express or implied warranty.
54  */
55
56 /** @file stl_deque.h
57  *  This is an internal header file, included by other library headers.
58  *  You should not attempt to use it directly.
59  */
60
61 #include <bits/concept_check.h>
62 #include <bits/stl_iterator_base_types.h>
63 #include <bits/stl_iterator_base_funcs.h>
64
65 #ifndef __GLIBCPP_INTERNAL_DEQUE_H
66 #define __GLIBCPP_INTERNAL_DEQUE_H
67
68
69 // Since this entire file is within namespace std, there's no reason to
70 // waste two spaces along the left column.  Thus the leading indentation is
71 // slightly violated from here on.
72 namespace std
73
74
75 /**
76  *  @if maint
77  *  @brief This function controls the size of memory nodes.
78  *  @param  size  The size of an element.
79  *  @return   The number (not bytesize) of elements per node.
80  *
81  *  This function started off as a compiler kludge from SGI, but seems to
82  *  be a useful wrapper around a repeated constant expression.
83  *  @endif
84 */
85 inline size_t 
86 __deque_buf_size(size_t __size) 
87 { return __size < 512 ? size_t(512 / __size) : size_t(1); }
88
89
90 /// A deque::iterator.
91 /**
92  *  Quite a bit of intelligence here.  Much of the functionality of deque is
93  *  actually passed off to this class.  A deque holds two of these internally,
94  *  marking its valid range.  Access to elements is done as offsets of either
95  *  of those two, relying on operator overloading in this class.
96  *
97  *  @if maint
98  *  All the functions are op overloads except for _M_set_node.
99  *  @endif
100 */
101 template <class _Tp, class _Ref, class _Ptr>
102 struct _Deque_iterator
103 {
104   typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
105   typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
106   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
107
108   typedef random_access_iterator_tag iterator_category;
109   typedef _Tp                        value_type;
110   typedef _Ptr                       pointer;
111   typedef _Ref                       reference;
112   typedef size_t                     size_type;
113   typedef ptrdiff_t                  difference_type;
114   typedef _Tp**                      _Map_pointer;
115   typedef _Deque_iterator            _Self;
116
117   _Tp* _M_cur;
118   _Tp* _M_first;
119   _Tp* _M_last;
120   _Map_pointer _M_node;
121
122   _Deque_iterator(_Tp* __x, _Map_pointer __y) 
123     : _M_cur(__x), _M_first(*__y),
124       _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
125   _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
126   _Deque_iterator(const iterator& __x)
127     : _M_cur(__x._M_cur), _M_first(__x._M_first), 
128       _M_last(__x._M_last), _M_node(__x._M_node) {}
129
130   reference operator*() const { return *_M_cur; }
131   pointer operator->() const { return _M_cur; }
132
133   _Self& operator++() {
134     ++_M_cur;
135     if (_M_cur == _M_last) {
136       _M_set_node(_M_node + 1);
137       _M_cur = _M_first;
138     }
139     return *this; 
140   }
141   _Self operator++(int)  {
142     _Self __tmp = *this;
143     ++*this;
144     return __tmp;
145   }
146
147   _Self& operator--() {
148     if (_M_cur == _M_first) {
149       _M_set_node(_M_node - 1);
150       _M_cur = _M_last;
151     }
152     --_M_cur;
153     return *this;
154   }
155   _Self operator--(int) {
156     _Self __tmp = *this;
157     --*this;
158     return __tmp;
159   }
160
161   _Self& operator+=(difference_type __n)
162   {
163     difference_type __offset = __n + (_M_cur - _M_first);
164     if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
165       _M_cur += __n;
166     else {
167       difference_type __node_offset =
168         __offset > 0 ? __offset / difference_type(_S_buffer_size())
169                    : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
170       _M_set_node(_M_node + __node_offset);
171       _M_cur = _M_first + 
172         (__offset - __node_offset * difference_type(_S_buffer_size()));
173     }
174     return *this;
175   }
176
177   _Self operator+(difference_type __n) const
178   {
179     _Self __tmp = *this;
180     return __tmp += __n;
181   }
182
183   _Self& operator-=(difference_type __n) { return *this += -__n; }
184  
185   _Self operator-(difference_type __n) const {
186     _Self __tmp = *this;
187     return __tmp -= __n;
188   }
189
190   reference operator[](difference_type __n) const { return *(*this + __n); }
191
192   /** @if maint
193    *  Prepares to traverse new_node.  Sets everything except _M_cur, which
194    *  should therefore be set by the caller immediately afterwards, based on
195    *  _M_first and _M_last.
196    *  @endif
197   */
198   void _M_set_node(_Map_pointer __new_node) {
199     _M_node = __new_node;
200     _M_first = *__new_node;
201     _M_last = _M_first + difference_type(_S_buffer_size());
202   }
203 };
204
205 // Note: we also provide overloads whose operands are of the same type in
206 // order to avoid ambiguos overload resolution when std::rel_ops operators
207 // are in scope (for additional details, see libstdc++/3628)
208 template <class _Tp, class _Ref, class _Ptr>
209 inline bool
210 operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
211            const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
212 {
213   return __x._M_cur == __y._M_cur;
214 }
215
216 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
217 inline bool
218 operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
219            const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
220 {
221   return __x._M_cur == __y._M_cur;
222 }
223
224 template <class _Tp, class _Ref, class _Ptr>
225 inline bool
226 operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
227            const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
228 {
229   return !(__x == __y);
230 }
231
232 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
233 inline bool
234 operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
235            const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
236 {
237   return !(__x == __y);
238 }
239
240 template <class _Tp, class _Ref, class _Ptr>
241 inline bool
242 operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
243            const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
244 {
245   return (__x._M_node == __y._M_node) ? 
246     (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
247 }
248
249 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
250 inline bool
251 operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
252            const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
253 {
254   return (__x._M_node == __y._M_node) ? 
255     (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
256 }
257
258 template <class _Tp, class _Ref, class _Ptr>
259 inline bool
260 operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
261            const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
262 {
263   return __y < __x;
264 }
265
266 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
267 inline bool
268 operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
269            const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
270 {
271   return __y < __x;
272 }
273
274 template <class _Tp, class _Ref, class _Ptr>
275 inline bool
276 operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
277            const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
278 {
279   return !(__y < __x);
280 }
281
282 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
283 inline bool
284 operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
285            const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
286 {
287   return !(__y < __x);
288 }
289
290 template <class _Tp, class _Ref, class _Ptr>
291 inline bool
292 operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
293            const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
294 {
295   return !(__x < __y);
296 }
297
298 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
299 inline bool
300 operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
301            const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
302 {
303   return !(__x < __y);
304 }
305
306 // _GLIBCPP_RESOLVE_LIB_DEFECTS
307 // According to the resolution of DR179 not only the various comparison
308 // operators but also operator- must accept mixed iterator/const_iterator
309 // parameters.
310 template <typename _Tp, typename _RefL, typename _PtrL,
311                         typename _RefR, typename _PtrR>
312 inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
313 operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
314           const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
315 {
316   return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
317     (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) *
318     (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) +
319     (__y._M_last - __y._M_cur);
320 }
321
322 template <class _Tp, class _Ref, class _Ptr>
323 inline _Deque_iterator<_Tp, _Ref, _Ptr>
324 operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
325 {
326   return __x + __n;
327 }
328
329
330 /// @if maint Primary default version.  @endif
331 /**
332  *  @if maint
333  *  Deque base class.  It has two purposes.  First, its constructor
334  *  and destructor allocate (but don't initialize) storage.  This makes
335  *  exception safety easier.  Second, the base class encapsulates all of
336  *  the differences between SGI-style allocators and standard-conforming
337  *  allocators.  There are two versions:  this ordinary one, and the
338  *  space-saving specialization for instanceless allocators.
339  *  @endif
340 */
341 template <class _Tp, class _Alloc, bool __is_static>
342 class _Deque_alloc_base
343 {
344 public:
345   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
346   allocator_type get_allocator() const { return _M_node_allocator; }
347
348   _Deque_alloc_base(const allocator_type& __a)
349     : _M_node_allocator(__a), _M_map_allocator(__a),
350       _M_map(0), _M_map_size(0)
351   {}
352   
353 protected:
354   typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
355           _Map_allocator_type;
356
357   allocator_type      _M_node_allocator;
358   _Map_allocator_type _M_map_allocator;
359
360   _Tp* _M_allocate_node() {
361     return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
362   }
363   void _M_deallocate_node(_Tp* __p) {
364     _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
365   }
366   _Tp** _M_allocate_map(size_t __n) 
367     { return _M_map_allocator.allocate(__n); }
368   void _M_deallocate_map(_Tp** __p, size_t __n) 
369     { _M_map_allocator.deallocate(__p, __n); }
370
371   _Tp** _M_map;
372   size_t _M_map_size;
373 };
374
375 /// @if maint Specialization for instanceless allocators.  @endif
376 template <class _Tp, class _Alloc>
377 class _Deque_alloc_base<_Tp, _Alloc, true>
378 {
379 public:
380   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
381   allocator_type get_allocator() const { return allocator_type(); }
382
383   _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
384   
385 protected:
386   typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
387   typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
388
389   _Tp* _M_allocate_node() {
390     return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
391   }
392   void _M_deallocate_node(_Tp* __p) {
393     _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
394   }
395   _Tp** _M_allocate_map(size_t __n) 
396     { return _Map_alloc_type::allocate(__n); }
397   void _M_deallocate_map(_Tp** __p, size_t __n) 
398     { _Map_alloc_type::deallocate(__p, __n); }
399
400   _Tp** _M_map;
401   size_t _M_map_size;
402 };
403
404
405 /**
406  *  @if maint
407  *  Deque base class.  Using _Alloc_traits in the instantiation of the parent
408  *  class provides the compile-time dispatching mentioned in the parent's docs.
409  *  This class provides the unified face for deque's allocation.
410  *
411  *  Nothing in this class ever constructs or destroys an actual Tp element.
412  *  (Deque handles that itself.)  Only/All memory management is performed here.
413  *  @endif
414 */
415 template <class _Tp, class _Alloc>
416 class _Deque_base
417   : public _Deque_alloc_base<_Tp,_Alloc,
418                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
419 {
420 public:
421   typedef _Deque_alloc_base<_Tp,_Alloc,
422                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
423           _Base;
424   typedef typename _Base::allocator_type             allocator_type;
425   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
426   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
427
428   _Deque_base(const allocator_type& __a, size_t __num_elements)
429     : _Base(__a), _M_start(), _M_finish()
430     { _M_initialize_map(__num_elements); }
431   _Deque_base(const allocator_type& __a) 
432     : _Base(__a), _M_start(), _M_finish() {}
433   ~_Deque_base();    
434
435 protected:
436   void _M_initialize_map(size_t);
437   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
438   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
439   enum { _S_initial_map_size = 8 };
440
441 protected:
442   iterator _M_start;
443   iterator _M_finish;
444 };
445
446
447 template <class _Tp, class _Alloc>
448 _Deque_base<_Tp,_Alloc>::~_Deque_base()
449 {
450   if (_M_map) {
451     _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
452     _M_deallocate_map(_M_map, _M_map_size);
453   }
454 }
455
456 /**
457  *  @if maint
458  *  @brief Layout storage.
459  *  @param  num_elements  The count of T's for which to allocate space at first.
460  *  @return   Nothing.
461  *
462  *  The initial underlying memory layout is a bit complicated...
463  *  @endif
464 */
465 template <class _Tp, class _Alloc>
466 void
467 _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
468 {
469   size_t __num_nodes = 
470     __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
471
472   _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
473   _M_map = _M_allocate_map(_M_map_size);
474
475   _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
476   _Tp** __nfinish = __nstart + __num_nodes;
477     
478   try 
479     { _M_create_nodes(__nstart, __nfinish); }
480   catch(...)
481     {
482       _M_deallocate_map(_M_map, _M_map_size);
483       _M_map = 0;
484       _M_map_size = 0;
485       __throw_exception_again;
486     }
487   
488   _M_start._M_set_node(__nstart);
489   _M_finish._M_set_node(__nfinish - 1);
490   _M_start._M_cur = _M_start._M_first;
491   _M_finish._M_cur = _M_finish._M_first +
492                __num_elements % __deque_buf_size(sizeof(_Tp));
493 }
494
495 template <class _Tp, class _Alloc>
496 void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
497 {
498   _Tp** __cur;
499   try {
500     for (__cur = __nstart; __cur < __nfinish; ++__cur)
501       *__cur = _M_allocate_node();
502   }
503   catch(...)
504     { 
505       _M_destroy_nodes(__nstart, __cur);
506       __throw_exception_again; 
507     }
508 }
509
510 template <class _Tp, class _Alloc>
511 void
512 _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
513 {
514   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
515     _M_deallocate_node(*__n);
516 }
517
518
519 /**
520  *  @ingroup Containers
521  *  @ingroup Sequences
522  *
523  *  Meets the requirements of a <a href="tables.html#65">container</a>, a
524  *  <a href="tables.html#66">reversible container</a>, and a
525  *  <a href="tables.html#67">sequence</a>, including the
526  *  <a href="tables.html#68">optional sequence requirements</a>.
527  *
528  *  Placeholder:  see http://www.sgi.com/tech/stl/Deque.html for now.
529  *
530  *  In previous HP/SGI versions of deque, there was an extra template parameter
531  *  so users could control the node size.  This extension turned out to violate
532  *  the C++ standard (it can be detected using template template parameters),
533  *  and it was removed.
534  *
535  *  @if maint
536  *  Here's how a deque<Tp> manages memory.  Each deque has 4 members:
537  *  
538  *  - Tp**        _M_map
539  *  - size_t      _M_map_size
540  *  - iterator    _M_start, _M_finish
541  *  
542  *  map_size is at least 8.  %map is an array of map_size pointers-to-"nodes".
543  *  (The name has nothing to do with the std::map class.)
544  *  
545  *  A "node" has no specific type name as such, but it is referred to as
546  *  "node" in this file.  It is a simple array-of-Tp.  If Tp is very large,
547  *  there will be one Tp element per node (i.e., an "array" of one).
548  *  For non-huge Tp's, node size is inversely related to Tp size:  the
549  *  larger the Tp, the fewer Tp's will fit in a node.  The goal here is to
550  *  keep the total size of a node relatively small and constant over different
551  *  Tp's, to improve allocator efficiency.
552  *  
553  *  **** As I write this, the nodes are /not/ allocated using the high-speed
554  *  memory pool.  There are 20 hours left in the year; perhaps I can fix
555  *  this before 2002.
556  *  
557  *  Not every pointer in the %map array will point to a node.  If the initial
558  *  number of elements in the deque is small, the /middle/ %map pointers will
559  *  be valid, and the ones at the edges will be unused.  This same situation
560  *  will arise as the %map grows:  available %map pointers, if any, will be on
561  *  the ends.  As new nodes are created, only a subset of the %map's pointers
562  *  need to be copied "outward".
563  *
564  *  Class invariants:
565  * - For any nonsingular iterator i:
566  *    - i.node points to a member of the %map array.  (Yes, you read that
567  *      correctly:  i.node does not actually point to a node.)  The member of
568  *      the %map array is what actually points to the node.
569  *    - i.first == *(i.node)    (This points to the node (first Tp element).)
570  *    - i.last  == i.first + node_size
571  *    - i.cur is a pointer in the range [i.first, i.last).  NOTE:
572  *      the implication of this is that i.cur is always a dereferenceable
573  *      pointer, even if i is a past-the-end iterator.
574  * - Start and Finish are always nonsingular iterators.  NOTE: this means that
575  *   an empty deque must have one node, a deque with <N elements (where N is
576  *   the node buffer size) must have one node, a deque with N through (2N-1)
577  *   elements must have two nodes, etc.
578  * - For every node other than start.node and finish.node, every element in the
579  *   node is an initialized object.  If start.node == finish.node, then
580  *   [start.cur, finish.cur) are initialized objects, and the elements outside
581  *   that range are uninitialized storage.  Otherwise, [start.cur, start.last)
582  *   and [finish.first, finish.cur) are initialized objects, and [start.first,
583  *   start.cur) and [finish.cur, finish.last) are uninitialized storage.
584  * - [%map, %map + map_size) is a valid, non-empty range.  
585  * - [start.node, finish.node] is a valid range contained within 
586  *   [%map, %map + map_size).  
587  * - A pointer in the range [%map, %map + map_size) points to an allocated node
588  *   if and only if the pointer is in the range [start.node, finish.node].
589  *
590  *  Here's the magic:  nothing in deque is "aware" of the discontiguous storage!
591  *
592  *  The memory setup and layout occurs in the parent, _Base, and the iterator
593  *  class is entirely responsible for "leaping" from one node to the next.  All
594  *  the implementation routines for deque itself work only through the start
595  *  and finish iterators.  This keeps the routines simple and sane, and we can
596  *  use other standard algorithms as well.
597  *  @endif
598 */
599 template <class _Tp, class _Alloc = allocator<_Tp> >
600 class deque : protected _Deque_base<_Tp, _Alloc>
601 {
602   // concept requirements
603   __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
604
605   typedef _Deque_base<_Tp, _Alloc> _Base;
606
607 public:
608   typedef _Tp                                value_type;
609   typedef value_type*                        pointer;
610   typedef const value_type*                  const_pointer;
611   typedef value_type&                        reference;
612   typedef const value_type&                  const_reference;
613   typedef size_t                             size_type;
614   typedef ptrdiff_t                          difference_type;
615
616   typedef typename _Base::allocator_type allocator_type;
617   allocator_type get_allocator() const { return _Base::get_allocator(); }
618
619   typedef typename _Base::iterator           iterator;
620   typedef typename _Base::const_iterator     const_iterator;
621   typedef reverse_iterator<const_iterator>   const_reverse_iterator;
622   typedef reverse_iterator<iterator>         reverse_iterator;
623
624 protected:
625   typedef pointer* _Map_pointer;
626   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
627
628   // Functions controlling memory layout, and nothing else.
629   using _Base::_M_initialize_map;
630   using _Base::_M_create_nodes;
631   using _Base::_M_destroy_nodes;
632   using _Base::_M_allocate_node;
633   using _Base::_M_deallocate_node;
634   using _Base::_M_allocate_map;
635   using _Base::_M_deallocate_map;
636
637   /** @if maint
638    *  A total of four data members accumulated down the heirarchy.  If the
639    *  _Alloc type requires separate instances, then two of them will also be
640    *  included in each deque.
641    *  @endif
642   */
643   using _Base::_M_map;
644   using _Base::_M_map_size;
645   using _Base::_M_start;
646   using _Base::_M_finish;
647
648 public:                         // Basic accessors
649   iterator begin() { return _M_start; }
650   iterator end() { return _M_finish; }
651   const_iterator begin() const { return _M_start; }
652   const_iterator end() const { return _M_finish; }
653
654   reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
655   reverse_iterator rend() { return reverse_iterator(_M_start); }
656   const_reverse_iterator rbegin() const 
657     { return const_reverse_iterator(_M_finish); }
658   const_reverse_iterator rend() const 
659     { return const_reverse_iterator(_M_start); }
660
661   reference operator[](size_type __n)
662     { return _M_start[difference_type(__n)]; }
663   const_reference operator[](size_type __n) const 
664     { return _M_start[difference_type(__n)]; }
665
666   void _M_range_check(size_type __n) const {
667     if (__n >= this->size())
668       __throw_range_error("deque");
669   }
670
671   reference at(size_type __n)
672     { _M_range_check(__n); return (*this)[__n]; }
673   const_reference at(size_type __n) const
674     { _M_range_check(__n); return (*this)[__n]; }
675
676   reference front() { return *_M_start; }
677   reference back() {
678     iterator __tmp = _M_finish;
679     --__tmp;
680     return *__tmp;
681   }
682   const_reference front() const { return *_M_start; }
683   const_reference back() const {
684     const_iterator __tmp = _M_finish;
685     --__tmp;
686     return *__tmp;
687   }
688
689   size_type size() const { return _M_finish - _M_start; }
690   size_type max_size() const { return size_type(-1); }
691   bool empty() const { return _M_finish == _M_start; }
692
693 public:                         // Constructor, destructor.
694   explicit deque(const allocator_type& __a = allocator_type()) 
695     : _Base(__a, 0) {}
696   deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) 
697     { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
698   deque(size_type __n, const value_type& __value,
699         const allocator_type& __a = allocator_type()) : _Base(__a, __n)
700     { _M_fill_initialize(__value); }
701
702   explicit
703   deque(size_type __n)
704   : _Base(allocator_type(), __n)
705   { _M_fill_initialize(value_type()); }
706
707   // Check whether it's an integral type.  If so, it's not an iterator.
708   template<class _InputIterator>
709     deque(_InputIterator __first, _InputIterator __last,
710           const allocator_type& __a = allocator_type())
711     : _Base(__a)
712     {
713       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
714       _M_initialize_dispatch(__first, __last, _Integral());
715     }
716
717   template<class _Integer>
718     void
719     _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
720     {
721       _M_initialize_map(__n);
722       _M_fill_initialize(__x);
723     }
724
725   template<class _InputIter>
726     void
727     _M_initialize_dispatch(_InputIter __first, _InputIter __last, __false_type)
728     {
729       typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
730       _M_range_initialize(__first, __last, _IterCategory());
731     }
732
733   ~deque()
734   { _Destroy(_M_start, _M_finish); }
735
736   deque& operator= (const deque& __x) {
737     const size_type __len = size();
738     if (&__x != this) {
739       if (__len >= __x.size())
740         erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
741       else {
742         const_iterator __mid = __x.begin() + difference_type(__len);
743         copy(__x.begin(), __mid, _M_start);
744         insert(_M_finish, __mid, __x.end());
745       }
746     }
747     return *this;
748   }        
749
750   void swap(deque& __x) {
751     std::swap(_M_start, __x._M_start);
752     std::swap(_M_finish, __x._M_finish);
753     std::swap(_M_map, __x._M_map);
754     std::swap(_M_map_size, __x._M_map_size);
755   }
756
757 public: 
758   // assign(), a generalized assignment member function.  Two
759   // versions: one that takes a count, and one that takes a range.
760   // The range version is a member template, so we dispatch on whether
761   // or not the type is an integer.
762
763   void _M_fill_assign(size_type __n, const _Tp& __val) {
764     if (__n > size()) {
765       fill(begin(), end(), __val);
766       insert(end(), __n - size(), __val);
767     }
768     else {
769       erase(begin() + __n, end());
770       fill(begin(), end(), __val);
771     }
772   }
773
774   void
775   assign(size_type __n, const _Tp& __val)
776   { _M_fill_assign(__n, __val); }
777
778   template<class _InputIterator>
779     void
780     assign(_InputIterator __first, _InputIterator __last)
781     {
782       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
783       _M_assign_dispatch(__first, __last, _Integral());
784     }
785
786 private:                        // helper functions for assign() 
787
788   template<class _Integer>
789     void
790     _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
791     { _M_fill_assign(static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
792
793   template<class _InputIterator>
794     void
795     _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type)
796     {
797       typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
798       _M_assign_aux(__first, __last, _IterCategory());
799     }
800
801   template <class _InputIterator>
802   void _M_assign_aux(_InputIterator __first, _InputIterator __last,
803                      input_iterator_tag);
804
805   template <class _ForwardIterator>
806   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
807                      forward_iterator_tag) {
808     size_type __len = distance(__first, __last);
809     if (__len > size()) {
810       _ForwardIterator __mid = __first;
811       advance(__mid, size());
812       copy(__first, __mid, begin());
813       insert(end(), __mid, __last);
814     }
815     else
816       erase(copy(__first, __last, begin()), end());
817   }
818
819 public:                         // push_* and pop_*
820   
821   void
822   push_back(const value_type& __t)
823   {
824     if (_M_finish._M_cur != _M_finish._M_last - 1) {
825       _Construct(_M_finish._M_cur, __t);
826       ++_M_finish._M_cur;
827     }
828     else
829       _M_push_back_aux(__t);
830   }
831
832   void
833   push_back()
834   {
835     if (_M_finish._M_cur != _M_finish._M_last - 1) {
836       _Construct(_M_finish._M_cur);
837       ++_M_finish._M_cur;
838     }
839     else
840       _M_push_back_aux();
841   }
842
843   void
844   push_front(const value_type& __t) 
845   {
846     if (_M_start._M_cur != _M_start._M_first) {
847       _Construct(_M_start._M_cur - 1, __t);
848       --_M_start._M_cur;
849     }
850     else
851       _M_push_front_aux(__t);
852   }
853
854   void
855   push_front()
856   {
857     if (_M_start._M_cur != _M_start._M_first) {
858       _Construct(_M_start._M_cur - 1);
859       --_M_start._M_cur;
860     }
861     else
862       _M_push_front_aux();
863   }
864
865
866   void
867   pop_back()
868   {
869     if (_M_finish._M_cur != _M_finish._M_first) {
870       --_M_finish._M_cur;
871       _Destroy(_M_finish._M_cur);
872     }
873     else
874       _M_pop_back_aux();
875   }
876
877   void
878   pop_front()
879   {
880     if (_M_start._M_cur != _M_start._M_last - 1) {
881       _Destroy(_M_start._M_cur);
882       ++_M_start._M_cur;
883     }
884     else 
885       _M_pop_front_aux();
886   }
887
888 public:                         // Insert
889
890   iterator
891   insert(iterator position, const value_type& __x)
892   {
893     if (position._M_cur == _M_start._M_cur) {
894       push_front(__x);
895       return _M_start;
896     }
897     else if (position._M_cur == _M_finish._M_cur) {
898       push_back(__x);
899       iterator __tmp = _M_finish;
900       --__tmp;
901       return __tmp;
902     }
903     else {
904       return _M_insert_aux(position, __x);
905     }
906   }
907
908   iterator
909   insert(iterator __position)
910   { return insert(__position, value_type()); }
911
912   void
913   insert(iterator __pos, size_type __n, const value_type& __x)
914   { _M_fill_insert(__pos, __n, __x); }
915
916   void
917   _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
918
919   // Check whether it's an integral type.  If so, it's not an iterator.
920   template<class _InputIterator>
921     void
922     insert(iterator __pos, _InputIterator __first, _InputIterator __last)
923     {
924       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
925       _M_insert_dispatch(__pos, __first, __last, _Integral());
926     }
927
928   template<class _Integer>
929     void
930     _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
931     { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<value_type>(__x)); }
932
933   template<class _InputIterator>
934     void
935     _M_insert_dispatch(iterator __pos,
936                        _InputIterator __first, _InputIterator __last,
937                        __false_type)
938     {
939       typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
940       insert(__pos, __first, __last, _IterCategory());
941     }
942
943   void resize(size_type __new_size, const value_type& __x) {
944     const size_type __len = size();
945     if (__new_size < __len) 
946       erase(_M_start + __new_size, _M_finish);
947     else
948       insert(_M_finish, __new_size - __len, __x);
949   }
950
951   void resize(size_type new_size) { resize(new_size, value_type()); }
952
953 public:                         // Erase
954   iterator erase(iterator __pos) {
955     iterator __next = __pos;
956     ++__next;
957     size_type __index = __pos - _M_start;
958     if (__index < (size() >> 1)) {
959       copy_backward(_M_start, __pos, __next);
960       pop_front();
961     }
962     else {
963       copy(__next, _M_finish, __pos);
964       pop_back();
965     }
966     return _M_start + __index;
967   }
968
969   iterator erase(iterator __first, iterator __last);
970   void clear(); 
971
972 protected:                        // Internal construction/destruction
973
974   void _M_fill_initialize(const value_type& __value);
975
976   template <class _InputIterator>
977   void _M_range_initialize(_InputIterator __first, _InputIterator __last,
978                         input_iterator_tag);
979
980   template <class _ForwardIterator>
981   void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
982                         forward_iterator_tag);
983
984 protected:                        // Internal push_* and pop_*
985
986   void _M_push_back_aux(const value_type&);
987   void _M_push_back_aux();
988   void _M_push_front_aux(const value_type&);
989   void _M_push_front_aux();
990   void _M_pop_back_aux();
991   void _M_pop_front_aux();
992
993 protected:                        // Internal insert functions
994
995   template <class _InputIterator>
996   void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
997               input_iterator_tag);
998
999   template <class _ForwardIterator>
1000   void insert(iterator __pos,
1001               _ForwardIterator __first, _ForwardIterator __last,
1002               forward_iterator_tag);
1003
1004   iterator _M_insert_aux(iterator __pos, const value_type& __x);
1005   iterator _M_insert_aux(iterator __pos);
1006   void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
1007
1008   template <class _ForwardIterator>
1009   void _M_insert_aux(iterator __pos, 
1010                      _ForwardIterator __first, _ForwardIterator __last,
1011                      size_type __n);
1012
1013   iterator _M_reserve_elements_at_front(size_type __n) {
1014     size_type __vacancies = _M_start._M_cur - _M_start._M_first;
1015     if (__n > __vacancies) 
1016       _M_new_elements_at_front(__n - __vacancies);
1017     return _M_start - difference_type(__n);
1018   }
1019
1020   iterator _M_reserve_elements_at_back(size_type __n) {
1021     size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
1022     if (__n > __vacancies)
1023       _M_new_elements_at_back(__n - __vacancies);
1024     return _M_finish + difference_type(__n);
1025   }
1026
1027   void _M_new_elements_at_front(size_type __new_elements);
1028   void _M_new_elements_at_back(size_type __new_elements);
1029
1030 protected:                      // Allocation of _M_map and nodes
1031
1032   // Makes sure the _M_map has space for new nodes.  Does not actually
1033   //  add the nodes.  Can invalidate _M_map pointers.  (And consequently, 
1034   //  deque iterators.)
1035
1036   void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
1037     if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
1038       _M_reallocate_map(__nodes_to_add, false);
1039   }
1040
1041   void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
1042     if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
1043       _M_reallocate_map(__nodes_to_add, true);
1044   }
1045
1046   void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
1047 };
1048
1049 // Non-inline member functions
1050
1051 template <class _Tp, class _Alloc>
1052 template <class _InputIter>
1053 void deque<_Tp, _Alloc>
1054   ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
1055 {
1056   iterator __cur = begin();
1057   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
1058     *__cur = *__first;
1059   if (__first == __last)
1060     erase(__cur, end());
1061   else
1062     insert(end(), __first, __last);
1063 }
1064
1065 template <class _Tp, class _Alloc>
1066 void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
1067                                         size_type __n, const value_type& __x)
1068 {
1069   if (__pos._M_cur == _M_start._M_cur) {
1070     iterator __new_start = _M_reserve_elements_at_front(__n);
1071     try {
1072       uninitialized_fill(__new_start, _M_start, __x);
1073       _M_start = __new_start;
1074     }
1075     catch(...)
1076       {
1077         _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
1078         __throw_exception_again;
1079       }
1080   }
1081   else if (__pos._M_cur == _M_finish._M_cur) {
1082     iterator __new_finish = _M_reserve_elements_at_back(__n);
1083     try {
1084       uninitialized_fill(_M_finish, __new_finish, __x);
1085       _M_finish = __new_finish;
1086     }
1087     catch(...)
1088       {
1089         _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);    
1090         __throw_exception_again;
1091       }
1092   }
1093   else 
1094     _M_insert_aux(__pos, __n, __x);
1095 }
1096
1097 template <class _Tp, class _Alloc>
1098 typename deque<_Tp,_Alloc>::iterator 
1099 deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
1100 {
1101   if (__first == _M_start && __last == _M_finish) {
1102     clear();
1103     return _M_finish;
1104   }
1105   else {
1106     difference_type __n = __last - __first;
1107     difference_type __elems_before = __first - _M_start;
1108     if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) {
1109       copy_backward(_M_start, __first, __last);
1110       iterator __new_start = _M_start + __n;
1111       _Destroy(_M_start, __new_start);
1112       _M_destroy_nodes(_M_start._M_node, __new_start._M_node);
1113       _M_start = __new_start;
1114     }
1115     else {
1116       copy(__last, _M_finish, __first);
1117       iterator __new_finish = _M_finish - __n;
1118       _Destroy(__new_finish, _M_finish);
1119       _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
1120       _M_finish = __new_finish;
1121     }
1122     return _M_start + __elems_before;
1123   }
1124 }
1125
1126 template <class _Tp, class _Alloc> 
1127 void deque<_Tp,_Alloc>::clear()
1128 {
1129   for (_Map_pointer __node = _M_start._M_node + 1;
1130        __node < _M_finish._M_node;
1131        ++__node) {
1132     _Destroy(*__node, *__node + _S_buffer_size());
1133     _M_deallocate_node(*__node);
1134   }
1135
1136   if (_M_start._M_node != _M_finish._M_node) {
1137     _Destroy(_M_start._M_cur, _M_start._M_last);
1138     _Destroy(_M_finish._M_first, _M_finish._M_cur);
1139     _M_deallocate_node(_M_finish._M_first);
1140   }
1141   else
1142     _Destroy(_M_start._M_cur, _M_finish._M_cur);
1143
1144   _M_finish = _M_start;
1145 }
1146
1147 /**
1148  *  @if maint
1149  *  @brief Fills the deque with copies of value.
1150  *  @param  value  Initial value.
1151  *  @return   Nothing.
1152  *  @pre _M_start and _M_finish have already been initialized, but none of the
1153  *       deque's elements have yet been constructed.
1154  *
1155  *  This function is called only when the user provides an explicit size (with
1156  *  or without an explicit exemplar value).
1157  *  @endif
1158 */
1159 template <class _Tp, class _Alloc>
1160 void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
1161 {
1162   _Map_pointer __cur;
1163   try {
1164     for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
1165       uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
1166     uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
1167   }
1168   catch(...)
1169     {
1170       _Destroy(_M_start, iterator(*__cur, __cur));
1171       __throw_exception_again;
1172     }
1173 }
1174
1175 /** @{
1176  *  @if maint
1177  *  @brief Fills the deque with whatever is in [first,last).
1178  *  @param  first  An input iterator.
1179  *  @param  last  An input iterator.
1180  *  @return   Nothing.
1181  *
1182  *  If the iterators are actually forward iterators (or better), then the
1183  *  memory layout can be done all at once.  Else we move forward using
1184  *  push_back on each value from the iterator.
1185  *  @endif
1186 */
1187 template <class _Tp, class _Alloc> template <class _InputIterator>
1188 void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
1189                                             _InputIterator __last,
1190                                             input_iterator_tag)
1191 {
1192   _M_initialize_map(0);
1193   try {
1194     for ( ; __first != __last; ++__first)
1195       push_back(*__first);
1196   }
1197   catch(...)
1198     {
1199       clear();
1200       __throw_exception_again;
1201     }
1202 }
1203
1204 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1205 void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
1206                                             _ForwardIterator __last,
1207                                             forward_iterator_tag)
1208 {
1209   size_type __n = distance(__first, __last);
1210   _M_initialize_map(__n);
1211
1212   _Map_pointer __cur_node;
1213   try {
1214     for (__cur_node = _M_start._M_node; 
1215          __cur_node < _M_finish._M_node; 
1216          ++__cur_node) {
1217       _ForwardIterator __mid = __first;
1218       advance(__mid, _S_buffer_size());
1219       uninitialized_copy(__first, __mid, *__cur_node);
1220       __first = __mid;
1221     }
1222     uninitialized_copy(__first, __last, _M_finish._M_first);
1223   }
1224   catch(...)
1225     {
1226       _Destroy(_M_start, iterator(*__cur_node, __cur_node));
1227       __throw_exception_again;
1228     }
1229 }
1230 /** @} */
1231
1232 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
1233 template <class _Tp, class _Alloc>
1234 void
1235 deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
1236 {
1237   value_type __t_copy = __t;
1238   _M_reserve_map_at_back();
1239   *(_M_finish._M_node + 1) = _M_allocate_node();
1240   try {
1241     _Construct(_M_finish._M_cur, __t_copy);
1242     _M_finish._M_set_node(_M_finish._M_node + 1);
1243     _M_finish._M_cur = _M_finish._M_first;
1244   }
1245   catch(...)
1246     {
1247       _M_deallocate_node(*(_M_finish._M_node + 1));
1248       __throw_exception_again;
1249     }
1250 }
1251
1252 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
1253 template <class _Tp, class _Alloc>
1254 void
1255 deque<_Tp,_Alloc>::_M_push_back_aux()
1256 {
1257   _M_reserve_map_at_back();
1258   *(_M_finish._M_node + 1) = _M_allocate_node();
1259   try {
1260     _Construct(_M_finish._M_cur);
1261     _M_finish._M_set_node(_M_finish._M_node + 1);
1262     _M_finish._M_cur = _M_finish._M_first;
1263   }
1264   catch(...)
1265     {
1266       _M_deallocate_node(*(_M_finish._M_node + 1));
1267       __throw_exception_again;
1268     }
1269 }
1270
1271 // Called only if _M_start._M_cur == _M_start._M_first.
1272 template <class _Tp, class _Alloc>
1273 void
1274 deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
1275 {
1276   value_type __t_copy = __t;
1277   _M_reserve_map_at_front();
1278   *(_M_start._M_node - 1) = _M_allocate_node();
1279   try {
1280     _M_start._M_set_node(_M_start._M_node - 1);
1281     _M_start._M_cur = _M_start._M_last - 1;
1282     _Construct(_M_start._M_cur, __t_copy);
1283   }
1284   catch(...)
1285     {
1286       ++_M_start;
1287       _M_deallocate_node(*(_M_start._M_node - 1));
1288       __throw_exception_again;
1289     }
1290
1291
1292 // Called only if _M_start._M_cur == _M_start._M_first.
1293 template <class _Tp, class _Alloc>
1294 void
1295 deque<_Tp,_Alloc>::_M_push_front_aux()
1296 {
1297   _M_reserve_map_at_front();
1298   *(_M_start._M_node - 1) = _M_allocate_node();
1299   try {
1300     _M_start._M_set_node(_M_start._M_node - 1);
1301     _M_start._M_cur = _M_start._M_last - 1;
1302     _Construct(_M_start._M_cur);
1303   }
1304   catch(...)
1305     {
1306       ++_M_start;
1307       _M_deallocate_node(*(_M_start._M_node - 1));
1308       __throw_exception_again;
1309     }
1310
1311
1312 // Called only if _M_finish._M_cur == _M_finish._M_first.
1313 template <class _Tp, class _Alloc>
1314 void deque<_Tp,_Alloc>::_M_pop_back_aux()
1315 {
1316   _M_deallocate_node(_M_finish._M_first);
1317   _M_finish._M_set_node(_M_finish._M_node - 1);
1318   _M_finish._M_cur = _M_finish._M_last - 1;
1319   _Destroy(_M_finish._M_cur);
1320 }
1321
1322 // Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
1323 // if the deque has at least one element (a precondition for this member 
1324 // function), and if _M_start._M_cur == _M_start._M_last, then the deque 
1325 // must have at least two nodes.
1326 template <class _Tp, class _Alloc>
1327 void deque<_Tp,_Alloc>::_M_pop_front_aux()
1328 {
1329   _Destroy(_M_start._M_cur);
1330   _M_deallocate_node(_M_start._M_first);
1331   _M_start._M_set_node(_M_start._M_node + 1);
1332   _M_start._M_cur = _M_start._M_first;
1333 }      
1334
1335 template <class _Tp, class _Alloc> template <class _InputIterator>
1336 void deque<_Tp,_Alloc>::insert(iterator __pos,
1337                                _InputIterator __first, _InputIterator __last,
1338                                input_iterator_tag)
1339 {
1340   copy(__first, __last, inserter(*this, __pos));
1341 }
1342
1343 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1344 void
1345 deque<_Tp,_Alloc>::insert(iterator __pos,
1346                           _ForwardIterator __first, _ForwardIterator __last,
1347                           forward_iterator_tag) {
1348   size_type __n = distance(__first, __last);
1349   if (__pos._M_cur == _M_start._M_cur) {
1350     iterator __new_start = _M_reserve_elements_at_front(__n);
1351     try {
1352       uninitialized_copy(__first, __last, __new_start);
1353       _M_start = __new_start;
1354     }
1355     catch(...)
1356       {
1357         _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
1358         __throw_exception_again;
1359       }
1360   }
1361   else if (__pos._M_cur == _M_finish._M_cur) {
1362     iterator __new_finish = _M_reserve_elements_at_back(__n);
1363     try {
1364       uninitialized_copy(__first, __last, _M_finish);
1365       _M_finish = __new_finish;
1366     }
1367     catch(...)
1368       {
1369         _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
1370         __throw_exception_again;
1371       }
1372   }
1373   else
1374     _M_insert_aux(__pos, __first, __last, __n);
1375 }
1376
1377 template <class _Tp, class _Alloc>
1378 typename deque<_Tp, _Alloc>::iterator
1379 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
1380 {
1381   difference_type __index = __pos - _M_start;
1382   value_type __x_copy = __x;
1383   if (static_cast<size_type>(__index) < size() / 2) {
1384     push_front(front());
1385     iterator __front1 = _M_start;
1386     ++__front1;
1387     iterator __front2 = __front1;
1388     ++__front2;
1389     __pos = _M_start + __index;
1390     iterator __pos1 = __pos;
1391     ++__pos1;
1392     copy(__front2, __pos1, __front1);
1393   }
1394   else {
1395     push_back(back());
1396     iterator __back1 = _M_finish;
1397     --__back1;
1398     iterator __back2 = __back1;
1399     --__back2;
1400     __pos = _M_start + __index;
1401     copy_backward(__pos, __back2, __back1);
1402   }
1403   *__pos = __x_copy;
1404   return __pos;
1405 }
1406
1407 template <class _Tp, class _Alloc>
1408 typename deque<_Tp,_Alloc>::iterator 
1409 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
1410 {
1411   difference_type __index = __pos - _M_start;
1412   if (static_cast<size_type>(__index) < size() / 2) {
1413     push_front(front());
1414     iterator __front1 = _M_start;
1415     ++__front1;
1416     iterator __front2 = __front1;
1417     ++__front2;
1418     __pos = _M_start + __index;
1419     iterator __pos1 = __pos;
1420     ++__pos1;
1421     copy(__front2, __pos1, __front1);
1422   }
1423   else {
1424     push_back(back());
1425     iterator __back1 = _M_finish;
1426     --__back1;
1427     iterator __back2 = __back1;
1428     --__back2;
1429     __pos = _M_start + __index;
1430     copy_backward(__pos, __back2, __back1);
1431   }
1432   *__pos = value_type();
1433   return __pos;
1434 }
1435
1436 template <class _Tp, class _Alloc>
1437 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
1438                                       size_type __n,
1439                                       const value_type& __x)
1440 {
1441   const difference_type __elems_before = __pos - _M_start;
1442   size_type __length = this->size();
1443   value_type __x_copy = __x;
1444   if (__elems_before < difference_type(__length / 2)) {
1445     iterator __new_start = _M_reserve_elements_at_front(__n);
1446     iterator __old_start = _M_start;
1447     __pos = _M_start + __elems_before;
1448     try {
1449       if (__elems_before >= difference_type(__n)) {
1450         iterator __start_n = _M_start + difference_type(__n);
1451         uninitialized_copy(_M_start, __start_n, __new_start);
1452         _M_start = __new_start;
1453         copy(__start_n, __pos, __old_start);
1454         fill(__pos - difference_type(__n), __pos, __x_copy);
1455       }
1456       else {
1457         __uninitialized_copy_fill(_M_start, __pos, __new_start, 
1458                                   _M_start, __x_copy);
1459         _M_start = __new_start;
1460         fill(__old_start, __pos, __x_copy);
1461       }
1462     }
1463     catch(...)
1464       { 
1465         _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
1466         __throw_exception_again;
1467       }
1468   }
1469   else {
1470     iterator __new_finish = _M_reserve_elements_at_back(__n);
1471     iterator __old_finish = _M_finish;
1472     const difference_type __elems_after = 
1473       difference_type(__length) - __elems_before;
1474     __pos = _M_finish - __elems_after;
1475     try {
1476       if (__elems_after > difference_type(__n)) {
1477         iterator __finish_n = _M_finish - difference_type(__n);
1478         uninitialized_copy(__finish_n, _M_finish, _M_finish);
1479         _M_finish = __new_finish;
1480         copy_backward(__pos, __finish_n, __old_finish);
1481         fill(__pos, __pos + difference_type(__n), __x_copy);
1482       }
1483       else {
1484         __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
1485                                   __x_copy, __pos, _M_finish);
1486         _M_finish = __new_finish;
1487         fill(__pos, __old_finish, __x_copy);
1488       }
1489     }
1490     catch(...)
1491       { 
1492         _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
1493         __throw_exception_again;
1494       }
1495   }
1496 }
1497
1498 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1499 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
1500                                       _ForwardIterator __first,
1501                                       _ForwardIterator __last,
1502                                       size_type __n)
1503 {
1504   const difference_type __elemsbefore = __pos - _M_start;
1505   size_type __length = size();
1506   if (static_cast<size_type>(__elemsbefore) < __length / 2) {
1507     iterator __new_start = _M_reserve_elements_at_front(__n);
1508     iterator __old_start = _M_start;
1509     __pos = _M_start + __elemsbefore;
1510     try {
1511       if (__elemsbefore >= difference_type(__n)) {
1512         iterator __start_n = _M_start + difference_type(__n); 
1513         uninitialized_copy(_M_start, __start_n, __new_start);
1514         _M_start = __new_start;
1515         copy(__start_n, __pos, __old_start);
1516         copy(__first, __last, __pos - difference_type(__n));
1517       }
1518       else {
1519         _ForwardIterator __mid = __first;
1520         advance(__mid, difference_type(__n) - __elemsbefore);
1521         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1522                                   __new_start);
1523         _M_start = __new_start;
1524         copy(__mid, __last, __old_start);
1525       }
1526     }
1527     catch(...)
1528       {
1529         _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
1530         __throw_exception_again;
1531       }
1532   }
1533   else {
1534     iterator __new_finish = _M_reserve_elements_at_back(__n);
1535     iterator __old_finish = _M_finish;
1536     const difference_type __elemsafter = 
1537       difference_type(__length) - __elemsbefore;
1538     __pos = _M_finish - __elemsafter;
1539     try {
1540       if (__elemsafter > difference_type(__n)) {
1541         iterator __finish_n = _M_finish - difference_type(__n);
1542         uninitialized_copy(__finish_n, _M_finish, _M_finish);
1543         _M_finish = __new_finish;
1544         copy_backward(__pos, __finish_n, __old_finish);
1545         copy(__first, __last, __pos);
1546       }
1547       else {
1548         _ForwardIterator __mid = __first;
1549         advance(__mid, __elemsafter);
1550         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1551         _M_finish = __new_finish;
1552         copy(__first, __mid, __pos);
1553       }
1554     }
1555     catch(...)
1556       {
1557         _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
1558         __throw_exception_again;
1559       }
1560   }
1561 }
1562
1563 template <class _Tp, class _Alloc>
1564 void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
1565 {
1566   size_type __new_nodes
1567       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
1568   _M_reserve_map_at_front(__new_nodes);
1569   size_type __i;
1570   try {
1571     for (__i = 1; __i <= __new_nodes; ++__i)
1572       *(_M_start._M_node - __i) = _M_allocate_node();
1573   }
1574   catch(...) {
1575     for (size_type __j = 1; __j < __i; ++__j)
1576       _M_deallocate_node(*(_M_start._M_node - __j));      
1577     __throw_exception_again;
1578   }
1579 }
1580
1581 template <class _Tp, class _Alloc>
1582 void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
1583 {
1584   size_type __new_nodes
1585       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
1586   _M_reserve_map_at_back(__new_nodes);
1587   size_type __i;
1588   try {
1589     for (__i = 1; __i <= __new_nodes; ++__i)
1590       *(_M_finish._M_node + __i) = _M_allocate_node();
1591   }
1592   catch(...) {
1593     for (size_type __j = 1; __j < __i; ++__j)
1594       _M_deallocate_node(*(_M_finish._M_node + __j));      
1595     __throw_exception_again;
1596   }
1597 }
1598
1599 template <class _Tp, class _Alloc>
1600 void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
1601                                           bool __add_at_front)
1602 {
1603   size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
1604   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
1605
1606   _Map_pointer __new_nstart;
1607   if (_M_map_size > 2 * __new_num_nodes) {
1608     __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
1609                      + (__add_at_front ? __nodes_to_add : 0);
1610     if (__new_nstart < _M_start._M_node)
1611       copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
1612     else
1613       copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
1614                     __new_nstart + __old_num_nodes);
1615   }
1616   else {
1617     size_type __new_map_size = 
1618       _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
1619
1620     _Map_pointer __new_map = _M_allocate_map(__new_map_size);
1621     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
1622                          + (__add_at_front ? __nodes_to_add : 0);
1623     copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
1624     _M_deallocate_map(_M_map, _M_map_size);
1625
1626     _M_map = __new_map;
1627     _M_map_size = __new_map_size;
1628   }
1629
1630   _M_start._M_set_node(__new_nstart);
1631   _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
1632 }
1633
1634
1635 // Nonmember functions.
1636
1637 template <class _Tp, class _Alloc>
1638 inline bool operator==(const deque<_Tp, _Alloc>& __x,
1639                        const deque<_Tp, _Alloc>& __y) {
1640   return __x.size() == __y.size() &&
1641          equal(__x.begin(), __x.end(), __y.begin());
1642 }
1643
1644 template <class _Tp, class _Alloc>
1645 inline bool operator<(const deque<_Tp, _Alloc>& __x,
1646                       const deque<_Tp, _Alloc>& __y) {
1647   return lexicographical_compare(__x.begin(), __x.end(), 
1648                                  __y.begin(), __y.end());
1649 }
1650
1651 template <class _Tp, class _Alloc>
1652 inline bool operator!=(const deque<_Tp, _Alloc>& __x,
1653                        const deque<_Tp, _Alloc>& __y) {
1654   return !(__x == __y);
1655 }
1656
1657 template <class _Tp, class _Alloc>
1658 inline bool operator>(const deque<_Tp, _Alloc>& __x,
1659                       const deque<_Tp, _Alloc>& __y) {
1660   return __y < __x;
1661 }
1662
1663 template <class _Tp, class _Alloc>
1664 inline bool operator<=(const deque<_Tp, _Alloc>& __x,
1665                        const deque<_Tp, _Alloc>& __y) {
1666   return !(__y < __x);
1667 }
1668 template <class _Tp, class _Alloc>
1669 inline bool operator>=(const deque<_Tp, _Alloc>& __x,
1670                        const deque<_Tp, _Alloc>& __y) {
1671   return !(__x < __y);
1672 }
1673
1674 template <class _Tp, class _Alloc>
1675 inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
1676   __x.swap(__y);
1677 }
1678
1679 } // namespace std 
1680   
1681 #endif /* __GLIBCPP_INTERNAL_DEQUE_H */
1682