Whole document tree
    

Whole document tree

stl_deque.h Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

stl_deque.h

Go to the documentation of this file.
00001 // deque implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /*
00031  *
00032  * Copyright (c) 1994
00033  * Hewlett-Packard Company
00034  *
00035  * Permission to use, copy, modify, distribute and sell this software
00036  * and its documentation for any purpose is hereby granted without fee,
00037  * provided that the above copyright notice appear in all copies and
00038  * that both that copyright notice and this permission notice appear
00039  * in supporting documentation.  Hewlett-Packard Company makes no
00040  * representations about the suitability of this software for any
00041  * purpose.  It is provided "as is" without express or implied warranty.
00042  *
00043  *
00044  * Copyright (c) 1997
00045  * Silicon Graphics Computer Systems, Inc.
00046  *
00047  * Permission to use, copy, modify, distribute and sell this software
00048  * and its documentation for any purpose is hereby granted without fee,
00049  * provided that the above copyright notice appear in all copies and
00050  * that both that copyright notice and this permission notice appear
00051  * in supporting documentation.  Silicon Graphics makes no
00052  * representations about the suitability of this software for any
00053  * purpose.  It is provided "as is" without express or implied warranty.
00054  */
00055 
00056 /* NOTE: This is an internal header file, included by other STL headers.
00057  *   You should not attempt to use it directly.
00058  */
00059 
00060 #include <bits/concept_check.h>
00061 #include <bits/stl_iterator_base_types.h>
00062 #include <bits/stl_iterator_base_funcs.h>
00063 
00064 #ifndef __SGI_STL_INTERNAL_DEQUE_H
00065 #define __SGI_STL_INTERNAL_DEQUE_H
00066 
00067 /* Class invariants:
00068  *  For any nonsingular iterator i:
00069  *    i.node is the address of an element in the map array.  The
00070  *      contents of i.node is a pointer to the beginning of a node.
00071  *    i.first == *(i.node) 
00072  *    i.last  == i.first + node_size
00073  *    i.cur is a pointer in the range [i.first, i.last).  NOTE:
00074  *      the implication of this is that i.cur is always a dereferenceable
00075  *      pointer, even if i is a past-the-end iterator.
00076  *  Start and Finish are always nonsingular iterators.  NOTE: this means
00077  *    that an empty deque must have one node, and that a deque
00078  *    with N elements, where N is the buffer size, must have two nodes.
00079  *  For every node other than start.node and finish.node, every element
00080  *    in the node is an initialized object.  If start.node == finish.node,
00081  *    then [start.cur, finish.cur) are initialized objects, and
00082  *    the elements outside that range are uninitialized storage.  Otherwise,
00083  *    [start.cur, start.last) and [finish.first, finish.cur) are initialized
00084  *    objects, and [start.first, start.cur) and [finish.cur, finish.last)
00085  *    are uninitialized storage.
00086  *  [map, map + map_size) is a valid, non-empty range.  
00087  *  [start.node, finish.node] is a valid range contained within 
00088  *    [map, map + map_size).  
00089  *  A pointer in the range [map, map + map_size) points to an allocated node
00090  *    if and only if the pointer is in the range [start.node, finish.node].
00091  */
00092 
00093 
00094 /*
00095  * In previous versions of deque, there was an extra template 
00096  * parameter so users could control the node size.  This extension
00097  * turns out to violate the C++ standard (it can be detected using
00098  * template template parameters), and it has been removed.
00099  */
00100 
00101 namespace std
00102 { 
00103 
00104 // Note: this function is simply a kludge to work around several compilers'
00105 //  bugs in handling constant expressions.
00106 inline size_t __deque_buf_size(size_t __size) {
00107   return __size < 512 ? size_t(512 / __size) : size_t(1);
00108 }
00109 
00110 template <class _Tp, class _Ref, class _Ptr>
00111 struct _Deque_iterator {
00112   typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
00113   typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
00114   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
00115 
00116   typedef random_access_iterator_tag iterator_category;
00117   typedef _Tp value_type;
00118   typedef _Ptr pointer;
00119   typedef _Ref reference;
00120   typedef size_t size_type;
00121   typedef ptrdiff_t difference_type;
00122   typedef _Tp** _Map_pointer;
00123 
00124   typedef _Deque_iterator _Self;
00125 
00126   _Tp* _M_cur;
00127   _Tp* _M_first;
00128   _Tp* _M_last;
00129   _Map_pointer _M_node;
00130 
00131   _Deque_iterator(_Tp* __x, _Map_pointer __y) 
00132     : _M_cur(__x), _M_first(*__y),
00133       _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
00134   _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
00135   _Deque_iterator(const iterator& __x)
00136     : _M_cur(__x._M_cur), _M_first(__x._M_first), 
00137       _M_last(__x._M_last), _M_node(__x._M_node) {}
00138 
00139   reference operator*() const { return *_M_cur; }
00140   pointer operator->() const { return _M_cur; }
00141 
00142   difference_type operator-(const _Self& __x) const {
00143     return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
00144       (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
00145   }
00146 
00147   _Self& operator++() {
00148     ++_M_cur;
00149     if (_M_cur == _M_last) {
00150       _M_set_node(_M_node + 1);
00151       _M_cur = _M_first;
00152     }
00153     return *this; 
00154   }
00155   _Self operator++(int)  {
00156     _Self __tmp = *this;
00157     ++*this;
00158     return __tmp;
00159   }
00160 
00161   _Self& operator--() {
00162     if (_M_cur == _M_first) {
00163       _M_set_node(_M_node - 1);
00164       _M_cur = _M_last;
00165     }
00166     --_M_cur;
00167     return *this;
00168   }
00169   _Self operator--(int) {
00170     _Self __tmp = *this;
00171     --*this;
00172     return __tmp;
00173   }
00174 
00175   _Self& operator+=(difference_type __n)
00176   {
00177     difference_type __offset = __n + (_M_cur - _M_first);
00178     if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
00179       _M_cur += __n;
00180     else {
00181       difference_type __node_offset =
00182         __offset > 0 ? __offset / difference_type(_S_buffer_size())
00183                    : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
00184       _M_set_node(_M_node + __node_offset);
00185       _M_cur = _M_first + 
00186         (__offset - __node_offset * difference_type(_S_buffer_size()));
00187     }
00188     return *this;
00189   }
00190 
00191   _Self operator+(difference_type __n) const
00192   {
00193     _Self __tmp = *this;
00194     return __tmp += __n;
00195   }
00196 
00197   _Self& operator-=(difference_type __n) { return *this += -__n; }
00198  
00199   _Self operator-(difference_type __n) const {
00200     _Self __tmp = *this;
00201     return __tmp -= __n;
00202   }
00203 
00204   reference operator[](difference_type __n) const { return *(*this + __n); }
00205 
00206   bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
00207   bool operator!=(const _Self& __x) const { return !(*this == __x); }
00208   bool operator<(const _Self& __x) const {
00209     return (_M_node == __x._M_node) ? 
00210       (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
00211   }
00212   bool operator>(const _Self& __x) const  { return __x < *this; }
00213   bool operator<=(const _Self& __x) const { return !(__x < *this); }
00214   bool operator>=(const _Self& __x) const { return !(*this < __x); }
00215 
00216   void _M_set_node(_Map_pointer __new_node) {
00217     _M_node = __new_node;
00218     _M_first = *__new_node;
00219     _M_last = _M_first + difference_type(_S_buffer_size());
00220   }
00221 };
00222 
00223 template <class _Tp, class _Ref, class _Ptr>
00224 inline _Deque_iterator<_Tp, _Ref, _Ptr>
00225 operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
00226 {
00227   return __x + __n;
00228 }
00229 
00230 
00231 // Deque base class.  It has two purposes.  First, its constructor
00232 //  and destructor allocate (but don't initialize) storage.  This makes
00233 //  exception safety easier.  Second, the base class encapsulates all of
00234 //  the differences between SGI-style allocators and standard-conforming
00235 //  allocators.
00236 
00237 // Base class for ordinary allocators.
00238 template <class _Tp, class _Alloc, bool __is_static>
00239 class _Deque_alloc_base {
00240 public:
00241   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00242   allocator_type get_allocator() const { return _M_node_allocator; }
00243 
00244   _Deque_alloc_base(const allocator_type& __a)
00245     : _M_node_allocator(__a), _M_map_allocator(__a),
00246       _M_map(0), _M_map_size(0)
00247   {}
00248   
00249 protected:
00250   typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
00251           _Map_allocator_type;
00252 
00253   allocator_type      _M_node_allocator;
00254   _Map_allocator_type _M_map_allocator;
00255 
00256   _Tp* _M_allocate_node() {
00257     return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
00258   }
00259   void _M_deallocate_node(_Tp* __p) {
00260     _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
00261   }
00262   _Tp** _M_allocate_map(size_t __n) 
00263     { return _M_map_allocator.allocate(__n); }
00264   void _M_deallocate_map(_Tp** __p, size_t __n) 
00265     { _M_map_allocator.deallocate(__p, __n); }
00266 
00267   _Tp** _M_map;
00268   size_t _M_map_size;
00269 };
00270 
00271 // Specialization for instanceless allocators.
00272 template <class _Tp, class _Alloc>
00273 class _Deque_alloc_base<_Tp, _Alloc, true>
00274 {
00275 public:
00276   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00277   allocator_type get_allocator() const { return allocator_type(); }
00278 
00279   _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
00280   
00281 protected:
00282   typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
00283   typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
00284 
00285   _Tp* _M_allocate_node() {
00286     return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
00287   }
00288   void _M_deallocate_node(_Tp* __p) {
00289     _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
00290   }
00291   _Tp** _M_allocate_map(size_t __n) 
00292     { return _Map_alloc_type::allocate(__n); }
00293   void _M_deallocate_map(_Tp** __p, size_t __n) 
00294     { _Map_alloc_type::deallocate(__p, __n); }
00295 
00296   _Tp** _M_map;
00297   size_t _M_map_size;
00298 };
00299 
00300 template <class _Tp, class _Alloc>
00301 class _Deque_base
00302   : public _Deque_alloc_base<_Tp,_Alloc,
00303                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00304 {
00305 public:
00306   typedef _Deque_alloc_base<_Tp,_Alloc,
00307                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00308           _Base;
00309   typedef typename _Base::allocator_type allocator_type;
00310   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
00311   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00312 
00313   _Deque_base(const allocator_type& __a, size_t __num_elements)
00314     : _Base(__a), _M_start(), _M_finish()
00315     { _M_initialize_map(__num_elements); }
00316   _Deque_base(const allocator_type& __a) 
00317     : _Base(__a), _M_start(), _M_finish() {}
00318   ~_Deque_base();    
00319 
00320 protected:
00321   void _M_initialize_map(size_t);
00322   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
00323   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
00324   enum { _S_initial_map_size = 8 };
00325 
00326 protected:
00327   iterator _M_start;
00328   iterator _M_finish;
00329 };
00330 
00331 // Non-inline member functions from _Deque_base.
00332 
00333 template <class _Tp, class _Alloc>
00334 _Deque_base<_Tp,_Alloc>::~_Deque_base() {
00335   if (_M_map) {
00336     _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
00337     _M_deallocate_map(_M_map, _M_map_size);
00338   }
00339 }
00340 
00341 template <class _Tp, class _Alloc>
00342 void
00343 _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
00344 {
00345   size_t __num_nodes = 
00346     __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
00347 
00348   _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
00349   _M_map = _M_allocate_map(_M_map_size);
00350 
00351   _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
00352   _Tp** __nfinish = __nstart + __num_nodes;
00353     
00354   __STL_TRY {
00355     _M_create_nodes(__nstart, __nfinish);
00356   }
00357   __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), 
00358                 _M_map = 0, _M_map_size = 0));
00359   _M_start._M_set_node(__nstart);
00360   _M_finish._M_set_node(__nfinish - 1);
00361   _M_start._M_cur = _M_start._M_first;
00362   _M_finish._M_cur = _M_finish._M_first +
00363                __num_elements % __deque_buf_size(sizeof(_Tp));
00364 }
00365 
00366 template <class _Tp, class _Alloc>
00367 void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
00368 {
00369   _Tp** __cur;
00370   __STL_TRY {
00371     for (__cur = __nstart; __cur < __nfinish; ++__cur)
00372       *__cur = _M_allocate_node();
00373   }
00374   __STL_UNWIND(_M_destroy_nodes(__nstart, __cur));
00375 }
00376 
00377 template <class _Tp, class _Alloc>
00378 void
00379 _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
00380 {
00381   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
00382     _M_deallocate_node(*__n);
00383 }
00384 
00385 template <class _Tp, class _Alloc = allocator<_Tp> >
00386 class deque : protected _Deque_base<_Tp, _Alloc> {
00387 
00388   // concept requirements
00389   __glibcpp_class_requires(_Tp, _SGIAssignableConcept);
00390 
00391   typedef _Deque_base<_Tp, _Alloc> _Base;
00392 public:                         // Basic types
00393   typedef _Tp value_type;
00394   typedef value_type* pointer;
00395   typedef const value_type* const_pointer;
00396   typedef value_type& reference;
00397   typedef const value_type& const_reference;
00398   typedef size_t size_type;
00399   typedef ptrdiff_t difference_type;
00400 
00401   typedef typename _Base::allocator_type allocator_type;
00402   allocator_type get_allocator() const { return _Base::get_allocator(); }
00403 
00404 public:                         // Iterators
00405   typedef typename _Base::iterator       iterator;
00406   typedef typename _Base::const_iterator const_iterator;
00407 
00408   typedef reverse_iterator<const_iterator> const_reverse_iterator;
00409   typedef reverse_iterator<iterator> reverse_iterator;
00410 
00411 protected:                      // Internal typedefs
00412   typedef pointer* _Map_pointer;
00413   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
00414 
00415 protected:
00416   using _Base::_M_initialize_map;
00417   using _Base::_M_create_nodes;
00418   using _Base::_M_destroy_nodes;
00419   using _Base::_M_allocate_node;
00420   using _Base::_M_deallocate_node;
00421   using _Base::_M_allocate_map;
00422   using _Base::_M_deallocate_map;
00423 
00424   using _Base::_M_map;
00425   using _Base::_M_map_size;
00426   using _Base::_M_start;
00427   using _Base::_M_finish;
00428 
00429 public:                         // Basic accessors
00430   iterator begin() { return _M_start; }
00431   iterator end() { return _M_finish; }
00432   const_iterator begin() const { return _M_start; }
00433   const_iterator end() const { return _M_finish; }
00434 
00435   reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
00436   reverse_iterator rend() { return reverse_iterator(_M_start); }
00437   const_reverse_iterator rbegin() const 
00438     { return const_reverse_iterator(_M_finish); }
00439   const_reverse_iterator rend() const 
00440     { return const_reverse_iterator(_M_start); }
00441 
00442   reference operator[](size_type __n)
00443     { return _M_start[difference_type(__n)]; }
00444   const_reference operator[](size_type __n) const 
00445     { return _M_start[difference_type(__n)]; }
00446 
00447   void _M_range_check(size_type __n) const {
00448     if (__n >= this->size())
00449       __throw_range_error("deque");
00450   }
00451 
00452   reference at(size_type __n)
00453     { _M_range_check(__n); return (*this)[__n]; }
00454   const_reference at(size_type __n) const
00455     { _M_range_check(__n); return (*this)[__n]; }
00456 
00457   reference front() { return *_M_start; }
00458   reference back() {
00459     iterator __tmp = _M_finish;
00460     --__tmp;
00461     return *__tmp;
00462   }
00463   const_reference front() const { return *_M_start; }
00464   const_reference back() const {
00465     const_iterator __tmp = _M_finish;
00466     --__tmp;
00467     return *__tmp;
00468   }
00469 
00470   size_type size() const { return _M_finish - _M_start; }
00471   size_type max_size() const { return size_type(-1); }
00472   bool empty() const { return _M_finish == _M_start; }
00473 
00474 public:                         // Constructor, destructor.
00475   explicit deque(const allocator_type& __a = allocator_type()) 
00476     : _Base(__a, 0) {}
00477   deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) 
00478     { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
00479   deque(size_type __n, const value_type& __value,
00480         const allocator_type& __a = allocator_type()) : _Base(__a, __n)
00481     { _M_fill_initialize(__value); }
00482   explicit deque(size_type __n) : _Base(allocator_type(), __n)
00483     { _M_fill_initialize(value_type()); }
00484 
00485   // Check whether it's an integral type.  If so, it's not an iterator.
00486   template <class _InputIterator>
00487   deque(_InputIterator __first, _InputIterator __last,
00488         const allocator_type& __a = allocator_type()) : _Base(__a) {
00489     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00490     _M_initialize_dispatch(__first, __last, _Integral());
00491   }
00492 
00493   template <class _Integer>
00494   void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
00495     _M_initialize_map(__n);
00496     _M_fill_initialize(__x);
00497   }
00498 
00499   template <class _InputIter>
00500   void _M_initialize_dispatch(_InputIter __first, _InputIter __last,
00501                               __false_type) {
00502     _M_range_initialize(__first, __last, __iterator_category(__first));
00503   }
00504 
00505   ~deque() { destroy(_M_start, _M_finish); }
00506 
00507   deque& operator= (const deque& __x) {
00508     const size_type __len = size();
00509     if (&__x != this) {
00510       if (__len >= __x.size())
00511         erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
00512       else {
00513         const_iterator __mid = __x.begin() + difference_type(__len);
00514         copy(__x.begin(), __mid, _M_start);
00515         insert(_M_finish, __mid, __x.end());
00516       }
00517     }
00518     return *this;
00519   }        
00520 
00521   void swap(deque& __x) {
00522     std::swap(_M_start, __x._M_start);
00523     std::swap(_M_finish, __x._M_finish);
00524     std::swap(_M_map, __x._M_map);
00525     std::swap(_M_map_size, __x._M_map_size);
00526   }
00527 
00528 public: 
00529   // assign(), a generalized assignment member function.  Two
00530   // versions: one that takes a count, and one that takes a range.
00531   // The range version is a member template, so we dispatch on whether
00532   // or not the type is an integer.
00533 
00534   void _M_fill_assign(size_type __n, const _Tp& __val) {
00535     if (__n > size()) {
00536       fill(begin(), end(), __val);
00537       insert(end(), __n - size(), __val);
00538     }
00539     else {
00540       erase(begin() + __n, end());
00541       fill(begin(), end(), __val);
00542     }
00543   }
00544 
00545   void assign(size_type __n, const _Tp& __val) {
00546     _M_fill_assign(__n, __val);
00547   }
00548 
00549   template <class _InputIterator>
00550   void assign(_InputIterator __first, _InputIterator __last) {
00551     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00552     _M_assign_dispatch(__first, __last, _Integral());
00553   }
00554 
00555 private:                        // helper functions for assign() 
00556 
00557   template <class _Integer>
00558   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00559     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00560 
00561   template <class _InputIterator>
00562   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00563                           __false_type) {
00564     _M_assign_aux(__first, __last, __iterator_category(__first));
00565   }
00566 
00567   template <class _InputIterator>
00568   void _M_assign_aux(_InputIterator __first, _InputIterator __last,
00569                      input_iterator_tag);
00570 
00571   template <class _ForwardIterator>
00572   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00573                      forward_iterator_tag) {
00574     size_type __len = 0;
00575     distance(__first, __last, __len);
00576     if (__len > size()) {
00577       _ForwardIterator __mid = __first;
00578       advance(__mid, size());
00579       copy(__first, __mid, begin());
00580       insert(end(), __mid, __last);
00581     }
00582     else
00583       erase(copy(__first, __last, begin()), end());
00584   }
00585 
00586 public:                         // push_* and pop_*
00587   
00588   void push_back(const value_type& __t) {
00589     if (_M_finish._M_cur != _M_finish._M_last - 1) {
00590       construct(_M_finish._M_cur, __t);
00591       ++_M_finish._M_cur;
00592     }
00593     else
00594       _M_push_back_aux(__t);
00595   }
00596 
00597   void push_back() {
00598     if (_M_finish._M_cur != _M_finish._M_last - 1) {
00599       construct(_M_finish._M_cur);
00600       ++_M_finish._M_cur;
00601     }
00602     else
00603       _M_push_back_aux();
00604   }
00605 
00606   void push_front(const value_type& __t) {
00607     if (_M_start._M_cur != _M_start._M_first) {
00608       construct(_M_start._M_cur - 1, __t);
00609       --_M_start._M_cur;
00610     }
00611     else
00612       _M_push_front_aux(__t);
00613   }
00614 
00615   void push_front() {
00616     if (_M_start._M_cur != _M_start._M_first) {
00617       construct(_M_start._M_cur - 1);
00618       --_M_start._M_cur;
00619     }
00620     else
00621       _M_push_front_aux();
00622   }
00623 
00624 
00625   void pop_back() {
00626     if (_M_finish._M_cur != _M_finish._M_first) {
00627       --_M_finish._M_cur;
00628       destroy(_M_finish._M_cur);
00629     }
00630     else
00631       _M_pop_back_aux();
00632   }
00633 
00634   void pop_front() {
00635     if (_M_start._M_cur != _M_start._M_last - 1) {
00636       destroy(_M_start._M_cur);
00637       ++_M_start._M_cur;
00638     }
00639     else 
00640       _M_pop_front_aux();
00641   }
00642 
00643 public:                         // Insert
00644 
00645   iterator insert(iterator position, const value_type& __x) {
00646     if (position._M_cur == _M_start._M_cur) {
00647       push_front(__x);
00648       return _M_start;
00649     }
00650     else if (position._M_cur == _M_finish._M_cur) {
00651       push_back(__x);
00652       iterator __tmp = _M_finish;
00653       --__tmp;
00654       return __tmp;
00655     }
00656     else {
00657       return _M_insert_aux(position, __x);
00658     }
00659   }
00660 
00661   iterator insert(iterator __position)
00662     { return insert(__position, value_type()); }
00663 
00664   void insert(iterator __pos, size_type __n, const value_type& __x)
00665     { _M_fill_insert(__pos, __n, __x); }
00666 
00667   void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
00668 
00669   // Check whether it's an integral type.  If so, it's not an iterator.
00670   template <class _InputIterator>
00671   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00672     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00673     _M_insert_dispatch(__pos, __first, __last, _Integral());
00674   }
00675 
00676   template <class _Integer>
00677   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
00678                           __true_type) {
00679     _M_fill_insert(__pos, (size_type) __n, (value_type) __x);
00680   }
00681 
00682   template <class _InputIterator>
00683   void _M_insert_dispatch(iterator __pos,
00684                           _InputIterator __first, _InputIterator __last,
00685                           __false_type) {
00686     insert(__pos, __first, __last, __iterator_category(__first));
00687   }
00688 
00689   void resize(size_type __new_size, const value_type& __x) {
00690     const size_type __len = size();
00691     if (__new_size < __len) 
00692       erase(_M_start + __new_size, _M_finish);
00693     else
00694       insert(_M_finish, __new_size - __len, __x);
00695   }
00696 
00697   void resize(size_type new_size) { resize(new_size, value_type()); }
00698 
00699 public:                         // Erase
00700   iterator erase(iterator __pos) {
00701     iterator __next = __pos;
00702     ++__next;
00703     size_type __index = __pos - _M_start;
00704     if (__index < (size() >> 1)) {
00705       copy_backward(_M_start, __pos, __next);
00706       pop_front();
00707     }
00708     else {
00709       copy(__next, _M_finish, __pos);
00710       pop_back();
00711     }
00712     return _M_start + __index;
00713   }
00714 
00715   iterator erase(iterator __first, iterator __last);
00716   void clear(); 
00717 
00718 protected:                        // Internal construction/destruction
00719 
00720   void _M_fill_initialize(const value_type& __value);
00721 
00722   template <class _InputIterator>
00723   void _M_range_initialize(_InputIterator __first, _InputIterator __last,
00724                         input_iterator_tag);
00725 
00726   template <class _ForwardIterator>
00727   void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
00728                         forward_iterator_tag);
00729 
00730 protected:                        // Internal push_* and pop_*
00731 
00732   void _M_push_back_aux(const value_type&);
00733   void _M_push_back_aux();
00734   void _M_push_front_aux(const value_type&);
00735   void _M_push_front_aux();
00736   void _M_pop_back_aux();
00737   void _M_pop_front_aux();
00738 
00739 protected:                        // Internal insert functions
00740 
00741   template <class _InputIterator>
00742   void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
00743               input_iterator_tag);
00744 
00745   template <class _ForwardIterator>
00746   void insert(iterator __pos,
00747               _ForwardIterator __first, _ForwardIterator __last,
00748               forward_iterator_tag);
00749 
00750   iterator _M_insert_aux(iterator __pos, const value_type& __x);
00751   iterator _M_insert_aux(iterator __pos);
00752   void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
00753 
00754   template <class _ForwardIterator>
00755   void _M_insert_aux(iterator __pos, 
00756                      _ForwardIterator __first, _ForwardIterator __last,
00757                      size_type __n);
00758 
00759   iterator _M_reserve_elements_at_front(size_type __n) {
00760     size_type __vacancies = _M_start._M_cur - _M_start._M_first;
00761     if (__n > __vacancies) 
00762       _M_new_elements_at_front(__n - __vacancies);
00763     return _M_start - difference_type(__n);
00764   }
00765 
00766   iterator _M_reserve_elements_at_back(size_type __n) {
00767     size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
00768     if (__n > __vacancies)
00769       _M_new_elements_at_back(__n - __vacancies);
00770     return _M_finish + difference_type(__n);
00771   }
00772 
00773   void _M_new_elements_at_front(size_type __new_elements);
00774   void _M_new_elements_at_back(size_type __new_elements);
00775 
00776 protected:                      // Allocation of _M_map and nodes
00777 
00778   // Makes sure the _M_map has space for new nodes.  Does not actually
00779   //  add the nodes.  Can invalidate _M_map pointers.  (And consequently, 
00780   //  deque iterators.)
00781 
00782   void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
00783     if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
00784       _M_reallocate_map(__nodes_to_add, false);
00785   }
00786 
00787   void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
00788     if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
00789       _M_reallocate_map(__nodes_to_add, true);
00790   }
00791 
00792   void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
00793 };
00794 
00795 // Non-inline member functions
00796 
00797 template <class _Tp, class _Alloc>
00798 template <class _InputIter>
00799 void deque<_Tp, _Alloc>
00800   ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
00801 {
00802   iterator __cur = begin();
00803   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00804     *__cur = *__first;
00805   if (__first == __last)
00806     erase(__cur, end());
00807   else
00808     insert(end(), __first, __last);
00809 }
00810 
00811 template <class _Tp, class _Alloc>
00812 void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
00813                                         size_type __n, const value_type& __x)
00814 {
00815   if (__pos._M_cur == _M_start._M_cur) {
00816     iterator __new_start = _M_reserve_elements_at_front(__n);
00817     __STL_TRY {
00818       uninitialized_fill(__new_start, _M_start, __x);
00819       _M_start = __new_start;
00820     }
00821     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
00822   }
00823   else if (__pos._M_cur == _M_finish._M_cur) {
00824     iterator __new_finish = _M_reserve_elements_at_back(__n);
00825     __STL_TRY {
00826       uninitialized_fill(_M_finish, __new_finish, __x);
00827       _M_finish = __new_finish;
00828     }
00829     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
00830                                   __new_finish._M_node + 1));    
00831   }
00832   else 
00833     _M_insert_aux(__pos, __n, __x);
00834 }
00835 
00836 template <class _Tp, class _Alloc>
00837 typename deque<_Tp,_Alloc>::iterator 
00838 deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
00839 {
00840   if (__first == _M_start && __last == _M_finish) {
00841     clear();
00842     return _M_finish;
00843   }
00844   else {
00845     difference_type __n = __last - __first;
00846     difference_type __elems_before = __first - _M_start;
00847     if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) {
00848       copy_backward(_M_start, __first, __last);
00849       iterator __new_start = _M_start + __n;
00850       destroy(_M_start, __new_start);
00851       _M_destroy_nodes(_M_start._M_node, __new_start._M_node);
00852       _M_start = __new_start;
00853     }
00854     else {
00855       copy(__last, _M_finish, __first);
00856       iterator __new_finish = _M_finish - __n;
00857       destroy(__new_finish, _M_finish);
00858       _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
00859       _M_finish = __new_finish;
00860     }
00861     return _M_start + __elems_before;
00862   }
00863 }
00864 
00865 template <class _Tp, class _Alloc> 
00866 void deque<_Tp,_Alloc>::clear()
00867 {
00868   for (_Map_pointer __node = _M_start._M_node + 1;
00869        __node < _M_finish._M_node;
00870        ++__node) {
00871     destroy(*__node, *__node + _S_buffer_size());
00872     _M_deallocate_node(*__node);
00873   }
00874 
00875   if (_M_start._M_node != _M_finish._M_node) {
00876     destroy(_M_start._M_cur, _M_start._M_last);
00877     destroy(_M_finish._M_first, _M_finish._M_cur);
00878     _M_deallocate_node(_M_finish._M_first);
00879   }
00880   else
00881     destroy(_M_start._M_cur, _M_finish._M_cur);
00882 
00883   _M_finish = _M_start;
00884 }
00885 
00886 // Precondition: _M_start and _M_finish have already been initialized,
00887 // but none of the deque's elements have yet been constructed.
00888 template <class _Tp, class _Alloc>
00889 void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value) {
00890   _Map_pointer __cur;
00891   __STL_TRY {
00892     for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
00893       uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
00894     uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
00895   }
00896   __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur)));
00897 }
00898 
00899 template <class _Tp, class _Alloc> template <class _InputIterator>
00900 void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
00901                                             _InputIterator __last,
00902                                             input_iterator_tag)
00903 {
00904   _M_initialize_map(0);
00905   __STL_TRY {
00906     for ( ; __first != __last; ++__first)
00907       push_back(*__first);
00908   }
00909   __STL_UNWIND(clear());
00910 }
00911 
00912 template <class _Tp, class _Alloc> template <class _ForwardIterator>
00913 void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
00914                                             _ForwardIterator __last,
00915                                             forward_iterator_tag)
00916 {
00917   size_type __n = 0;
00918   distance(__first, __last, __n);
00919   _M_initialize_map(__n);
00920 
00921   _Map_pointer __cur_node;
00922   __STL_TRY {
00923     for (__cur_node = _M_start._M_node; 
00924          __cur_node < _M_finish._M_node; 
00925          ++__cur_node) {
00926       _ForwardIterator __mid = __first;
00927       advance(__mid, _S_buffer_size());
00928       uninitialized_copy(__first, __mid, *__cur_node);
00929       __first = __mid;
00930     }
00931     uninitialized_copy(__first, __last, _M_finish._M_first);
00932   }
00933   __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node)));
00934 }
00935 
00936 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
00937 template <class _Tp, class _Alloc>
00938 void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
00939 {
00940   value_type __t_copy = __t;
00941   _M_reserve_map_at_back();
00942   *(_M_finish._M_node + 1) = _M_allocate_node();
00943   __STL_TRY {
00944     construct(_M_finish._M_cur, __t_copy);
00945     _M_finish._M_set_node(_M_finish._M_node + 1);
00946     _M_finish._M_cur = _M_finish._M_first;
00947   }
00948   __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
00949 }
00950 
00951 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
00952 template <class _Tp, class _Alloc>
00953 void deque<_Tp,_Alloc>::_M_push_back_aux()
00954 {
00955   _M_reserve_map_at_back();
00956   *(_M_finish._M_node + 1) = _M_allocate_node();
00957   __STL_TRY {
00958     construct(_M_finish._M_cur);
00959     _M_finish._M_set_node(_M_finish._M_node + 1);
00960     _M_finish._M_cur = _M_finish._M_first;
00961   }
00962   __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
00963 }
00964 
00965 // Called only if _M_start._M_cur == _M_start._M_first.
00966 template <class _Tp, class _Alloc>
00967 void  deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
00968 {
00969   value_type __t_copy = __t;
00970   _M_reserve_map_at_front();
00971   *(_M_start._M_node - 1) = _M_allocate_node();
00972   __STL_TRY {
00973     _M_start._M_set_node(_M_start._M_node - 1);
00974     _M_start._M_cur = _M_start._M_last - 1;
00975     construct(_M_start._M_cur, __t_copy);
00976   }
00977   __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
00978 } 
00979 
00980 // Called only if _M_start._M_cur == _M_start._M_first.
00981 template <class _Tp, class _Alloc>
00982 void deque<_Tp,_Alloc>::_M_push_front_aux()
00983 {
00984   _M_reserve_map_at_front();
00985   *(_M_start._M_node - 1) = _M_allocate_node();
00986   __STL_TRY {
00987     _M_start._M_set_node(_M_start._M_node - 1);
00988     _M_start._M_cur = _M_start._M_last - 1;
00989     construct(_M_start._M_cur);
00990   }
00991   __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
00992 } 
00993 
00994 // Called only if _M_finish._M_cur == _M_finish._M_first.
00995 template <class _Tp, class _Alloc>
00996 void deque<_Tp,_Alloc>::_M_pop_back_aux()
00997 {
00998   _M_deallocate_node(_M_finish._M_first);
00999   _M_finish._M_set_node(_M_finish._M_node - 1);
01000   _M_finish._M_cur = _M_finish._M_last - 1;
01001   destroy(_M_finish._M_cur);
01002 }
01003 
01004 // Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
01005 // if the deque has at least one element (a precondition for this member 
01006 // function), and if _M_start._M_cur == _M_start._M_last, then the deque 
01007 // must have at least two nodes.
01008 template <class _Tp, class _Alloc>
01009 void deque<_Tp,_Alloc>::_M_pop_front_aux()
01010 {
01011   destroy(_M_start._M_cur);
01012   _M_deallocate_node(_M_start._M_first);
01013   _M_start._M_set_node(_M_start._M_node + 1);
01014   _M_start._M_cur = _M_start._M_first;
01015 }      
01016 
01017 template <class _Tp, class _Alloc> template <class _InputIterator>
01018 void deque<_Tp,_Alloc>::insert(iterator __pos,
01019                                _InputIterator __first, _InputIterator __last,
01020                                input_iterator_tag)
01021 {
01022   copy(__first, __last, inserter(*this, __pos));
01023 }
01024 
01025 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01026 void
01027 deque<_Tp,_Alloc>::insert(iterator __pos,
01028                           _ForwardIterator __first, _ForwardIterator __last,
01029                           forward_iterator_tag) {
01030   size_type __n = 0;
01031   distance(__first, __last, __n);
01032   if (__pos._M_cur == _M_start._M_cur) {
01033     iterator __new_start = _M_reserve_elements_at_front(__n);
01034     __STL_TRY {
01035       uninitialized_copy(__first, __last, __new_start);
01036       _M_start = __new_start;
01037     }
01038     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01039   }
01040   else if (__pos._M_cur == _M_finish._M_cur) {
01041     iterator __new_finish = _M_reserve_elements_at_back(__n);
01042     __STL_TRY {
01043       uninitialized_copy(__first, __last, _M_finish);
01044       _M_finish = __new_finish;
01045     }
01046     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01047                                   __new_finish._M_node + 1));
01048   }
01049   else
01050     _M_insert_aux(__pos, __first, __last, __n);
01051 }
01052 
01053 template <class _Tp, class _Alloc>
01054 typename deque<_Tp, _Alloc>::iterator
01055 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
01056 {
01057   difference_type __index = __pos - _M_start;
01058   value_type __x_copy = __x;
01059   if (static_cast<size_type>(__index) < size() / 2) {
01060     push_front(front());
01061     iterator __front1 = _M_start;
01062     ++__front1;
01063     iterator __front2 = __front1;
01064     ++__front2;
01065     __pos = _M_start + __index;
01066     iterator __pos1 = __pos;
01067     ++__pos1;
01068     copy(__front2, __pos1, __front1);
01069   }
01070   else {
01071     push_back(back());
01072     iterator __back1 = _M_finish;
01073     --__back1;
01074     iterator __back2 = __back1;
01075     --__back2;
01076     __pos = _M_start + __index;
01077     copy_backward(__pos, __back2, __back1);
01078   }
01079   *__pos = __x_copy;
01080   return __pos;
01081 }
01082 
01083 template <class _Tp, class _Alloc>
01084 typename deque<_Tp,_Alloc>::iterator 
01085 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
01086 {
01087   difference_type __index = __pos - _M_start;
01088   if (static_cast<size_type>(__index) < size() / 2) {
01089     push_front(front());
01090     iterator __front1 = _M_start;
01091     ++__front1;
01092     iterator __front2 = __front1;
01093     ++__front2;
01094     __pos = _M_start + __index;
01095     iterator __pos1 = __pos;
01096     ++__pos1;
01097     copy(__front2, __pos1, __front1);
01098   }
01099   else {
01100     push_back(back());
01101     iterator __back1 = _M_finish;
01102     --__back1;
01103     iterator __back2 = __back1;
01104     --__back2;
01105     __pos = _M_start + __index;
01106     copy_backward(__pos, __back2, __back1);
01107   }
01108   *__pos = value_type();
01109   return __pos;
01110 }
01111 
01112 template <class _Tp, class _Alloc>
01113 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01114                                       size_type __n,
01115                                       const value_type& __x)
01116 {
01117   const difference_type __elems_before = __pos - _M_start;
01118   size_type __length = this->size();
01119   value_type __x_copy = __x;
01120   if (__elems_before < difference_type(__length / 2)) {
01121     iterator __new_start = _M_reserve_elements_at_front(__n);
01122     iterator __old_start = _M_start;
01123     __pos = _M_start + __elems_before;
01124     __STL_TRY {
01125       if (__elems_before >= difference_type(__n)) {
01126         iterator __start_n = _M_start + difference_type(__n);
01127         uninitialized_copy(_M_start, __start_n, __new_start);
01128         _M_start = __new_start;
01129         copy(__start_n, __pos, __old_start);
01130         fill(__pos - difference_type(__n), __pos, __x_copy);
01131       }
01132       else {
01133         __uninitialized_copy_fill(_M_start, __pos, __new_start, 
01134                                   _M_start, __x_copy);
01135         _M_start = __new_start;
01136         fill(__old_start, __pos, __x_copy);
01137       }
01138     }
01139     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01140   }
01141   else {
01142     iterator __new_finish = _M_reserve_elements_at_back(__n);
01143     iterator __old_finish = _M_finish;
01144     const difference_type __elems_after = 
01145       difference_type(__length) - __elems_before;
01146     __pos = _M_finish - __elems_after;
01147     __STL_TRY {
01148       if (__elems_after > difference_type(__n)) {
01149         iterator __finish_n = _M_finish - difference_type(__n);
01150         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01151         _M_finish = __new_finish;
01152         copy_backward(__pos, __finish_n, __old_finish);
01153         fill(__pos, __pos + difference_type(__n), __x_copy);
01154       }
01155       else {
01156         __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
01157                                   __x_copy, __pos, _M_finish);
01158         _M_finish = __new_finish;
01159         fill(__pos, __old_finish, __x_copy);
01160       }
01161     }
01162     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01163                                   __new_finish._M_node + 1));
01164   }
01165 }
01166 
01167 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01168 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01169                                       _ForwardIterator __first,
01170                                       _ForwardIterator __last,
01171                                       size_type __n)
01172 {
01173   const difference_type __elemsbefore = __pos - _M_start;
01174   size_type __length = size();
01175   if (static_cast<size_type>(__elemsbefore) < __length / 2) {
01176     iterator __new_start = _M_reserve_elements_at_front(__n);
01177     iterator __old_start = _M_start;
01178     __pos = _M_start + __elemsbefore;
01179     __STL_TRY {
01180       if (__elemsbefore >= difference_type(__n)) {
01181         iterator __start_n = _M_start + difference_type(__n); 
01182         uninitialized_copy(_M_start, __start_n, __new_start);
01183         _M_start = __new_start;
01184         copy(__start_n, __pos, __old_start);
01185         copy(__first, __last, __pos - difference_type(__n));
01186       }
01187       else {
01188         _ForwardIterator __mid = __first;
01189         advance(__mid, difference_type(__n) - __elemsbefore);
01190         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
01191                                   __new_start);
01192         _M_start = __new_start;
01193         copy(__mid, __last, __old_start);
01194       }
01195     }
01196     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01197   }
01198   else {
01199     iterator __new_finish = _M_reserve_elements_at_back(__n);
01200     iterator __old_finish = _M_finish;
01201     const difference_type __elemsafter = 
01202       difference_type(__length) - __elemsbefore;
01203     __pos = _M_finish - __elemsafter;
01204     __STL_TRY {
01205       if (__elemsafter > difference_type(__n)) {
01206         iterator __finish_n = _M_finish - difference_type(__n);
01207         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01208         _M_finish = __new_finish;
01209         copy_backward(__pos, __finish_n, __old_finish);
01210         copy(__first, __last, __pos);
01211       }
01212       else {
01213         _ForwardIterator __mid = __first;
01214         advance(__mid, __elemsafter);
01215         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
01216         _M_finish = __new_finish;
01217         copy(__first, __mid, __pos);
01218       }
01219     }
01220     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01221                                   __new_finish._M_node + 1));
01222   }
01223 }
01224 
01225 template <class _Tp, class _Alloc>
01226 void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
01227 {
01228   size_type __new_nodes
01229       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
01230   _M_reserve_map_at_front(__new_nodes);
01231   size_type __i;
01232   __STL_TRY {
01233     for (__i = 1; __i <= __new_nodes; ++__i)
01234       *(_M_start._M_node - __i) = _M_allocate_node();
01235   }
01236 #       ifdef __STL_USE_EXCEPTIONS
01237   catch(...) {
01238     for (size_type __j = 1; __j < __i; ++__j)
01239       _M_deallocate_node(*(_M_start._M_node - __j));      
01240     throw;
01241   }
01242 #       endif /* __STL_USE_EXCEPTIONS */
01243 }
01244 
01245 template <class _Tp, class _Alloc>
01246 void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
01247 {
01248   size_type __new_nodes
01249       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
01250   _M_reserve_map_at_back(__new_nodes);
01251   size_type __i;
01252   __STL_TRY {
01253     for (__i = 1; __i <= __new_nodes; ++__i)
01254       *(_M_finish._M_node + __i) = _M_allocate_node();
01255   }
01256 #       ifdef __STL_USE_EXCEPTIONS
01257   catch(...) {
01258     for (size_type __j = 1; __j < __i; ++__j)
01259       _M_deallocate_node(*(_M_finish._M_node + __j));      
01260     throw;
01261   }
01262 #       endif /* __STL_USE_EXCEPTIONS */
01263 }
01264 
01265 template <class _Tp, class _Alloc>
01266 void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
01267                                           bool __add_at_front)
01268 {
01269   size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
01270   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
01271 
01272   _Map_pointer __new_nstart;
01273   if (_M_map_size > 2 * __new_num_nodes) {
01274     __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
01275                      + (__add_at_front ? __nodes_to_add : 0);
01276     if (__new_nstart < _M_start._M_node)
01277       copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
01278     else
01279       copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
01280                     __new_nstart + __old_num_nodes);
01281   }
01282   else {
01283     size_type __new_map_size = 
01284       _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
01285 
01286     _Map_pointer __new_map = _M_allocate_map(__new_map_size);
01287     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
01288                          + (__add_at_front ? __nodes_to_add : 0);
01289     copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
01290     _M_deallocate_map(_M_map, _M_map_size);
01291 
01292     _M_map = __new_map;
01293     _M_map_size = __new_map_size;
01294   }
01295 
01296   _M_start._M_set_node(__new_nstart);
01297   _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
01298 }
01299 
01300 
01301 // Nonmember functions.
01302 
01303 template <class _Tp, class _Alloc>
01304 inline bool operator==(const deque<_Tp, _Alloc>& __x,
01305                        const deque<_Tp, _Alloc>& __y) {
01306   return __x.size() == __y.size() &&
01307          equal(__x.begin(), __x.end(), __y.begin());
01308 }
01309 
01310 template <class _Tp, class _Alloc>
01311 inline bool operator<(const deque<_Tp, _Alloc>& __x,
01312                       const deque<_Tp, _Alloc>& __y) {
01313   return lexicographical_compare(__x.begin(), __x.end(), 
01314                                  __y.begin(), __y.end());
01315 }
01316 
01317 template <class _Tp, class _Alloc>
01318 inline bool operator!=(const deque<_Tp, _Alloc>& __x,
01319                        const deque<_Tp, _Alloc>& __y) {
01320   return !(__x == __y);
01321 }
01322 
01323 template <class _Tp, class _Alloc>
01324 inline bool operator>(const deque<_Tp, _Alloc>& __x,
01325                       const deque<_Tp, _Alloc>& __y) {
01326   return __y < __x;
01327 }
01328 
01329 template <class _Tp, class _Alloc>
01330 inline bool operator<=(const deque<_Tp, _Alloc>& __x,
01331                        const deque<_Tp, _Alloc>& __y) {
01332   return !(__y < __x);
01333 }
01334 template <class _Tp, class _Alloc>
01335 inline bool operator>=(const deque<_Tp, _Alloc>& __x,
01336                        const deque<_Tp, _Alloc>& __y) {
01337   return !(__x < __y);
01338 }
01339 
01340 template <class _Tp, class _Alloc>
01341 inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
01342   __x.swap(__y);
01343 }
01344 
01345 } // namespace std 
01346   
01347 #endif /* __SGI_STL_INTERNAL_DEQUE_H */
01348 
01349 // Local Variables:
01350 // mode:C++
01351 // End:

Generated on Mon Apr 8 03:11:39 2002 for libstdc++-v3 Source by doxygen1.2.15