stl_deque.h

Go to the documentation of this file.
00001 // deque implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002 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 
00061 #include <bits/concept_check.h>
00062 #include <bits/stl_iterator_base_types.h>
00063 #include <bits/stl_iterator_base_funcs.h>
00064 
00065 #ifndef __GLIBCPP_INTERNAL_DEQUE_H
00066 #define __GLIBCPP_INTERNAL_DEQUE_H
00067 
00068 
00069 // Since this entire file is within namespace std, there's no reason to
00070 // waste two spaces along the left column.  Thus the leading indentation is
00071 // slightly violated from here on.
00072 namespace std
00073 { 
00074 
00085 inline size_t 
00086 __deque_buf_size(size_t __size) 
00087 { return __size < 512 ? size_t(512 / __size) : size_t(1); }
00088 
00089 
00091 
00101 template <class _Tp, class _Ref, class _Ptr>
00102 struct _Deque_iterator
00103 {
00104   typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
00105   typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
00106   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
00107 
00108   typedef random_access_iterator_tag iterator_category;
00109   typedef _Tp                        value_type;
00110   typedef _Ptr                       pointer;
00111   typedef _Ref                       reference;
00112   typedef size_t                     size_type;
00113   typedef ptrdiff_t                  difference_type;
00114   typedef _Tp**                      _Map_pointer;
00115   typedef _Deque_iterator            _Self;
00116 
00117   _Tp* _M_cur;
00118   _Tp* _M_first;
00119   _Tp* _M_last;
00120   _Map_pointer _M_node;
00121 
00122   _Deque_iterator(_Tp* __x, _Map_pointer __y) 
00123     : _M_cur(__x), _M_first(*__y),
00124       _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
00125   _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
00126   _Deque_iterator(const iterator& __x)
00127     : _M_cur(__x._M_cur), _M_first(__x._M_first), 
00128       _M_last(__x._M_last), _M_node(__x._M_node) {}
00129 
00130   reference operator*() const { return *_M_cur; }
00131   pointer operator->() const { return _M_cur; }
00132 
00133   difference_type operator-(const _Self& __x) const {
00134     return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
00135       (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
00136   }
00137 
00138   _Self& operator++() {
00139     ++_M_cur;
00140     if (_M_cur == _M_last) {
00141       _M_set_node(_M_node + 1);
00142       _M_cur = _M_first;
00143     }
00144     return *this; 
00145   }
00146   _Self operator++(int)  {
00147     _Self __tmp = *this;
00148     ++*this;
00149     return __tmp;
00150   }
00151 
00152   _Self& operator--() {
00153     if (_M_cur == _M_first) {
00154       _M_set_node(_M_node - 1);
00155       _M_cur = _M_last;
00156     }
00157     --_M_cur;
00158     return *this;
00159   }
00160   _Self operator--(int) {
00161     _Self __tmp = *this;
00162     --*this;
00163     return __tmp;
00164   }
00165 
00166   _Self& operator+=(difference_type __n)
00167   {
00168     difference_type __offset = __n + (_M_cur - _M_first);
00169     if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
00170       _M_cur += __n;
00171     else {
00172       difference_type __node_offset =
00173         __offset > 0 ? __offset / difference_type(_S_buffer_size())
00174                    : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
00175       _M_set_node(_M_node + __node_offset);
00176       _M_cur = _M_first + 
00177         (__offset - __node_offset * difference_type(_S_buffer_size()));
00178     }
00179     return *this;
00180   }
00181 
00182   _Self operator+(difference_type __n) const
00183   {
00184     _Self __tmp = *this;
00185     return __tmp += __n;
00186   }
00187 
00188   _Self& operator-=(difference_type __n) { return *this += -__n; }
00189  
00190   _Self operator-(difference_type __n) const {
00191     _Self __tmp = *this;
00192     return __tmp -= __n;
00193   }
00194 
00195   reference operator[](difference_type __n) const { return *(*this + __n); }
00196 
00197   bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
00198   bool operator!=(const _Self& __x) const { return !(*this == __x); }
00199   bool operator<(const _Self& __x) const {
00200     return (_M_node == __x._M_node) ? 
00201       (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
00202   }
00203   bool operator>(const _Self& __x) const  { return __x < *this; }
00204   bool operator<=(const _Self& __x) const { return !(__x < *this); }
00205   bool operator>=(const _Self& __x) const { return !(*this < __x); }
00206 
00213   void _M_set_node(_Map_pointer __new_node) {
00214     _M_node = __new_node;
00215     _M_first = *__new_node;
00216     _M_last = _M_first + difference_type(_S_buffer_size());
00217   }
00218 };
00219 
00220 template <class _Tp, class _Ref, class _Ptr>
00221 inline _Deque_iterator<_Tp, _Ref, _Ptr>
00222 operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
00223 {
00224   return __x + __n;
00225 }
00226 
00227 
00229 
00239 template <class _Tp, class _Alloc, bool __is_static>
00240 class _Deque_alloc_base
00241 {
00242 public:
00243   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00244   allocator_type get_allocator() const { return _M_node_allocator; }
00245 
00246   _Deque_alloc_base(const allocator_type& __a)
00247     : _M_node_allocator(__a), _M_map_allocator(__a),
00248       _M_map(0), _M_map_size(0)
00249   {}
00250   
00251 protected:
00252   typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
00253           _Map_allocator_type;
00254 
00255   allocator_type      _M_node_allocator;
00256   _Map_allocator_type _M_map_allocator;
00257 
00258   _Tp* _M_allocate_node() {
00259     return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
00260   }
00261   void _M_deallocate_node(_Tp* __p) {
00262     _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
00263   }
00264   _Tp** _M_allocate_map(size_t __n) 
00265     { return _M_map_allocator.allocate(__n); }
00266   void _M_deallocate_map(_Tp** __p, size_t __n) 
00267     { _M_map_allocator.deallocate(__p, __n); }
00268 
00269   _Tp** _M_map;
00270   size_t _M_map_size;
00271 };
00272 
00274 template <class _Tp, class _Alloc>
00275 class _Deque_alloc_base<_Tp, _Alloc, true>
00276 {
00277 public:
00278   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00279   allocator_type get_allocator() const { return allocator_type(); }
00280 
00281   _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
00282   
00283 protected:
00284   typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
00285   typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
00286 
00287   _Tp* _M_allocate_node() {
00288     return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
00289   }
00290   void _M_deallocate_node(_Tp* __p) {
00291     _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
00292   }
00293   _Tp** _M_allocate_map(size_t __n) 
00294     { return _Map_alloc_type::allocate(__n); }
00295   void _M_deallocate_map(_Tp** __p, size_t __n) 
00296     { _Map_alloc_type::deallocate(__p, __n); }
00297 
00298   _Tp** _M_map;
00299   size_t _M_map_size;
00300 };
00301 
00302 
00313 template <class _Tp, class _Alloc>
00314 class _Deque_base
00315   : public _Deque_alloc_base<_Tp,_Alloc,
00316                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00317 {
00318 public:
00319   typedef _Deque_alloc_base<_Tp,_Alloc,
00320                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00321           _Base;
00322   typedef typename _Base::allocator_type             allocator_type;
00323   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
00324   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00325 
00326   _Deque_base(const allocator_type& __a, size_t __num_elements)
00327     : _Base(__a), _M_start(), _M_finish()
00328     { _M_initialize_map(__num_elements); }
00329   _Deque_base(const allocator_type& __a) 
00330     : _Base(__a), _M_start(), _M_finish() {}
00331   ~_Deque_base();    
00332 
00333 protected:
00334   void _M_initialize_map(size_t);
00335   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
00336   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
00337   enum { _S_initial_map_size = 8 };
00338 
00339 protected:
00340   iterator _M_start;
00341   iterator _M_finish;
00342 };
00343 
00344 
00345 template <class _Tp, class _Alloc>
00346 _Deque_base<_Tp,_Alloc>::~_Deque_base()
00347 {
00348   if (_M_map) {
00349     _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
00350     _M_deallocate_map(_M_map, _M_map_size);
00351   }
00352 }
00353 
00363 template <class _Tp, class _Alloc>
00364 void
00365 _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
00366 {
00367   size_t __num_nodes = 
00368     __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
00369 
00370   _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
00371   _M_map = _M_allocate_map(_M_map_size);
00372 
00373   _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
00374   _Tp** __nfinish = __nstart + __num_nodes;
00375     
00376   try 
00377     { _M_create_nodes(__nstart, __nfinish); }
00378   catch(...)
00379     {
00380       _M_deallocate_map(_M_map, _M_map_size);
00381       _M_map = 0;
00382       _M_map_size = 0;
00383       __throw_exception_again;
00384     }
00385   
00386   _M_start._M_set_node(__nstart);
00387   _M_finish._M_set_node(__nfinish - 1);
00388   _M_start._M_cur = _M_start._M_first;
00389   _M_finish._M_cur = _M_finish._M_first +
00390                __num_elements % __deque_buf_size(sizeof(_Tp));
00391 }
00392 
00393 template <class _Tp, class _Alloc>
00394 void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
00395 {
00396   _Tp** __cur;
00397   try {
00398     for (__cur = __nstart; __cur < __nfinish; ++__cur)
00399       *__cur = _M_allocate_node();
00400   }
00401   catch(...)
00402     { 
00403       _M_destroy_nodes(__nstart, __cur);
00404       __throw_exception_again; 
00405     }
00406 }
00407 
00408 template <class _Tp, class _Alloc>
00409 void
00410 _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
00411 {
00412   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
00413     _M_deallocate_node(*__n);
00414 }
00415 
00416 
00497 template <class _Tp, class _Alloc = allocator<_Tp> >
00498 class deque : protected _Deque_base<_Tp, _Alloc>
00499 {
00500   // concept requirements
00501   __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
00502 
00503   typedef _Deque_base<_Tp, _Alloc> _Base;
00504 
00505 public:
00506   typedef _Tp                                value_type;
00507   typedef value_type*                        pointer;
00508   typedef const value_type*                  const_pointer;
00509   typedef value_type&                        reference;
00510   typedef const value_type&                  const_reference;
00511   typedef size_t                             size_type;
00512   typedef ptrdiff_t                          difference_type;
00513 
00514   typedef typename _Base::allocator_type allocator_type;
00515   allocator_type get_allocator() const { return _Base::get_allocator(); }
00516 
00517   typedef typename _Base::iterator           iterator;
00518   typedef typename _Base::const_iterator     const_iterator;
00519   typedef reverse_iterator<const_iterator>   const_reverse_iterator;
00520   typedef reverse_iterator<iterator>         reverse_iterator;
00521 
00522 protected:
00523   typedef pointer* _Map_pointer;
00524   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
00525 
00526   // Functions controlling memory layout, and nothing else.
00527   using _Base::_M_initialize_map;
00528   using _Base::_M_create_nodes;
00529   using _Base::_M_destroy_nodes;
00530   using _Base::_M_allocate_node;
00531   using _Base::_M_deallocate_node;
00532   using _Base::_M_allocate_map;
00533   using _Base::_M_deallocate_map;
00534 
00541   using _Base::_M_map;
00542   using _Base::_M_map_size;
00543   using _Base::_M_start;
00544   using _Base::_M_finish;
00545 
00546 public:                         // Basic accessors
00547   iterator begin() { return _M_start; }
00548   iterator end() { return _M_finish; }
00549   const_iterator begin() const { return _M_start; }
00550   const_iterator end() const { return _M_finish; }
00551 
00552   reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
00553   reverse_iterator rend() { return reverse_iterator(_M_start); }
00554   const_reverse_iterator rbegin() const 
00555     { return const_reverse_iterator(_M_finish); }
00556   const_reverse_iterator rend() const 
00557     { return const_reverse_iterator(_M_start); }
00558 
00559   reference operator[](size_type __n)
00560     { return _M_start[difference_type(__n)]; }
00561   const_reference operator[](size_type __n) const 
00562     { return _M_start[difference_type(__n)]; }
00563 
00564   void _M_range_check(size_type __n) const {
00565     if (__n >= this->size())
00566       __throw_range_error("deque");
00567   }
00568 
00569   reference at(size_type __n)
00570     { _M_range_check(__n); return (*this)[__n]; }
00571   const_reference at(size_type __n) const
00572     { _M_range_check(__n); return (*this)[__n]; }
00573 
00574   reference front() { return *_M_start; }
00575   reference back() {
00576     iterator __tmp = _M_finish;
00577     --__tmp;
00578     return *__tmp;
00579   }
00580   const_reference front() const { return *_M_start; }
00581   const_reference back() const {
00582     const_iterator __tmp = _M_finish;
00583     --__tmp;
00584     return *__tmp;
00585   }
00586 
00587   size_type size() const { return _M_finish - _M_start; }
00588   size_type max_size() const { return size_type(-1); }
00589   bool empty() const { return _M_finish == _M_start; }
00590 
00591 public:                         // Constructor, destructor.
00592   explicit deque(const allocator_type& __a = allocator_type()) 
00593     : _Base(__a, 0) {}
00594   deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) 
00595     { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
00596   deque(size_type __n, const value_type& __value,
00597         const allocator_type& __a = allocator_type()) : _Base(__a, __n)
00598     { _M_fill_initialize(__value); }
00599 
00600   explicit
00601   deque(size_type __n)
00602   : _Base(allocator_type(), __n)
00603   { _M_fill_initialize(value_type()); }
00604 
00605   // Check whether it's an integral type.  If so, it's not an iterator.
00606   template<class _InputIterator>
00607     deque(_InputIterator __first, _InputIterator __last,
00608           const allocator_type& __a = allocator_type())
00609     : _Base(__a)
00610     {
00611       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00612       _M_initialize_dispatch(__first, __last, _Integral());
00613     }
00614 
00615   template<class _Integer>
00616     void
00617     _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
00618     {
00619       _M_initialize_map(__n);
00620       _M_fill_initialize(__x);
00621     }
00622 
00623   template<class _InputIter>
00624     void
00625     _M_initialize_dispatch(_InputIter __first, _InputIter __last, __false_type)
00626     {
00627       typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
00628       _M_range_initialize(__first, __last, _IterCategory());
00629     }
00630 
00631   ~deque()
00632   { _Destroy(_M_start, _M_finish); }
00633 
00634   deque& operator= (const deque& __x) {
00635     const size_type __len = size();
00636     if (&__x != this) {
00637       if (__len >= __x.size())
00638         erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
00639       else {
00640         const_iterator __mid = __x.begin() + difference_type(__len);
00641         copy(__x.begin(), __mid, _M_start);
00642         insert(_M_finish, __mid, __x.end());
00643       }
00644     }
00645     return *this;
00646   }        
00647 
00648   void swap(deque& __x) {
00649     std::swap(_M_start, __x._M_start);
00650     std::swap(_M_finish, __x._M_finish);
00651     std::swap(_M_map, __x._M_map);
00652     std::swap(_M_map_size, __x._M_map_size);
00653   }
00654 
00655 public: 
00656   // assign(), a generalized assignment member function.  Two
00657   // versions: one that takes a count, and one that takes a range.
00658   // The range version is a member template, so we dispatch on whether
00659   // or not the type is an integer.
00660 
00661   void _M_fill_assign(size_type __n, const _Tp& __val) {
00662     if (__n > size()) {
00663       fill(begin(), end(), __val);
00664       insert(end(), __n - size(), __val);
00665     }
00666     else {
00667       erase(begin() + __n, end());
00668       fill(begin(), end(), __val);
00669     }
00670   }
00671 
00672   void
00673   assign(size_type __n, const _Tp& __val)
00674   { _M_fill_assign(__n, __val); }
00675 
00676   template<class _InputIterator>
00677     void
00678     assign(_InputIterator __first, _InputIterator __last)
00679     {
00680       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00681       _M_assign_dispatch(__first, __last, _Integral());
00682     }
00683 
00684 private:                        // helper functions for assign() 
00685 
00686   template<class _Integer>
00687     void
00688     _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00689     { _M_fill_assign(static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
00690 
00691   template<class _InputIterator>
00692     void
00693     _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type)
00694     {
00695       typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
00696       _M_assign_aux(__first, __last, _IterCategory());
00697     }
00698 
00699   template <class _InputIterator>
00700   void _M_assign_aux(_InputIterator __first, _InputIterator __last,
00701                      input_iterator_tag);
00702 
00703   template <class _ForwardIterator>
00704   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00705                      forward_iterator_tag) {
00706     size_type __len = distance(__first, __last);
00707     if (__len > size()) {
00708       _ForwardIterator __mid = __first;
00709       advance(__mid, size());
00710       copy(__first, __mid, begin());
00711       insert(end(), __mid, __last);
00712     }
00713     else
00714       erase(copy(__first, __last, begin()), end());
00715   }
00716 
00717 public:                         // push_* and pop_*
00718   
00719   void
00720   push_back(const value_type& __t)
00721   {
00722     if (_M_finish._M_cur != _M_finish._M_last - 1) {
00723       _Construct(_M_finish._M_cur, __t);
00724       ++_M_finish._M_cur;
00725     }
00726     else
00727       _M_push_back_aux(__t);
00728   }
00729 
00730   void
00731   push_back()
00732   {
00733     if (_M_finish._M_cur != _M_finish._M_last - 1) {
00734       _Construct(_M_finish._M_cur);
00735       ++_M_finish._M_cur;
00736     }
00737     else
00738       _M_push_back_aux();
00739   }
00740 
00741   void
00742   push_front(const value_type& __t) 
00743   {
00744     if (_M_start._M_cur != _M_start._M_first) {
00745       _Construct(_M_start._M_cur - 1, __t);
00746       --_M_start._M_cur;
00747     }
00748     else
00749       _M_push_front_aux(__t);
00750   }
00751 
00752   void
00753   push_front()
00754   {
00755     if (_M_start._M_cur != _M_start._M_first) {
00756       _Construct(_M_start._M_cur - 1);
00757       --_M_start._M_cur;
00758     }
00759     else
00760       _M_push_front_aux();
00761   }
00762 
00763 
00764   void
00765   pop_back()
00766   {
00767     if (_M_finish._M_cur != _M_finish._M_first) {
00768       --_M_finish._M_cur;
00769       _Destroy(_M_finish._M_cur);
00770     }
00771     else
00772       _M_pop_back_aux();
00773   }
00774 
00775   void
00776   pop_front()
00777   {
00778     if (_M_start._M_cur != _M_start._M_last - 1) {
00779       _Destroy(_M_start._M_cur);
00780       ++_M_start._M_cur;
00781     }
00782     else 
00783       _M_pop_front_aux();
00784   }
00785 
00786 public:                         // Insert
00787 
00788   iterator
00789   insert(iterator position, const value_type& __x)
00790   {
00791     if (position._M_cur == _M_start._M_cur) {
00792       push_front(__x);
00793       return _M_start;
00794     }
00795     else if (position._M_cur == _M_finish._M_cur) {
00796       push_back(__x);
00797       iterator __tmp = _M_finish;
00798       --__tmp;
00799       return __tmp;
00800     }
00801     else {
00802       return _M_insert_aux(position, __x);
00803     }
00804   }
00805 
00806   iterator
00807   insert(iterator __position)
00808   { return insert(__position, value_type()); }
00809 
00810   void
00811   insert(iterator __pos, size_type __n, const value_type& __x)
00812   { _M_fill_insert(__pos, __n, __x); }
00813 
00814   void
00815   _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
00816 
00817   // Check whether it's an integral type.  If so, it's not an iterator.
00818   template<class _InputIterator>
00819     void
00820     insert(iterator __pos, _InputIterator __first, _InputIterator __last)
00821     {
00822       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00823       _M_insert_dispatch(__pos, __first, __last, _Integral());
00824     }
00825 
00826   template<class _Integer>
00827     void
00828     _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
00829     { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<value_type>(__x)); }
00830 
00831   template<class _InputIterator>
00832     void
00833     _M_insert_dispatch(iterator __pos,
00834                        _InputIterator __first, _InputIterator __last,
00835                        __false_type)
00836     {
00837       typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
00838       insert(__pos, __first, __last, _IterCategory());
00839     }
00840 
00841   void resize(size_type __new_size, const value_type& __x) {
00842     const size_type __len = size();
00843     if (__new_size < __len) 
00844       erase(_M_start + __new_size, _M_finish);
00845     else
00846       insert(_M_finish, __new_size - __len, __x);
00847   }
00848 
00849   void resize(size_type new_size) { resize(new_size, value_type()); }
00850 
00851 public:                         // Erase
00852   iterator erase(iterator __pos) {
00853     iterator __next = __pos;
00854     ++__next;
00855     size_type __index = __pos - _M_start;
00856     if (__index < (size() >> 1)) {
00857       copy_backward(_M_start, __pos, __next);
00858       pop_front();
00859     }
00860     else {
00861       copy(__next, _M_finish, __pos);
00862       pop_back();
00863     }
00864     return _M_start + __index;
00865   }
00866 
00867   iterator erase(iterator __first, iterator __last);
00868   void clear(); 
00869 
00870 protected:                        // Internal construction/destruction
00871 
00872   void _M_fill_initialize(const value_type& __value);
00873 
00874   template <class _InputIterator>
00875   void _M_range_initialize(_InputIterator __first, _InputIterator __last,
00876                         input_iterator_tag);
00877 
00878   template <class _ForwardIterator>
00879   void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
00880                         forward_iterator_tag);
00881 
00882 protected:                        // Internal push_* and pop_*
00883 
00884   void _M_push_back_aux(const value_type&);
00885   void _M_push_back_aux();
00886   void _M_push_front_aux(const value_type&);
00887   void _M_push_front_aux();
00888   void _M_pop_back_aux();
00889   void _M_pop_front_aux();
00890 
00891 protected:                        // Internal insert functions
00892 
00893   template <class _InputIterator>
00894   void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
00895               input_iterator_tag);
00896 
00897   template <class _ForwardIterator>
00898   void insert(iterator __pos,
00899               _ForwardIterator __first, _ForwardIterator __last,
00900               forward_iterator_tag);
00901 
00902   iterator _M_insert_aux(iterator __pos, const value_type& __x);
00903   iterator _M_insert_aux(iterator __pos);
00904   void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
00905 
00906   template <class _ForwardIterator>
00907   void _M_insert_aux(iterator __pos, 
00908                      _ForwardIterator __first, _ForwardIterator __last,
00909                      size_type __n);
00910 
00911   iterator _M_reserve_elements_at_front(size_type __n) {
00912     size_type __vacancies = _M_start._M_cur - _M_start._M_first;
00913     if (__n > __vacancies) 
00914       _M_new_elements_at_front(__n - __vacancies);
00915     return _M_start - difference_type(__n);
00916   }
00917 
00918   iterator _M_reserve_elements_at_back(size_type __n) {
00919     size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
00920     if (__n > __vacancies)
00921       _M_new_elements_at_back(__n - __vacancies);
00922     return _M_finish + difference_type(__n);
00923   }
00924 
00925   void _M_new_elements_at_front(size_type __new_elements);
00926   void _M_new_elements_at_back(size_type __new_elements);
00927 
00928 protected:                      // Allocation of _M_map and nodes
00929 
00930   // Makes sure the _M_map has space for new nodes.  Does not actually
00931   //  add the nodes.  Can invalidate _M_map pointers.  (And consequently, 
00932   //  deque iterators.)
00933 
00934   void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
00935     if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
00936       _M_reallocate_map(__nodes_to_add, false);
00937   }
00938 
00939   void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
00940     if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
00941       _M_reallocate_map(__nodes_to_add, true);
00942   }
00943 
00944   void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
00945 };
00946 
00947 // Non-inline member functions
00948 
00949 template <class _Tp, class _Alloc>
00950 template <class _InputIter>
00951 void deque<_Tp, _Alloc>
00952   ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
00953 {
00954   iterator __cur = begin();
00955   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00956     *__cur = *__first;
00957   if (__first == __last)
00958     erase(__cur, end());
00959   else
00960     insert(end(), __first, __last);
00961 }
00962 
00963 template <class _Tp, class _Alloc>
00964 void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
00965                                         size_type __n, const value_type& __x)
00966 {
00967   if (__pos._M_cur == _M_start._M_cur) {
00968     iterator __new_start = _M_reserve_elements_at_front(__n);
00969     try {
00970       uninitialized_fill(__new_start, _M_start, __x);
00971       _M_start = __new_start;
00972     }
00973     catch(...)
00974       {
00975     _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
00976     __throw_exception_again;
00977       }
00978   }
00979   else if (__pos._M_cur == _M_finish._M_cur) {
00980     iterator __new_finish = _M_reserve_elements_at_back(__n);
00981     try {
00982       uninitialized_fill(_M_finish, __new_finish, __x);
00983       _M_finish = __new_finish;
00984     }
00985     catch(...)
00986       {
00987     _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);    
00988     __throw_exception_again;
00989       }
00990   }
00991   else 
00992     _M_insert_aux(__pos, __n, __x);
00993 }
00994 
00995 template <class _Tp, class _Alloc>
00996 typename deque<_Tp,_Alloc>::iterator 
00997 deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
00998 {
00999   if (__first == _M_start && __last == _M_finish) {
01000     clear();
01001     return _M_finish;
01002   }
01003   else {
01004     difference_type __n = __last - __first;
01005     difference_type __elems_before = __first - _M_start;
01006     if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) {
01007       copy_backward(_M_start, __first, __last);
01008       iterator __new_start = _M_start + __n;
01009       _Destroy(_M_start, __new_start);
01010       _M_destroy_nodes(_M_start._M_node, __new_start._M_node);
01011       _M_start = __new_start;
01012     }
01013     else {
01014       copy(__last, _M_finish, __first);
01015       iterator __new_finish = _M_finish - __n;
01016       _Destroy(__new_finish, _M_finish);
01017       _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
01018       _M_finish = __new_finish;
01019     }
01020     return _M_start + __elems_before;
01021   }
01022 }
01023 
01024 template <class _Tp, class _Alloc> 
01025 void deque<_Tp,_Alloc>::clear()
01026 {
01027   for (_Map_pointer __node = _M_start._M_node + 1;
01028        __node < _M_finish._M_node;
01029        ++__node) {
01030     _Destroy(*__node, *__node + _S_buffer_size());
01031     _M_deallocate_node(*__node);
01032   }
01033 
01034   if (_M_start._M_node != _M_finish._M_node) {
01035     _Destroy(_M_start._M_cur, _M_start._M_last);
01036     _Destroy(_M_finish._M_first, _M_finish._M_cur);
01037     _M_deallocate_node(_M_finish._M_first);
01038   }
01039   else
01040     _Destroy(_M_start._M_cur, _M_finish._M_cur);
01041 
01042   _M_finish = _M_start;
01043 }
01044 
01057 template <class _Tp, class _Alloc>
01058 void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value)
01059 {
01060   _Map_pointer __cur;
01061   try {
01062     for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
01063       uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
01064     uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
01065   }
01066   catch(...)
01067     {
01068       _Destroy(_M_start, iterator(*__cur, __cur));
01069       __throw_exception_again;
01070     }
01071 }
01072 
01085 template <class _Tp, class _Alloc> template <class _InputIterator>
01086 void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
01087                                             _InputIterator __last,
01088                                             input_iterator_tag)
01089 {
01090   _M_initialize_map(0);
01091   try {
01092     for ( ; __first != __last; ++__first)
01093       push_back(*__first);
01094   }
01095   catch(...)
01096     {
01097       clear();
01098       __throw_exception_again;
01099     }
01100 }
01101 
01102 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01103 void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
01104                                             _ForwardIterator __last,
01105                                             forward_iterator_tag)
01106 {
01107   size_type __n = distance(__first, __last);
01108   _M_initialize_map(__n);
01109 
01110   _Map_pointer __cur_node;
01111   try {
01112     for (__cur_node = _M_start._M_node; 
01113          __cur_node < _M_finish._M_node; 
01114          ++__cur_node) {
01115       _ForwardIterator __mid = __first;
01116       advance(__mid, _S_buffer_size());
01117       uninitialized_copy(__first, __mid, *__cur_node);
01118       __first = __mid;
01119     }
01120     uninitialized_copy(__first, __last, _M_finish._M_first);
01121   }
01122   catch(...)
01123     {
01124       _Destroy(_M_start, iterator(*__cur_node, __cur_node));
01125       __throw_exception_again;
01126     }
01127 }
01130 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
01131 template <class _Tp, class _Alloc>
01132 void
01133 deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
01134 {
01135   value_type __t_copy = __t;
01136   _M_reserve_map_at_back();
01137   *(_M_finish._M_node + 1) = _M_allocate_node();
01138   try {
01139     _Construct(_M_finish._M_cur, __t_copy);
01140     _M_finish._M_set_node(_M_finish._M_node + 1);
01141     _M_finish._M_cur = _M_finish._M_first;
01142   }
01143   catch(...)
01144     {
01145       _M_deallocate_node(*(_M_finish._M_node + 1));
01146       __throw_exception_again;
01147     }
01148 }
01149 
01150 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
01151 template <class _Tp, class _Alloc>
01152 void
01153 deque<_Tp,_Alloc>::_M_push_back_aux()
01154 {
01155   _M_reserve_map_at_back();
01156   *(_M_finish._M_node + 1) = _M_allocate_node();
01157   try {
01158     _Construct(_M_finish._M_cur);
01159     _M_finish._M_set_node(_M_finish._M_node + 1);
01160     _M_finish._M_cur = _M_finish._M_first;
01161   }
01162   catch(...)
01163     {
01164       _M_deallocate_node(*(_M_finish._M_node + 1));
01165       __throw_exception_again;
01166     }
01167 }
01168 
01169 // Called only if _M_start._M_cur == _M_start._M_first.
01170 template <class _Tp, class _Alloc>
01171 void
01172 deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
01173 {
01174   value_type __t_copy = __t;
01175   _M_reserve_map_at_front();
01176   *(_M_start._M_node - 1) = _M_allocate_node();
01177   try {
01178     _M_start._M_set_node(_M_start._M_node - 1);
01179     _M_start._M_cur = _M_start._M_last - 1;
01180     _Construct(_M_start._M_cur, __t_copy);
01181   }
01182   catch(...)
01183     {
01184       ++_M_start;
01185       _M_deallocate_node(*(_M_start._M_node - 1));
01186       __throw_exception_again;
01187     }
01188 } 
01189 
01190 // Called only if _M_start._M_cur == _M_start._M_first.
01191 template <class _Tp, class _Alloc>
01192 void
01193 deque<_Tp,_Alloc>::_M_push_front_aux()
01194 {
01195   _M_reserve_map_at_front();
01196   *(_M_start._M_node - 1) = _M_allocate_node();
01197   try {
01198     _M_start._M_set_node(_M_start._M_node - 1);
01199     _M_start._M_cur = _M_start._M_last - 1;
01200     _Construct(_M_start._M_cur);
01201   }
01202   catch(...)
01203     {
01204       ++_M_start;
01205       _M_deallocate_node(*(_M_start._M_node - 1));
01206       __throw_exception_again;
01207     }
01208 } 
01209 
01210 // Called only if _M_finish._M_cur == _M_finish._M_first.
01211 template <class _Tp, class _Alloc>
01212 void deque<_Tp,_Alloc>::_M_pop_back_aux()
01213 {
01214   _M_deallocate_node(_M_finish._M_first);
01215   _M_finish._M_set_node(_M_finish._M_node - 1);
01216   _M_finish._M_cur = _M_finish._M_last - 1;
01217   _Destroy(_M_finish._M_cur);
01218 }
01219 
01220 // Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
01221 // if the deque has at least one element (a precondition for this member 
01222 // function), and if _M_start._M_cur == _M_start._M_last, then the deque 
01223 // must have at least two nodes.
01224 template <class _Tp, class _Alloc>
01225 void deque<_Tp,_Alloc>::_M_pop_front_aux()
01226 {
01227   _Destroy(_M_start._M_cur);
01228   _M_deallocate_node(_M_start._M_first);
01229   _M_start._M_set_node(_M_start._M_node + 1);
01230   _M_start._M_cur = _M_start._M_first;
01231 }      
01232 
01233 template <class _Tp, class _Alloc> template <class _InputIterator>
01234 void deque<_Tp,_Alloc>::insert(iterator __pos,
01235                                _InputIterator __first, _InputIterator __last,
01236                                input_iterator_tag)
01237 {
01238   copy(__first, __last, inserter(*this, __pos));
01239 }
01240 
01241 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01242 void
01243 deque<_Tp,_Alloc>::insert(iterator __pos,
01244                           _ForwardIterator __first, _ForwardIterator __last,
01245                           forward_iterator_tag) {
01246   size_type __n = distance(__first, __last);
01247   if (__pos._M_cur == _M_start._M_cur) {
01248     iterator __new_start = _M_reserve_elements_at_front(__n);
01249     try {
01250       uninitialized_copy(__first, __last, __new_start);
01251       _M_start = __new_start;
01252     }
01253     catch(...)
01254       {
01255     _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
01256     __throw_exception_again;
01257       }
01258   }
01259   else if (__pos._M_cur == _M_finish._M_cur) {
01260     iterator __new_finish = _M_reserve_elements_at_back(__n);
01261     try {
01262       uninitialized_copy(__first, __last, _M_finish);
01263       _M_finish = __new_finish;
01264     }
01265     catch(...)
01266       {
01267     _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
01268     __throw_exception_again;
01269       }
01270   }
01271   else
01272     _M_insert_aux(__pos, __first, __last, __n);
01273 }
01274 
01275 template <class _Tp, class _Alloc>
01276 typename deque<_Tp, _Alloc>::iterator
01277 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
01278 {
01279   difference_type __index = __pos - _M_start;
01280   value_type __x_copy = __x;
01281   if (static_cast<size_type>(__index) < size() / 2) {
01282     push_front(front());
01283     iterator __front1 = _M_start;
01284     ++__front1;
01285     iterator __front2 = __front1;
01286     ++__front2;
01287     __pos = _M_start + __index;
01288     iterator __pos1 = __pos;
01289     ++__pos1;
01290     copy(__front2, __pos1, __front1);
01291   }
01292   else {
01293     push_back(back());
01294     iterator __back1 = _M_finish;
01295     --__back1;
01296     iterator __back2 = __back1;
01297     --__back2;
01298     __pos = _M_start + __index;
01299     copy_backward(__pos, __back2, __back1);
01300   }
01301   *__pos = __x_copy;
01302   return __pos;
01303 }
01304 
01305 template <class _Tp, class _Alloc>
01306 typename deque<_Tp,_Alloc>::iterator 
01307 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
01308 {
01309   difference_type __index = __pos - _M_start;
01310   if (static_cast<size_type>(__index) < size() / 2) {
01311     push_front(front());
01312     iterator __front1 = _M_start;
01313     ++__front1;
01314     iterator __front2 = __front1;
01315     ++__front2;
01316     __pos = _M_start + __index;
01317     iterator __pos1 = __pos;
01318     ++__pos1;
01319     copy(__front2, __pos1, __front1);
01320   }
01321   else {
01322     push_back(back());
01323     iterator __back1 = _M_finish;
01324     --__back1;
01325     iterator __back2 = __back1;
01326     --__back2;
01327     __pos = _M_start + __index;
01328     copy_backward(__pos, __back2, __back1);
01329   }
01330   *__pos = value_type();
01331   return __pos;
01332 }
01333 
01334 template <class _Tp, class _Alloc>
01335 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01336                                       size_type __n,
01337                                       const value_type& __x)
01338 {
01339   const difference_type __elems_before = __pos - _M_start;
01340   size_type __length = this->size();
01341   value_type __x_copy = __x;
01342   if (__elems_before < difference_type(__length / 2)) {
01343     iterator __new_start = _M_reserve_elements_at_front(__n);
01344     iterator __old_start = _M_start;
01345     __pos = _M_start + __elems_before;
01346     try {
01347       if (__elems_before >= difference_type(__n)) {
01348         iterator __start_n = _M_start + difference_type(__n);
01349         uninitialized_copy(_M_start, __start_n, __new_start);
01350         _M_start = __new_start;
01351         copy(__start_n, __pos, __old_start);
01352         fill(__pos - difference_type(__n), __pos, __x_copy);
01353       }
01354       else {
01355         __uninitialized_copy_fill(_M_start, __pos, __new_start, 
01356                                   _M_start, __x_copy);
01357         _M_start = __new_start;
01358         fill(__old_start, __pos, __x_copy);
01359       }
01360     }
01361     catch(...)
01362       { 
01363     _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
01364     __throw_exception_again;
01365       }
01366   }
01367   else {
01368     iterator __new_finish = _M_reserve_elements_at_back(__n);
01369     iterator __old_finish = _M_finish;
01370     const difference_type __elems_after = 
01371       difference_type(__length) - __elems_before;
01372     __pos = _M_finish - __elems_after;
01373     try {
01374       if (__elems_after > difference_type(__n)) {
01375         iterator __finish_n = _M_finish - difference_type(__n);
01376         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01377         _M_finish = __new_finish;
01378         copy_backward(__pos, __finish_n, __old_finish);
01379         fill(__pos, __pos + difference_type(__n), __x_copy);
01380       }
01381       else {
01382         __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
01383                                   __x_copy, __pos, _M_finish);
01384         _M_finish = __new_finish;
01385         fill(__pos, __old_finish, __x_copy);
01386       }
01387     }
01388     catch(...)
01389       { 
01390     _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
01391     __throw_exception_again;
01392       }
01393   }
01394 }
01395 
01396 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01397 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01398                                       _ForwardIterator __first,
01399                                       _ForwardIterator __last,
01400                                       size_type __n)
01401 {
01402   const difference_type __elemsbefore = __pos - _M_start;
01403   size_type __length = size();
01404   if (static_cast<size_type>(__elemsbefore) < __length / 2) {
01405     iterator __new_start = _M_reserve_elements_at_front(__n);
01406     iterator __old_start = _M_start;
01407     __pos = _M_start + __elemsbefore;
01408     try {
01409       if (__elemsbefore >= difference_type(__n)) {
01410         iterator __start_n = _M_start + difference_type(__n); 
01411         uninitialized_copy(_M_start, __start_n, __new_start);
01412         _M_start = __new_start;
01413         copy(__start_n, __pos, __old_start);
01414         copy(__first, __last, __pos - difference_type(__n));
01415       }
01416       else {
01417         _ForwardIterator __mid = __first;
01418         advance(__mid, difference_type(__n) - __elemsbefore);
01419         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
01420                                   __new_start);
01421         _M_start = __new_start;
01422         copy(__mid, __last, __old_start);
01423       }
01424     }
01425     catch(...)
01426       {
01427     _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
01428     __throw_exception_again;
01429       }
01430   }
01431   else {
01432     iterator __new_finish = _M_reserve_elements_at_back(__n);
01433     iterator __old_finish = _M_finish;
01434     const difference_type __elemsafter = 
01435       difference_type(__length) - __elemsbefore;
01436     __pos = _M_finish - __elemsafter;
01437     try {
01438       if (__elemsafter > difference_type(__n)) {
01439         iterator __finish_n = _M_finish - difference_type(__n);
01440         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01441         _M_finish = __new_finish;
01442         copy_backward(__pos, __finish_n, __old_finish);
01443         copy(__first, __last, __pos);
01444       }
01445       else {
01446         _ForwardIterator __mid = __first;
01447         advance(__mid, __elemsafter);
01448         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
01449         _M_finish = __new_finish;
01450         copy(__first, __mid, __pos);
01451       }
01452     }
01453     catch(...)
01454       {
01455     _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
01456     __throw_exception_again;
01457       }
01458   }
01459 }
01460 
01461 template <class _Tp, class _Alloc>
01462 void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
01463 {
01464   size_type __new_nodes
01465       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
01466   _M_reserve_map_at_front(__new_nodes);
01467   size_type __i;
01468   try {
01469     for (__i = 1; __i <= __new_nodes; ++__i)
01470       *(_M_start._M_node - __i) = _M_allocate_node();
01471   }
01472   catch(...) {
01473     for (size_type __j = 1; __j < __i; ++__j)
01474       _M_deallocate_node(*(_M_start._M_node - __j));      
01475     __throw_exception_again;
01476   }
01477 }
01478 
01479 template <class _Tp, class _Alloc>
01480 void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
01481 {
01482   size_type __new_nodes
01483       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
01484   _M_reserve_map_at_back(__new_nodes);
01485   size_type __i;
01486   try {
01487     for (__i = 1; __i <= __new_nodes; ++__i)
01488       *(_M_finish._M_node + __i) = _M_allocate_node();
01489   }
01490   catch(...) {
01491     for (size_type __j = 1; __j < __i; ++__j)
01492       _M_deallocate_node(*(_M_finish._M_node + __j));      
01493     __throw_exception_again;
01494   }
01495 }
01496 
01497 template <class _Tp, class _Alloc>
01498 void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
01499                                           bool __add_at_front)
01500 {
01501   size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
01502   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
01503 
01504   _Map_pointer __new_nstart;
01505   if (_M_map_size > 2 * __new_num_nodes) {
01506     __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
01507                      + (__add_at_front ? __nodes_to_add : 0);
01508     if (__new_nstart < _M_start._M_node)
01509       copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
01510     else
01511       copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
01512                     __new_nstart + __old_num_nodes);
01513   }
01514   else {
01515     size_type __new_map_size = 
01516       _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
01517 
01518     _Map_pointer __new_map = _M_allocate_map(__new_map_size);
01519     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
01520                          + (__add_at_front ? __nodes_to_add : 0);
01521     copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
01522     _M_deallocate_map(_M_map, _M_map_size);
01523 
01524     _M_map = __new_map;
01525     _M_map_size = __new_map_size;
01526   }
01527 
01528   _M_start._M_set_node(__new_nstart);
01529   _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
01530 }
01531 
01532 
01533 // Nonmember functions.
01534 
01535 template <class _Tp, class _Alloc>
01536 inline bool operator==(const deque<_Tp, _Alloc>& __x,
01537                        const deque<_Tp, _Alloc>& __y) {
01538   return __x.size() == __y.size() &&
01539          equal(__x.begin(), __x.end(), __y.begin());
01540 }
01541 
01542 template <class _Tp, class _Alloc>
01543 inline bool operator<(const deque<_Tp, _Alloc>& __x,
01544                       const deque<_Tp, _Alloc>& __y) {
01545   return lexicographical_compare(__x.begin(), __x.end(), 
01546                                  __y.begin(), __y.end());
01547 }
01548 
01549 template <class _Tp, class _Alloc>
01550 inline bool operator!=(const deque<_Tp, _Alloc>& __x,
01551                        const deque<_Tp, _Alloc>& __y) {
01552   return !(__x == __y);
01553 }
01554 
01555 template <class _Tp, class _Alloc>
01556 inline bool operator>(const deque<_Tp, _Alloc>& __x,
01557                       const deque<_Tp, _Alloc>& __y) {
01558   return __y < __x;
01559 }
01560 
01561 template <class _Tp, class _Alloc>
01562 inline bool operator<=(const deque<_Tp, _Alloc>& __x,
01563                        const deque<_Tp, _Alloc>& __y) {
01564   return !(__y < __x);
01565 }
01566 template <class _Tp, class _Alloc>
01567 inline bool operator>=(const deque<_Tp, _Alloc>& __x,
01568                        const deque<_Tp, _Alloc>& __y) {
01569   return !(__x < __y);
01570 }
01571 
01572 template <class _Tp, class _Alloc>
01573 inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
01574   __x.swap(__y);
01575 }
01576 
01577 } // namespace std 
01578   
01579 #endif /* __GLIBCPP_INTERNAL_DEQUE_H */
01580 

Generated on Wed May 1 19:19:36 2002 for libstdc++-v3 Source by doxygen1.2.15