stl_deque.h

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 <concept_checks.h>
00032 
00033 #ifndef __SGI_STL_INTERNAL_DEQUE_H
00034 #define __SGI_STL_INTERNAL_DEQUE_H
00035 
00036 /* Class invariants:
00037  *  For any nonsingular iterator i:
00038  *    i.node is the address of an element in the map array.  The
00039  *      contents of i.node is a pointer to the beginning of a node.
00040  *    i.first == *(i.node) 
00041  *    i.last  == i.first + node_size
00042  *    i.cur is a pointer in the range [i.first, i.last).  NOTE:
00043  *      the implication of this is that i.cur is always a dereferenceable
00044  *      pointer, even if i is a past-the-end iterator.
00045  *  Start and Finish are always nonsingular iterators.  NOTE: this means
00046  *    that an empty deque must have one node, and that a deque
00047  *    with N elements, where N is the buffer size, must have two nodes.
00048  *  For every node other than start.node and finish.node, every element
00049  *    in the node is an initialized object.  If start.node == finish.node,
00050  *    then [start.cur, finish.cur) are initialized objects, and
00051  *    the elements outside that range are uninitialized storage.  Otherwise,
00052  *    [start.cur, start.last) and [finish.first, finish.cur) are initialized
00053  *    objects, and [start.first, start.cur) and [finish.cur, finish.last)
00054  *    are uninitialized storage.
00055  *  [map, map + map_size) is a valid, non-empty range.  
00056  *  [start.node, finish.node] is a valid range contained within 
00057  *    [map, map + map_size).  
00058  *  A pointer in the range [map, map + map_size) points to an allocated node
00059  *    if and only if the pointer is in the range [start.node, finish.node].
00060  */
00061 
00062 
00063 /*
00064  * In previous versions of deque, there was an extra template 
00065  * parameter so users could control the node size.  This extension
00066  * turns out to violate the C++ standard (it can be detected using
00067  * template template parameters), and it has been removed.
00068  */
00069 
00070 __STL_BEGIN_NAMESPACE 
00071 
00072 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00073 #pragma set woff 1174
00074 #pragma set woff 1375
00075 #endif
00076 
00077 // Note: this function is simply a kludge to work around several compilers'
00078 //  bugs in handling constant expressions.
00079 inline size_t __deque_buf_size(size_t __size) {
00080   return __size < 512 ? size_t(512 / __size) : size_t(1);
00081 }
00082 
00083 template <class _Tp, class _Ref, class _Ptr>
00084 struct _Deque_iterator {
00085   typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
00086   typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
00087   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
00088 
00089   typedef random_access_iterator_tag iterator_category;
00090   typedef _Tp value_type;
00091   typedef _Ptr pointer;
00092   typedef _Ref reference;
00093   typedef size_t size_type;
00094   typedef ptrdiff_t difference_type;
00095   typedef _Tp** _Map_pointer;
00096 
00097   typedef _Deque_iterator _Self;
00098 
00099   _Tp* _M_cur;
00100   _Tp* _M_first;
00101   _Tp* _M_last;
00102   _Map_pointer _M_node;
00103 
00104   _Deque_iterator(_Tp* __x, _Map_pointer __y) 
00105     : _M_cur(__x), _M_first(*__y),
00106       _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
00107   _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
00108   _Deque_iterator(const iterator& __x)
00109     : _M_cur(__x._M_cur), _M_first(__x._M_first), 
00110       _M_last(__x._M_last), _M_node(__x._M_node) {}
00111 
00112   reference operator*() const { return *_M_cur; }
00113 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00114   pointer operator->() const { return _M_cur; }
00115 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
00116 
00117   difference_type operator-(const _Self& __x) const {
00118     return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
00119       (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
00120   }
00121 
00122   _Self& operator++() {
00123     ++_M_cur;
00124     if (_M_cur == _M_last) {
00125       _M_set_node(_M_node + 1);
00126       _M_cur = _M_first;
00127     }
00128     return *this; 
00129   }
00130   _Self operator++(int)  {
00131     _Self __tmp = *this;
00132     ++*this;
00133     return __tmp;
00134   }
00135 
00136   _Self& operator--() {
00137     if (_M_cur == _M_first) {
00138       _M_set_node(_M_node - 1);
00139       _M_cur = _M_last;
00140     }
00141     --_M_cur;
00142     return *this;
00143   }
00144   _Self operator--(int) {
00145     _Self __tmp = *this;
00146     --*this;
00147     return __tmp;
00148   }
00149 
00150   _Self& operator+=(difference_type __n)
00151   {
00152     difference_type __offset = __n + (_M_cur - _M_first);
00153     if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
00154       _M_cur += __n;
00155     else {
00156       difference_type __node_offset =
00157         __offset > 0 ? __offset / difference_type(_S_buffer_size())
00158                    : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
00159       _M_set_node(_M_node + __node_offset);
00160       _M_cur = _M_first + 
00161         (__offset - __node_offset * difference_type(_S_buffer_size()));
00162     }
00163     return *this;
00164   }
00165 
00166   _Self operator+(difference_type __n) const
00167   {
00168     _Self __tmp = *this;
00169     return __tmp += __n;
00170   }
00171 
00172   _Self& operator-=(difference_type __n) { return *this += -__n; }
00173  
00174   _Self operator-(difference_type __n) const {
00175     _Self __tmp = *this;
00176     return __tmp -= __n;
00177   }
00178 
00179   reference operator[](difference_type __n) const { return *(*this + __n); }
00180 
00181   bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
00182   bool operator!=(const _Self& __x) const { return !(*this == __x); }
00183   bool operator<(const _Self& __x) const {
00184     return (_M_node == __x._M_node) ? 
00185       (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
00186   }
00187   bool operator>(const _Self& __x) const  { return __x < *this; }
00188   bool operator<=(const _Self& __x) const { return !(__x < *this); }
00189   bool operator>=(const _Self& __x) const { return !(*this < __x); }
00190 
00191   void _M_set_node(_Map_pointer __new_node) {
00192     _M_node = __new_node;
00193     _M_first = *__new_node;
00194     _M_last = _M_first + difference_type(_S_buffer_size());
00195   }
00196 };
00197 
00198 template <class _Tp, class _Ref, class _Ptr>
00199 inline _Deque_iterator<_Tp, _Ref, _Ptr>
00200 operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
00201 {
00202   return __x + __n;
00203 }
00204 
00205 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
00206 
00207 template <class _Tp, class _Ref, class _Ptr>
00208 inline random_access_iterator_tag
00209 iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&)
00210 {
00211   return random_access_iterator_tag();
00212 }
00213 
00214 template <class _Tp, class _Ref, class _Ptr>
00215 inline _Tp* value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; }
00216 
00217 template <class _Tp, class _Ref, class _Ptr>
00218 inline ptrdiff_t* distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) {
00219   return 0;
00220 }
00221 
00222 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00223 
00224 // Deque base class.  It has two purposes.  First, its constructor
00225 //  and destructor allocate (but don't initialize) storage.  This makes
00226 //  exception safety easier.  Second, the base class encapsulates all of
00227 //  the differences between SGI-style allocators and standard-conforming
00228 //  allocators.
00229 
00230 #ifdef __STL_USE_STD_ALLOCATORS
00231 
00232 // Base class for ordinary allocators.
00233 template <class _Tp, class _Alloc, bool __is_static>
00234 class _Deque_alloc_base {
00235 public:
00236   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00237   allocator_type get_allocator() const { return _M_node_allocator; }
00238 
00239   _Deque_alloc_base(const allocator_type& __a)
00240     : _M_node_allocator(__a), _M_map_allocator(__a),
00241       _M_map(0), _M_map_size(0)
00242   {}
00243   
00244 protected:
00245   typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
00246           _Map_allocator_type;
00247 
00248   allocator_type      _M_node_allocator;
00249   _Map_allocator_type _M_map_allocator;
00250 
00251   _Tp* _M_allocate_node() {
00252     return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
00253   }
00254   void _M_deallocate_node(_Tp* __p) {
00255     _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
00256   }
00257   _Tp** _M_allocate_map(size_t __n) 
00258     { return _M_map_allocator.allocate(__n); }
00259   void _M_deallocate_map(_Tp** __p, size_t __n) 
00260     { _M_map_allocator.deallocate(__p, __n); }
00261 
00262   _Tp** _M_map;
00263   size_t _M_map_size;
00264 };
00265 
00266 // Specialization for instanceless allocators.
00267 template <class _Tp, class _Alloc>
00268 class _Deque_alloc_base<_Tp, _Alloc, true>
00269 {
00270 public:
00271   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
00272   allocator_type get_allocator() const { return allocator_type(); }
00273 
00274   _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
00275   
00276 protected:
00277   typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
00278   typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
00279 
00280   _Tp* _M_allocate_node() {
00281     return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
00282   }
00283   void _M_deallocate_node(_Tp* __p) {
00284     _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
00285   }
00286   _Tp** _M_allocate_map(size_t __n) 
00287     { return _Map_alloc_type::allocate(__n); }
00288   void _M_deallocate_map(_Tp** __p, size_t __n) 
00289     { _Map_alloc_type::deallocate(__p, __n); }
00290 
00291   _Tp** _M_map;
00292   size_t _M_map_size;
00293 };
00294 
00295 template <class _Tp, class _Alloc>
00296 class _Deque_base
00297   : public _Deque_alloc_base<_Tp,_Alloc,
00298                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00299 {
00300 public:
00301   typedef _Deque_alloc_base<_Tp,_Alloc,
00302                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00303           _Base;
00304   typedef typename _Base::allocator_type allocator_type;
00305   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
00306   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00307 
00308   _Deque_base(const allocator_type& __a, size_t __num_elements)
00309     : _Base(__a), _M_start(), _M_finish()
00310     { _M_initialize_map(__num_elements); }
00311   _Deque_base(const allocator_type& __a) 
00312     : _Base(__a), _M_start(), _M_finish() {}
00313   ~_Deque_base();    
00314 
00315 protected:
00316   void _M_initialize_map(size_t);
00317   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
00318   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
00319   enum { _S_initial_map_size = 8 };
00320 
00321 protected:
00322   iterator _M_start;
00323   iterator _M_finish;
00324 };
00325 
00326 #else /* __STL_USE_STD_ALLOCATORS */
00327 
00328 template <class _Tp, class _Alloc>
00329 class _Deque_base {
00330 public:
00331   typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
00332   typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00333 
00334   typedef _Alloc allocator_type;
00335   allocator_type get_allocator() const { return allocator_type(); }
00336 
00337   _Deque_base(const allocator_type&, size_t __num_elements)
00338     : _M_map(0), _M_map_size(0),  _M_start(), _M_finish() {
00339     _M_initialize_map(__num_elements);
00340   }
00341   _Deque_base(const allocator_type&)
00342     : _M_map(0), _M_map_size(0),  _M_start(), _M_finish() {}
00343   ~_Deque_base();    
00344 
00345 protected:
00346   void _M_initialize_map(size_t);
00347   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
00348   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
00349   enum { _S_initial_map_size = 8 };
00350 
00351 protected:
00352   _Tp** _M_map;
00353   size_t _M_map_size;  
00354   iterator _M_start;
00355   iterator _M_finish;
00356 
00357   typedef simple_alloc<_Tp, _Alloc>  _Node_alloc_type;
00358   typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type;
00359 
00360   _Tp* _M_allocate_node()
00361     { return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp))); }
00362   void _M_deallocate_node(_Tp* __p)
00363     { _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); }
00364   _Tp** _M_allocate_map(size_t __n) 
00365     { return _Map_alloc_type::allocate(__n); }
00366   void _M_deallocate_map(_Tp** __p, size_t __n) 
00367     { _Map_alloc_type::deallocate(__p, __n); }
00368 };
00369 
00370 #endif /* __STL_USE_STD_ALLOCATORS */
00371 
00372 // Non-inline member functions from _Deque_base.
00373 
00374 template <class _Tp, class _Alloc>
00375 _Deque_base<_Tp,_Alloc>::~_Deque_base() {
00376   if (_M_map) {
00377     _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
00378     _M_deallocate_map(_M_map, _M_map_size);
00379   }
00380 }
00381 
00382 template <class _Tp, class _Alloc>
00383 void
00384 _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
00385 {
00386   size_t __num_nodes = 
00387     __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
00388 
00389   _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
00390   _M_map = _M_allocate_map(_M_map_size);
00391 
00392   _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
00393   _Tp** __nfinish = __nstart + __num_nodes;
00394     
00395   __STL_TRY {
00396     _M_create_nodes(__nstart, __nfinish);
00397   }
00398   __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), 
00399                 _M_map = 0, _M_map_size = 0));
00400   _M_start._M_set_node(__nstart);
00401   _M_finish._M_set_node(__nfinish - 1);
00402   _M_start._M_cur = _M_start._M_first;
00403   _M_finish._M_cur = _M_finish._M_first +
00404                __num_elements % __deque_buf_size(sizeof(_Tp));
00405 }
00406 
00407 template <class _Tp, class _Alloc>
00408 void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
00409 {
00410   _Tp** __cur;
00411   __STL_TRY {
00412     for (__cur = __nstart; __cur < __nfinish; ++__cur)
00413       *__cur = _M_allocate_node();
00414   }
00415   __STL_UNWIND(_M_destroy_nodes(__nstart, __cur));
00416 }
00417 
00418 template <class _Tp, class _Alloc>
00419 void
00420 _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
00421 {
00422   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
00423     _M_deallocate_node(*__n);
00424 }
00425 
00426 template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
00427 class deque : protected _Deque_base<_Tp, _Alloc> {
00428 
00429   // requirements:
00430 
00431   __STL_CLASS_REQUIRES(_Tp, _Assignable);
00432 
00433   typedef _Deque_base<_Tp, _Alloc> _Base;
00434 public:                         // Basic types
00435   typedef _Tp value_type;
00436   typedef value_type* pointer;
00437   typedef const value_type* const_pointer;
00438   typedef value_type& reference;
00439   typedef const value_type& const_reference;
00440   typedef size_t size_type;
00441   typedef ptrdiff_t difference_type;
00442 
00443   typedef typename _Base::allocator_type allocator_type;
00444   allocator_type get_allocator() const { return _Base::get_allocator(); }
00445 
00446 public:                         // Iterators
00447   typedef typename _Base::iterator       iterator;
00448   typedef typename _Base::const_iterator const_iterator;
00449 
00450 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
00451   typedef reverse_iterator<const_iterator> const_reverse_iterator;
00452   typedef reverse_iterator<iterator> reverse_iterator;
00453 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00454   typedef reverse_iterator<const_iterator, value_type, const_reference, 
00455                            difference_type>  
00456           const_reverse_iterator;
00457   typedef reverse_iterator<iterator, value_type, reference, difference_type>
00458           reverse_iterator; 
00459 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00460 
00461 protected:                      // Internal typedefs
00462   typedef pointer* _Map_pointer;
00463   static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
00464 
00465 protected:
00466 #ifdef __STL_USE_NAMESPACES
00467   using _Base::_M_initialize_map;
00468   using _Base::_M_create_nodes;
00469   using _Base::_M_destroy_nodes;
00470   using _Base::_M_allocate_node;
00471   using _Base::_M_deallocate_node;
00472   using _Base::_M_allocate_map;
00473   using _Base::_M_deallocate_map;
00474 
00475   using _Base::_M_map;
00476   using _Base::_M_map_size;
00477   using _Base::_M_start;
00478   using _Base::_M_finish;
00479 #endif /* __STL_USE_NAMESPACES */
00480 
00481 public:                         // Basic accessors
00482   iterator begin() { return _M_start; }
00483   iterator end() { return _M_finish; }
00484   const_iterator begin() const { return _M_start; }
00485   const_iterator end() const { return _M_finish; }
00486 
00487   reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
00488   reverse_iterator rend() { return reverse_iterator(_M_start); }
00489   const_reverse_iterator rbegin() const 
00490     { return const_reverse_iterator(_M_finish); }
00491   const_reverse_iterator rend() const 
00492     { return const_reverse_iterator(_M_start); }
00493 
00494   reference operator[](size_type __n)
00495     { return _M_start[difference_type(__n)]; }
00496   const_reference operator[](size_type __n) const 
00497     { return _M_start[difference_type(__n)]; }
00498 
00499 #ifdef __STL_THROW_RANGE_ERRORS
00500   void _M_range_check(size_type __n) const {
00501     if (__n >= this->size())
00502       __stl_throw_range_error("deque");
00503   }
00504 
00505   reference at(size_type __n)
00506     { _M_range_check(__n); return (*this)[__n]; }
00507   const_reference at(size_type __n) const
00508     { _M_range_check(__n); return (*this)[__n]; }
00509 #endif /* __STL_THROW_RANGE_ERRORS */
00510 
00511   reference front() { return *_M_start; }
00512   reference back() {
00513     iterator __tmp = _M_finish;
00514     --__tmp;
00515     return *__tmp;
00516   }
00517   const_reference front() const { return *_M_start; }
00518   const_reference back() const {
00519     const_iterator __tmp = _M_finish;
00520     --__tmp;
00521     return *__tmp;
00522   }
00523 
00524   size_type size() const { return _M_finish - _M_start; }
00525   size_type max_size() const { return size_type(-1); }
00526   bool empty() const { return _M_finish == _M_start; }
00527 
00528 public:                         // Constructor, destructor.
00529   explicit deque(const allocator_type& __a = allocator_type()) 
00530     : _Base(__a, 0) {}
00531   deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) 
00532     { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
00533   deque(size_type __n, const value_type& __value,
00534         const allocator_type& __a = allocator_type()) : _Base(__a, __n)
00535     { _M_fill_initialize(__value); }
00536   explicit deque(size_type __n) : _Base(allocator_type(), __n)
00537     { _M_fill_initialize(value_type()); }
00538 
00539 #ifdef __STL_MEMBER_TEMPLATES
00540 
00541   // Check whether it's an integral type.  If so, it's not an iterator.
00542   template <class _InputIterator>
00543   deque(_InputIterator __first, _InputIterator __last,
00544         const allocator_type& __a = allocator_type()) : _Base(__a) {
00545     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00546     _M_initialize_dispatch(__first, __last, _Integral());
00547   }
00548 
00549   template <class _Integer>
00550   void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
00551     _M_initialize_map(__n);
00552     _M_fill_initialize(__x);
00553   }
00554 
00555   template <class _InputIter>
00556   void _M_initialize_dispatch(_InputIter __first, _InputIter __last,
00557                               __false_type) {
00558     _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
00559   }
00560 
00561 #else /* __STL_MEMBER_TEMPLATES */
00562 
00563   deque(const value_type* __first, const value_type* __last,
00564         const allocator_type& __a = allocator_type()) 
00565     : _Base(__a, __last - __first)
00566     { uninitialized_copy(__first, __last, _M_start); }
00567   deque(const_iterator __first, const_iterator __last,
00568         const allocator_type& __a = allocator_type()) 
00569     : _Base(__a, __last - __first)
00570     { uninitialized_copy(__first, __last, _M_start); }
00571 
00572 #endif /* __STL_MEMBER_TEMPLATES */
00573 
00574   ~deque() { destroy(_M_start, _M_finish); }
00575 
00576   deque& operator= (const deque& __x) {
00577     const size_type __len = size();
00578     if (&__x != this) {
00579       if (__len >= __x.size())
00580         erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
00581       else {
00582         const_iterator __mid = __x.begin() + difference_type(__len);
00583         copy(__x.begin(), __mid, _M_start);
00584         insert(_M_finish, __mid, __x.end());
00585       }
00586     }
00587     return *this;
00588   }        
00589 
00590   void swap(deque& __x) {
00591     __STD::swap(_M_start, __x._M_start);
00592     __STD::swap(_M_finish, __x._M_finish);
00593     __STD::swap(_M_map, __x._M_map);
00594     __STD::swap(_M_map_size, __x._M_map_size);
00595   }
00596 
00597 public: 
00598   // assign(), a generalized assignment member function.  Two
00599   // versions: one that takes a count, and one that takes a range.
00600   // The range version is a member template, so we dispatch on whether
00601   // or not the type is an integer.
00602 
00603   void _M_fill_assign(size_type __n, const _Tp& __val) {
00604     if (__n > size()) {
00605       fill(begin(), end(), __val);
00606       insert(end(), __n - size(), __val);
00607     }
00608     else {
00609       erase(begin() + __n, end());
00610       fill(begin(), end(), __val);
00611     }
00612   }
00613 
00614   void assign(size_type __n, const _Tp& __val) {
00615     _M_fill_assign(__n, __val);
00616   }
00617 
00618 #ifdef __STL_MEMBER_TEMPLATES
00619 
00620   template <class _InputIterator>
00621   void assign(_InputIterator __first, _InputIterator __last) {
00622     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00623     _M_assign_dispatch(__first, __last, _Integral());
00624   }
00625 
00626 private:                        // helper functions for assign() 
00627 
00628   template <class _Integer>
00629   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00630     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00631 
00632   template <class _InputIterator>
00633   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00634                           __false_type) {
00635     _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first));
00636   }
00637 
00638   template <class _InputIterator>
00639   void _M_assign_aux(_InputIterator __first, _InputIterator __last,
00640                      input_iterator_tag);
00641 
00642   template <class _ForwardIterator>
00643   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00644                      forward_iterator_tag) {
00645     size_type __len = 0;
00646     distance(__first, __last, __len);
00647     if (__len > size()) {
00648       _ForwardIterator __mid = __first;
00649       advance(__mid, size());
00650       copy(__first, __mid, begin());
00651       insert(end(), __mid, __last);
00652     }
00653     else
00654       erase(copy(__first, __last, begin()), end());
00655   }
00656 
00657 #endif /* __STL_MEMBER_TEMPLATES */
00658 
00659 public:                         // push_* and pop_*
00660   
00661   void push_back(const value_type& __t) {
00662     if (_M_finish._M_cur != _M_finish._M_last - 1) {
00663       construct(_M_finish._M_cur, __t);
00664       ++_M_finish._M_cur;
00665     }
00666     else
00667       _M_push_back_aux(__t);
00668   }
00669 
00670   void push_back() {
00671     if (_M_finish._M_cur != _M_finish._M_last - 1) {
00672       construct(_M_finish._M_cur);
00673       ++_M_finish._M_cur;
00674     }
00675     else
00676       _M_push_back_aux();
00677   }
00678 
00679   void push_front(const value_type& __t) {
00680     if (_M_start._M_cur != _M_start._M_first) {
00681       construct(_M_start._M_cur - 1, __t);
00682       --_M_start._M_cur;
00683     }
00684     else
00685       _M_push_front_aux(__t);
00686   }
00687 
00688   void push_front() {
00689     if (_M_start._M_cur != _M_start._M_first) {
00690       construct(_M_start._M_cur - 1);
00691       --_M_start._M_cur;
00692     }
00693     else
00694       _M_push_front_aux();
00695   }
00696 
00697 
00698   void pop_back() {
00699     if (_M_finish._M_cur != _M_finish._M_first) {
00700       --_M_finish._M_cur;
00701       destroy(_M_finish._M_cur);
00702     }
00703     else
00704       _M_pop_back_aux();
00705   }
00706 
00707   void pop_front() {
00708     if (_M_start._M_cur != _M_start._M_last - 1) {
00709       destroy(_M_start._M_cur);
00710       ++_M_start._M_cur;
00711     }
00712     else 
00713       _M_pop_front_aux();
00714   }
00715 
00716 public:                         // Insert
00717 
00718   iterator insert(iterator position, const value_type& __x) {
00719     if (position._M_cur == _M_start._M_cur) {
00720       push_front(__x);
00721       return _M_start;
00722     }
00723     else if (position._M_cur == _M_finish._M_cur) {
00724       push_back(__x);
00725       iterator __tmp = _M_finish;
00726       --__tmp;
00727       return __tmp;
00728     }
00729     else {
00730       return _M_insert_aux(position, __x);
00731     }
00732   }
00733 
00734   iterator insert(iterator __position)
00735     { return insert(__position, value_type()); }
00736 
00737   void insert(iterator __pos, size_type __n, const value_type& __x)
00738     { _M_fill_insert(__pos, __n, __x); }
00739 
00740   void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
00741 
00742 #ifdef __STL_MEMBER_TEMPLATES  
00743 
00744   // Check whether it's an integral type.  If so, it's not an iterator.
00745   template <class _InputIterator>
00746   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00747     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00748     _M_insert_dispatch(__pos, __first, __last, _Integral());
00749   }
00750 
00751   template <class _Integer>
00752   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
00753                           __true_type) {
00754     _M_fill_insert(__pos, (size_type) __n, (value_type) __x);
00755   }
00756 
00757   template <class _InputIterator>
00758   void _M_insert_dispatch(iterator __pos,
00759                           _InputIterator __first, _InputIterator __last,
00760                           __false_type) {
00761     insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
00762   }
00763 
00764 #else /* __STL_MEMBER_TEMPLATES */
00765 
00766   void insert(iterator __pos,
00767               const value_type* __first, const value_type* __last);
00768   void insert(iterator __pos,
00769               const_iterator __first, const_iterator __last);
00770 
00771 #endif /* __STL_MEMBER_TEMPLATES */
00772 
00773   void resize(size_type __new_size, const value_type& __x) {
00774     const size_type __len = size();
00775     if (__new_size < __len) 
00776       erase(_M_start + __new_size, _M_finish);
00777     else
00778       insert(_M_finish, __new_size - __len, __x);
00779   }
00780 
00781   void resize(size_type new_size) { resize(new_size, value_type()); }
00782 
00783 public:                         // Erase
00784   iterator erase(iterator __pos) {
00785     iterator __next = __pos;
00786     ++__next;
00787     difference_type __index = __pos - _M_start;
00788     if (size_type(__index) < (this->size() >> 1)) {
00789       copy_backward(_M_start, __pos, __next);
00790       pop_front();
00791     }
00792     else {
00793       copy(__next, _M_finish, __pos);
00794       pop_back();
00795     }
00796     return _M_start + __index;
00797   }
00798 
00799   iterator erase(iterator __first, iterator __last);
00800   void clear(); 
00801 
00802 protected:                        // Internal construction/destruction
00803 
00804   void _M_fill_initialize(const value_type& __value);
00805 
00806 #ifdef __STL_MEMBER_TEMPLATES  
00807 
00808   template <class _InputIterator>
00809   void _M_range_initialize(_InputIterator __first, _InputIterator __last,
00810                         input_iterator_tag);
00811 
00812   template <class _ForwardIterator>
00813   void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
00814                         forward_iterator_tag);
00815 
00816 #endif /* __STL_MEMBER_TEMPLATES */
00817 
00818 protected:                        // Internal push_* and pop_*
00819 
00820   void _M_push_back_aux(const value_type&);
00821   void _M_push_back_aux();
00822   void _M_push_front_aux(const value_type&);
00823   void _M_push_front_aux();
00824   void _M_pop_back_aux();
00825   void _M_pop_front_aux();
00826 
00827 protected:                        // Internal insert functions
00828 
00829 #ifdef __STL_MEMBER_TEMPLATES  
00830 
00831   template <class _InputIterator>
00832   void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
00833               input_iterator_tag);
00834 
00835   template <class _ForwardIterator>
00836   void insert(iterator __pos,
00837               _ForwardIterator __first, _ForwardIterator __last,
00838               forward_iterator_tag);
00839 
00840 #endif /* __STL_MEMBER_TEMPLATES */
00841 
00842   iterator _M_insert_aux(iterator __pos, const value_type& __x);
00843   iterator _M_insert_aux(iterator __pos);
00844   void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
00845 
00846 #ifdef __STL_MEMBER_TEMPLATES  
00847 
00848   template <class _ForwardIterator>
00849   void _M_insert_aux(iterator __pos, 
00850                      _ForwardIterator __first, _ForwardIterator __last,
00851                      size_type __n);
00852 
00853 #else /* __STL_MEMBER_TEMPLATES */
00854   
00855   void _M_insert_aux(iterator __pos,
00856                      const value_type* __first, const value_type* __last,
00857                      size_type __n);
00858 
00859   void _M_insert_aux(iterator __pos, 
00860                      const_iterator __first, const_iterator __last,
00861                      size_type __n);
00862  
00863 #endif /* __STL_MEMBER_TEMPLATES */
00864 
00865   iterator _M_reserve_elements_at_front(size_type __n) {
00866     size_type __vacancies = _M_start._M_cur - _M_start._M_first;
00867     if (__n > __vacancies) 
00868       _M_new_elements_at_front(__n - __vacancies);
00869     return _M_start - difference_type(__n);
00870   }
00871 
00872   iterator _M_reserve_elements_at_back(size_type __n) {
00873     size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
00874     if (__n > __vacancies)
00875       _M_new_elements_at_back(__n - __vacancies);
00876     return _M_finish + difference_type(__n);
00877   }
00878 
00879   void _M_new_elements_at_front(size_type __new_elements);
00880   void _M_new_elements_at_back(size_type __new_elements);
00881 
00882 protected:                      // Allocation of _M_map and nodes
00883 
00884   // Makes sure the _M_map has space for new nodes.  Does not actually
00885   //  add the nodes.  Can invalidate _M_map pointers.  (And consequently, 
00886   //  deque iterators.)
00887 
00888   void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
00889     if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
00890       _M_reallocate_map(__nodes_to_add, false);
00891   }
00892 
00893   void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
00894     if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
00895       _M_reallocate_map(__nodes_to_add, true);
00896   }
00897 
00898   void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
00899 };
00900 
00901 // Non-inline member functions
00902 
00903 #ifdef __STL_MEMBER_TEMPLATES
00904 
00905 template <class _Tp, class _Alloc>
00906 template <class _InputIter>
00907 void deque<_Tp, _Alloc>
00908   ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
00909 {
00910   iterator __cur = begin();
00911   for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00912     *__cur = *__first;
00913   if (__first == __last)
00914     erase(__cur, end());
00915   else
00916     insert(end(), __first, __last);
00917 }
00918 
00919 #endif /* __STL_MEMBER_TEMPLATES */
00920 
00921 template <class _Tp, class _Alloc>
00922 void deque<_Tp, _Alloc>::_M_fill_insert(iterator __pos,
00923                                         size_type __n, const value_type& __x)
00924 {
00925   if (__pos._M_cur == _M_start._M_cur) {
00926     iterator __new_start = _M_reserve_elements_at_front(__n);
00927     __STL_TRY {
00928       uninitialized_fill(__new_start, _M_start, __x);
00929       _M_start = __new_start;
00930     }
00931     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
00932   }
00933   else if (__pos._M_cur == _M_finish._M_cur) {
00934     iterator __new_finish = _M_reserve_elements_at_back(__n);
00935     __STL_TRY {
00936       uninitialized_fill(_M_finish, __new_finish, __x);
00937       _M_finish = __new_finish;
00938     }
00939     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
00940                                   __new_finish._M_node + 1));    
00941   }
00942   else 
00943     _M_insert_aux(__pos, __n, __x);
00944 }
00945 
00946 #ifndef __STL_MEMBER_TEMPLATES  
00947 
00948 template <class _Tp, class _Alloc>
00949 void deque<_Tp, _Alloc>::insert(iterator __pos,
00950                                 const value_type* __first,
00951                                 const value_type* __last) {
00952   size_type __n = __last - __first;
00953   if (__pos._M_cur == _M_start._M_cur) {
00954     iterator __new_start = _M_reserve_elements_at_front(__n);
00955     __STL_TRY {
00956       uninitialized_copy(__first, __last, __new_start);
00957       _M_start = __new_start;
00958     }
00959     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
00960   }
00961   else if (__pos._M_cur == _M_finish._M_cur) {
00962     iterator __new_finish = _M_reserve_elements_at_back(__n);
00963     __STL_TRY {
00964       uninitialized_copy(__first, __last, _M_finish);
00965       _M_finish = __new_finish;
00966     }
00967     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
00968                                   __new_finish._M_node + 1));
00969   }
00970   else
00971     _M_insert_aux(__pos, __first, __last, __n);
00972 }
00973 
00974 template <class _Tp, class _Alloc>
00975 void deque<_Tp,_Alloc>::insert(iterator __pos,
00976                                const_iterator __first, const_iterator __last)
00977 {
00978   size_type __n = __last - __first;
00979   if (__pos._M_cur == _M_start._M_cur) {
00980     iterator __new_start = _M_reserve_elements_at_front(__n);
00981     __STL_TRY {
00982       uninitialized_copy(__first, __last, __new_start);
00983       _M_start = __new_start;
00984     }
00985     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
00986   }
00987   else if (__pos._M_cur == _M_finish._M_cur) {
00988     iterator __new_finish = _M_reserve_elements_at_back(__n);
00989     __STL_TRY {
00990       uninitialized_copy(__first, __last, _M_finish);
00991       _M_finish = __new_finish;
00992     }
00993     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
00994                  __new_finish._M_node + 1));
00995   }
00996   else
00997     _M_insert_aux(__pos, __first, __last, __n);
00998 }
00999 
01000 #endif /* __STL_MEMBER_TEMPLATES */
01001 
01002 template <class _Tp, class _Alloc>
01003 typename deque<_Tp,_Alloc>::iterator 
01004 deque<_Tp,_Alloc>::erase(iterator __first, iterator __last)
01005 {
01006   if (__first == _M_start && __last == _M_finish) {
01007     clear();
01008     return _M_finish;
01009   }
01010   else {
01011     difference_type __n = __last - __first;
01012     difference_type __elems_before = __first - _M_start;
01013     if (__elems_before < difference_type((this->size() - __n) / 2)) {
01014       copy_backward(_M_start, __first, __last);
01015       iterator __new_start = _M_start + __n;
01016       destroy(_M_start, __new_start);
01017       _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
01018       _M_start = __new_start;
01019     }
01020     else {
01021       copy(__last, _M_finish, __first);
01022       iterator __new_finish = _M_finish - __n;
01023       destroy(__new_finish, _M_finish);
01024       _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
01025       _M_finish = __new_finish;
01026     }
01027     return _M_start + __elems_before;
01028   }
01029 }
01030 
01031 template <class _Tp, class _Alloc> 
01032 void deque<_Tp,_Alloc>::clear()
01033 {
01034   for (_Map_pointer __node = _M_start._M_node + 1;
01035        __node < _M_finish._M_node;
01036        ++__node) {
01037     destroy(*__node, *__node + _S_buffer_size());
01038     _M_deallocate_node(*__node);
01039   }
01040 
01041   if (_M_start._M_node != _M_finish._M_node) {
01042     destroy(_M_start._M_cur, _M_start._M_last);
01043     destroy(_M_finish._M_first, _M_finish._M_cur);
01044     _M_deallocate_node(_M_finish._M_first);
01045   }
01046   else
01047     destroy(_M_start._M_cur, _M_finish._M_cur);
01048 
01049   _M_finish = _M_start;
01050 }
01051 
01052 // Precondition: _M_start and _M_finish have already been initialized,
01053 // but none of the deque's elements have yet been constructed.
01054 template <class _Tp, class _Alloc>
01055 void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __value) {
01056   _Map_pointer __cur;
01057   __STL_TRY {
01058     for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
01059       uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
01060     uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
01061   }
01062   __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur)));
01063 }
01064 
01065 #ifdef __STL_MEMBER_TEMPLATES  
01066 
01067 template <class _Tp, class _Alloc> template <class _InputIterator>
01068 void deque<_Tp,_Alloc>::_M_range_initialize(_InputIterator __first,
01069                                             _InputIterator __last,
01070                                             input_iterator_tag)
01071 {
01072   _M_initialize_map(0);
01073   __STL_TRY {
01074     for ( ; __first != __last; ++__first)
01075       push_back(*__first);
01076   }
01077   __STL_UNWIND(clear());
01078 }
01079 
01080 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01081 void deque<_Tp,_Alloc>::_M_range_initialize(_ForwardIterator __first,
01082                                             _ForwardIterator __last,
01083                                             forward_iterator_tag)
01084 {
01085   size_type __n = 0;
01086   distance(__first, __last, __n);
01087   _M_initialize_map(__n);
01088 
01089   _Map_pointer __cur_node;
01090   __STL_TRY {
01091     for (__cur_node = _M_start._M_node; 
01092          __cur_node < _M_finish._M_node; 
01093          ++__cur_node) {
01094       _ForwardIterator __mid = __first;
01095       advance(__mid, _S_buffer_size());
01096       uninitialized_copy(__first, __mid, *__cur_node);
01097       __first = __mid;
01098     }
01099     uninitialized_copy(__first, __last, _M_finish._M_first);
01100   }
01101   __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node)));
01102 }
01103 
01104 #endif /* __STL_MEMBER_TEMPLATES */
01105 
01106 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
01107 template <class _Tp, class _Alloc>
01108 void deque<_Tp,_Alloc>::_M_push_back_aux(const value_type& __t)
01109 {
01110   value_type __t_copy = __t;
01111   _M_reserve_map_at_back();
01112   *(_M_finish._M_node + 1) = _M_allocate_node();
01113   __STL_TRY {
01114     construct(_M_finish._M_cur, __t_copy);
01115     _M_finish._M_set_node(_M_finish._M_node + 1);
01116     _M_finish._M_cur = _M_finish._M_first;
01117   }
01118   __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
01119 }
01120 
01121 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
01122 template <class _Tp, class _Alloc>
01123 void deque<_Tp,_Alloc>::_M_push_back_aux()
01124 {
01125   _M_reserve_map_at_back();
01126   *(_M_finish._M_node + 1) = _M_allocate_node();
01127   __STL_TRY {
01128     construct(_M_finish._M_cur);
01129     _M_finish._M_set_node(_M_finish._M_node + 1);
01130     _M_finish._M_cur = _M_finish._M_first;
01131   }
01132   __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
01133 }
01134 
01135 // Called only if _M_start._M_cur == _M_start._M_first.
01136 template <class _Tp, class _Alloc>
01137 void  deque<_Tp,_Alloc>::_M_push_front_aux(const value_type& __t)
01138 {
01139   value_type __t_copy = __t;
01140   _M_reserve_map_at_front();
01141   *(_M_start._M_node - 1) = _M_allocate_node();
01142   __STL_TRY {
01143     _M_start._M_set_node(_M_start._M_node - 1);
01144     _M_start._M_cur = _M_start._M_last - 1;
01145     construct(_M_start._M_cur, __t_copy);
01146   }
01147   __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
01148 } 
01149 
01150 // Called only if _M_start._M_cur == _M_start._M_first.
01151 template <class _Tp, class _Alloc>
01152 void deque<_Tp,_Alloc>::_M_push_front_aux()
01153 {
01154   _M_reserve_map_at_front();
01155   *(_M_start._M_node - 1) = _M_allocate_node();
01156   __STL_TRY {
01157     _M_start._M_set_node(_M_start._M_node - 1);
01158     _M_start._M_cur = _M_start._M_last - 1;
01159     construct(_M_start._M_cur);
01160   }
01161   __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
01162 } 
01163 
01164 // Called only if _M_finish._M_cur == _M_finish._M_first.
01165 template <class _Tp, class _Alloc>
01166 void deque<_Tp,_Alloc>::_M_pop_back_aux()
01167 {
01168   _M_deallocate_node(_M_finish._M_first);
01169   _M_finish._M_set_node(_M_finish._M_node - 1);
01170   _M_finish._M_cur = _M_finish._M_last - 1;
01171   destroy(_M_finish._M_cur);
01172 }
01173 
01174 // Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
01175 // if the deque has at least one element (a precondition for this member 
01176 // function), and if _M_start._M_cur == _M_start._M_last, then the deque 
01177 // must have at least two nodes.
01178 template <class _Tp, class _Alloc>
01179 void deque<_Tp,_Alloc>::_M_pop_front_aux()
01180 {
01181   destroy(_M_start._M_cur);
01182   _M_deallocate_node(_M_start._M_first);
01183   _M_start._M_set_node(_M_start._M_node + 1);
01184   _M_start._M_cur = _M_start._M_first;
01185 }      
01186 
01187 #ifdef __STL_MEMBER_TEMPLATES  
01188 
01189 template <class _Tp, class _Alloc> template <class _InputIterator>
01190 void deque<_Tp,_Alloc>::insert(iterator __pos,
01191                                _InputIterator __first, _InputIterator __last,
01192                                input_iterator_tag)
01193 {
01194   copy(__first, __last, inserter(*this, __pos));
01195 }
01196 
01197 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01198 void
01199 deque<_Tp,_Alloc>::insert(iterator __pos,
01200                           _ForwardIterator __first, _ForwardIterator __last,
01201                           forward_iterator_tag) {
01202   size_type __n = 0;
01203   distance(__first, __last, __n);
01204   if (__pos._M_cur == _M_start._M_cur) {
01205     iterator __new_start = _M_reserve_elements_at_front(__n);
01206     __STL_TRY {
01207       uninitialized_copy(__first, __last, __new_start);
01208       _M_start = __new_start;
01209     }
01210     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01211   }
01212   else if (__pos._M_cur == _M_finish._M_cur) {
01213     iterator __new_finish = _M_reserve_elements_at_back(__n);
01214     __STL_TRY {
01215       uninitialized_copy(__first, __last, _M_finish);
01216       _M_finish = __new_finish;
01217     }
01218     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01219                                   __new_finish._M_node + 1));
01220   }
01221   else
01222     _M_insert_aux(__pos, __first, __last, __n);
01223 }
01224 
01225 #endif /* __STL_MEMBER_TEMPLATES */
01226 
01227 template <class _Tp, class _Alloc>
01228 typename deque<_Tp, _Alloc>::iterator
01229 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos, const value_type& __x)
01230 {
01231   difference_type __index = __pos - _M_start;
01232   value_type __x_copy = __x;
01233   if (size_type(__index) < this->size() / 2) {
01234     push_front(front());
01235     iterator __front1 = _M_start;
01236     ++__front1;
01237     iterator __front2 = __front1;
01238     ++__front2;
01239     __pos = _M_start + __index;
01240     iterator __pos1 = __pos;
01241     ++__pos1;
01242     copy(__front2, __pos1, __front1);
01243   }
01244   else {
01245     push_back(back());
01246     iterator __back1 = _M_finish;
01247     --__back1;
01248     iterator __back2 = __back1;
01249     --__back2;
01250     __pos = _M_start + __index;
01251     copy_backward(__pos, __back2, __back1);
01252   }
01253   *__pos = __x_copy;
01254   return __pos;
01255 }
01256 
01257 template <class _Tp, class _Alloc>
01258 typename deque<_Tp,_Alloc>::iterator 
01259 deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
01260 {
01261   difference_type __index = __pos - _M_start;
01262   if (__index < size() / 2) {
01263     push_front(front());
01264     iterator __front1 = _M_start;
01265     ++__front1;
01266     iterator __front2 = __front1;
01267     ++__front2;
01268     __pos = _M_start + __index;
01269     iterator __pos1 = __pos;
01270     ++__pos1;
01271     copy(__front2, __pos1, __front1);
01272   }
01273   else {
01274     push_back(back());
01275     iterator __back1 = _M_finish;
01276     --__back1;
01277     iterator __back2 = __back1;
01278     --__back2;
01279     __pos = _M_start + __index;
01280     copy_backward(__pos, __back2, __back1);
01281   }
01282   *__pos = value_type();
01283   return __pos;
01284 }
01285 
01286 template <class _Tp, class _Alloc>
01287 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01288                                       size_type __n,
01289                                       const value_type& __x)
01290 {
01291   const difference_type __elems_before = __pos - _M_start;
01292   size_type __length = this->size();
01293   value_type __x_copy = __x;
01294   if (__elems_before < difference_type(__length / 2)) {
01295     iterator __new_start = _M_reserve_elements_at_front(__n);
01296     iterator __old_start = _M_start;
01297     __pos = _M_start + __elems_before;
01298     __STL_TRY {
01299       if (__elems_before >= difference_type(__n)) {
01300         iterator __start_n = _M_start + difference_type(__n);
01301         uninitialized_copy(_M_start, __start_n, __new_start);
01302         _M_start = __new_start;
01303         copy(__start_n, __pos, __old_start);
01304         fill(__pos - difference_type(__n), __pos, __x_copy);
01305       }
01306       else {
01307         __uninitialized_copy_fill(_M_start, __pos, __new_start, 
01308                                   _M_start, __x_copy);
01309         _M_start = __new_start;
01310         fill(__old_start, __pos, __x_copy);
01311       }
01312     }
01313     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01314   }
01315   else {
01316     iterator __new_finish = _M_reserve_elements_at_back(__n);
01317     iterator __old_finish = _M_finish;
01318     const difference_type __elems_after = 
01319       difference_type(__length) - __elems_before;
01320     __pos = _M_finish - __elems_after;
01321     __STL_TRY {
01322       if (__elems_after > difference_type(__n)) {
01323         iterator __finish_n = _M_finish - difference_type(__n);
01324         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01325         _M_finish = __new_finish;
01326         copy_backward(__pos, __finish_n, __old_finish);
01327         fill(__pos, __pos + difference_type(__n), __x_copy);
01328       }
01329       else {
01330         __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
01331                                   __x_copy, __pos, _M_finish);
01332         _M_finish = __new_finish;
01333         fill(__pos, __old_finish, __x_copy);
01334       }
01335     }
01336     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01337                                   __new_finish._M_node + 1));
01338   }
01339 }
01340 
01341 #ifdef __STL_MEMBER_TEMPLATES  
01342 
01343 template <class _Tp, class _Alloc> template <class _ForwardIterator>
01344 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01345                                       _ForwardIterator __first,
01346                                       _ForwardIterator __last,
01347                                       size_type __n)
01348 {
01349   const difference_type __elemsbefore = __pos - _M_start;
01350   size_type __length = size();
01351   if (__elemsbefore < __length / 2) {
01352     iterator __new_start = _M_reserve_elements_at_front(__n);
01353     iterator __old_start = _M_start;
01354     __pos = _M_start + __elemsbefore;
01355     __STL_TRY {
01356       if (__elemsbefore >= difference_type(__n)) {
01357         iterator __start_n = _M_start + difference_type(__n); 
01358         uninitialized_copy(_M_start, __start_n, __new_start);
01359         _M_start = __new_start;
01360         copy(__start_n, __pos, __old_start);
01361         copy(__first, __last, __pos - difference_type(__n));
01362       }
01363       else {
01364         _ForwardIterator __mid = __first;
01365         advance(__mid, difference_type(__n) - __elemsbefore);
01366         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
01367                                   __new_start);
01368         _M_start = __new_start;
01369         copy(__mid, __last, __old_start);
01370       }
01371     }
01372     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01373   }
01374   else {
01375     iterator __new_finish = _M_reserve_elements_at_back(__n);
01376     iterator __old_finish = _M_finish;
01377     const difference_type __elemsafter = 
01378       difference_type(__length) - __elemsbefore;
01379     __pos = _M_finish - __elemsafter;
01380     __STL_TRY {
01381       if (__elemsafter > difference_type(__n)) {
01382         iterator __finish_n = _M_finish - difference_type(__n);
01383         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01384         _M_finish = __new_finish;
01385         copy_backward(__pos, __finish_n, __old_finish);
01386         copy(__first, __last, __pos);
01387       }
01388       else {
01389         _ForwardIterator __mid = __first;
01390         advance(__mid, __elemsafter);
01391         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
01392         _M_finish = __new_finish;
01393         copy(__first, __mid, __pos);
01394       }
01395     }
01396     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01397                                   __new_finish._M_node + 1));
01398   }
01399 }
01400 
01401 #else /* __STL_MEMBER_TEMPLATES */
01402 
01403 template <class _Tp, class _Alloc>
01404 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01405                                       const value_type* __first,
01406                                       const value_type* __last,
01407                                       size_type __n)
01408 {
01409   const difference_type __elemsbefore = __pos - _M_start;
01410   size_type __length = size();
01411   if (__elemsbefore < __length / 2) {
01412     iterator __new_start = _M_reserve_elements_at_front(__n);
01413     iterator __old_start = _M_start;
01414     __pos = _M_start + __elemsbefore;
01415     __STL_TRY {
01416       if (__elemsbefore >= difference_type(__n)) {
01417         iterator __start_n = _M_start + difference_type(__n);
01418         uninitialized_copy(_M_start, __start_n, __new_start);
01419         _M_start = __new_start;
01420         copy(__start_n, __pos, __old_start);
01421         copy(__first, __last, __pos - difference_type(__n));
01422       }
01423       else {
01424         const value_type* __mid = 
01425           __first + (difference_type(__n) - __elemsbefore);
01426         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
01427                                   __new_start);
01428         _M_start = __new_start;
01429         copy(__mid, __last, __old_start);
01430       }
01431     }
01432     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01433   }
01434   else {
01435     iterator __new_finish = _M_reserve_elements_at_back(__n);
01436     iterator __old_finish = _M_finish;
01437     const difference_type __elemsafter = 
01438       difference_type(__length) - __elemsbefore;
01439     __pos = _M_finish - __elemsafter;
01440     __STL_TRY {
01441       if (__elemsafter > difference_type(__n)) {
01442         iterator __finish_n = _M_finish - difference_type(__n);
01443         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01444         _M_finish = __new_finish;
01445         copy_backward(__pos, __finish_n, __old_finish);
01446         copy(__first, __last, __pos);
01447       }
01448       else {
01449         const value_type* __mid = __first + __elemsafter;
01450         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
01451         _M_finish = __new_finish;
01452         copy(__first, __mid, __pos);
01453       }
01454     }
01455     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01456                                   __new_finish._M_node + 1));
01457   }
01458 }
01459 
01460 template <class _Tp, class _Alloc>
01461 void deque<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
01462                                       const_iterator __first,
01463                                       const_iterator __last,
01464                                       size_type __n)
01465 {
01466   const difference_type __elemsbefore = __pos - _M_start;
01467   size_type __length = size();
01468   if (__elemsbefore < __length / 2) {
01469     iterator __new_start = _M_reserve_elements_at_front(__n);
01470     iterator __old_start = _M_start;
01471     __pos = _M_start + __elemsbefore;
01472     __STL_TRY {
01473       if (__elemsbefore >= __n) {
01474         iterator __start_n = _M_start + __n;
01475         uninitialized_copy(_M_start, __start_n, __new_start);
01476         _M_start = __new_start;
01477         copy(__start_n, __pos, __old_start);
01478         copy(__first, __last, __pos - difference_type(__n));
01479       }
01480       else {
01481         const_iterator __mid = __first + (__n - __elemsbefore);
01482         __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
01483                                   __new_start);
01484         _M_start = __new_start;
01485         copy(__mid, __last, __old_start);
01486       }
01487     }
01488     __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
01489   }
01490   else {
01491     iterator __new_finish = _M_reserve_elements_at_back(__n);
01492     iterator __old_finish = _M_finish;
01493     const difference_type __elemsafter = __length - __elemsbefore;
01494     __pos = _M_finish - __elemsafter;
01495     __STL_TRY {
01496       if (__elemsafter > __n) {
01497         iterator __finish_n = _M_finish - difference_type(__n);
01498         uninitialized_copy(__finish_n, _M_finish, _M_finish);
01499         _M_finish = __new_finish;
01500         copy_backward(__pos, __finish_n, __old_finish);
01501         copy(__first, __last, __pos);
01502       }
01503       else {
01504         const_iterator __mid = __first + __elemsafter;
01505         __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
01506         _M_finish = __new_finish;
01507         copy(__first, __mid, __pos);
01508       }
01509     }
01510     __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, 
01511                  __new_finish._M_node + 1));
01512   }
01513 }
01514 
01515 #endif /* __STL_MEMBER_TEMPLATES */
01516 
01517 template <class _Tp, class _Alloc>
01518 void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
01519 {
01520   size_type __new_nodes
01521       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
01522   _M_reserve_map_at_front(__new_nodes);
01523   size_type __i;
01524   __STL_TRY {
01525     for (__i = 1; __i <= __new_nodes; ++__i)
01526       *(_M_start._M_node - __i) = _M_allocate_node();
01527   }
01528 #       ifdef __STL_USE_EXCEPTIONS
01529   catch(...) {
01530     for (size_type __j = 1; __j < __i; ++__j)
01531       _M_deallocate_node(*(_M_start._M_node - __j));      
01532     throw;
01533   }
01534 #       endif /* __STL_USE_EXCEPTIONS */
01535 }
01536 
01537 template <class _Tp, class _Alloc>
01538 void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
01539 {
01540   size_type __new_nodes
01541       = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
01542   _M_reserve_map_at_back(__new_nodes);
01543   size_type __i;
01544   __STL_TRY {
01545     for (__i = 1; __i <= __new_nodes; ++__i)
01546       *(_M_finish._M_node + __i) = _M_allocate_node();
01547   }
01548 #       ifdef __STL_USE_EXCEPTIONS
01549   catch(...) {
01550     for (size_type __j = 1; __j < __i; ++__j)
01551       _M_deallocate_node(*(_M_finish._M_node + __j));      
01552     throw;
01553   }
01554 #       endif /* __STL_USE_EXCEPTIONS */
01555 }
01556 
01557 template <class _Tp, class _Alloc>
01558 void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
01559                                           bool __add_at_front)
01560 {
01561   size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
01562   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
01563 
01564   _Map_pointer __new_nstart;
01565   if (_M_map_size > 2 * __new_num_nodes) {
01566     __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
01567                      + (__add_at_front ? __nodes_to_add : 0);
01568     if (__new_nstart < _M_start._M_node)
01569       copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
01570     else
01571       copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
01572                     __new_nstart + __old_num_nodes);
01573   }
01574   else {
01575     size_type __new_map_size = 
01576       _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
01577 
01578     _Map_pointer __new_map = _M_allocate_map(__new_map_size);
01579     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
01580                          + (__add_at_front ? __nodes_to_add : 0);
01581     copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
01582     _M_deallocate_map(_M_map, _M_map_size);
01583 
01584     _M_map = __new_map;
01585     _M_map_size = __new_map_size;
01586   }
01587 
01588   _M_start._M_set_node(__new_nstart);
01589   _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
01590 }
01591 
01592 
01593 // Nonmember functions.
01594 
01595 template <class _Tp, class _Alloc>
01596 inline bool operator==(const deque<_Tp, _Alloc>& __x,
01597                        const deque<_Tp, _Alloc>& __y) {
01598   return __x.size() == __y.size() &&
01599          equal(__x.begin(), __x.end(), __y.begin());
01600 }
01601 
01602 template <class _Tp, class _Alloc>
01603 inline bool operator<(const deque<_Tp, _Alloc>& __x,
01604                       const deque<_Tp, _Alloc>& __y) {
01605   return lexicographical_compare(__x.begin(), __x.end(), 
01606                                  __y.begin(), __y.end());
01607 }
01608 
01609 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
01610 
01611 template <class _Tp, class _Alloc>
01612 inline bool operator!=(const deque<_Tp, _Alloc>& __x,
01613                        const deque<_Tp, _Alloc>& __y) {
01614   return !(__x == __y);
01615 }
01616 
01617 template <class _Tp, class _Alloc>
01618 inline bool operator>(const deque<_Tp, _Alloc>& __x,
01619                       const deque<_Tp, _Alloc>& __y) {
01620   return __y < __x;
01621 }
01622 
01623 template <class _Tp, class _Alloc>
01624 inline bool operator<=(const deque<_Tp, _Alloc>& __x,
01625                        const deque<_Tp, _Alloc>& __y) {
01626   return !(__y < __x);
01627 }
01628 template <class _Tp, class _Alloc>
01629 inline bool operator>=(const deque<_Tp, _Alloc>& __x,
01630                        const deque<_Tp, _Alloc>& __y) {
01631   return !(__x < __y);
01632 }
01633 
01634 template <class _Tp, class _Alloc>
01635 inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) {
01636   __x.swap(__y);
01637 }
01638 
01639 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
01640 
01641 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
01642 #pragma reset woff 1174
01643 #pragma reset woff 1375
01644 #endif
01645           
01646 __STL_END_NAMESPACE 
01647   
01648 #endif /* __SGI_STL_INTERNAL_DEQUE_H */
01649 
01650 // Local Variables:
01651 // mode:C++
01652 // End:

Generated on Mon Jun 5 10:20:44 2006 for Intelligence.kdevelop by  doxygen 1.4.6