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

Generated at Tue May 1 16:28:39 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001