_deque.h

00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Copyright (c) 1996,1997
00007  * Silicon Graphics Computer Systems, Inc.
00008  *
00009  * Copyright (c) 1997
00010  * Moscow Center for SPARC Technology
00011  *
00012  * Copyright (c) 1999 
00013  * Boris Fomitchev
00014  *
00015  * This material is provided "as is", with absolutely no warranty expressed
00016  * or implied. Any use is at your own risk.
00017  *
00018  * Permission to use or copy this software for any purpose is hereby granted 
00019  * without fee, provided the above notices are retained on all copies.
00020  * Permission to modify the code and to distribute modified code is granted,
00021  * provided the above notices are retained, and a notice that the code was
00022  * modified is included with the above copyright notice.
00023  *
00024  */
00025 
00026 /* NOTE: This is an internal header file, included by other STL headers.
00027  *   You should not attempt to use it directly.
00028  */
00029 
00030 #ifndef _STLP_INTERNAL_DEQUE_H
00031 #define _STLP_INTERNAL_DEQUE_H
00032 
00033 # ifndef _STLP_INTERNAL_ALGOBASE_H
00034 #  include <stl/_algobase.h>
00035 # endif
00036 
00037 # ifndef _STLP_INTERNAL_ALLOC_H
00038 #  include <stl/_alloc.h>
00039 # endif
00040 
00041 # ifndef _STLP_INTERNAL_ITERATOR_H
00042 #  include <stl/_iterator.h>
00043 # endif
00044 
00045 # ifndef _STLP_INTERNAL_UNINITIALIZED_H
00046 #  include <stl/_uninitialized.h>
00047 # endif
00048 
00049 # ifndef _STLP_RANGE_ERRORS_H
00050 #  include <stl/_range_errors.h>
00051 # endif
00052 
00053 /* Class invariants:
00054  *  For any nonsingular iterator i:
00055  *    i.node is the address of an element in the map array.  The
00056  *      contents of i.node is a pointer to the beginning of a node.
00057  *    i.first == *(i.node) 
00058  *    i.last  == i.first + node_size
00059  *    i.cur is a pointer in the range [i.first, i.last).  NOTE:
00060  *      the implication of this is that i.cur is always a dereferenceable
00061  *      pointer, even if i is a past-the-end iterator.
00062  *  Start and Finish are always nonsingular iterators.  NOTE: this means
00063  *    that an empty deque must have one node, and that a deque
00064  *    with N elements, where N is the buffer size, must have two nodes.
00065  *  For every node other than start.node and finish.node, every element
00066  *    in the node is an initialized object.  If start.node == finish.node,
00067  *    then [start.cur, finish.cur) are initialized objects, and
00068  *    the elements outside that range are uninitialized storage.  Otherwise,
00069  *    [start.cur, start.last) and [finish.first, finish.cur) are initialized
00070  *    objects, and [start.first, start.cur) and [finish.cur, finish.last)
00071  *    are uninitialized storage.
00072  *  [map, map + map_size) is a valid, non-empty range.  
00073  *  [start.node, finish.node] is a valid range contained within 
00074  *    [map, map + map_size).  
00075  *  A pointer in the range [map, map + map_size) points to an allocated node
00076  *    if and only if the pointer is in the range [start.node, finish.node].
00077  */
00078 
00079 # undef deque
00080 # define deque __WORKAROUND_DBG_RENAME(deque)
00081 
00082 _STLP_BEGIN_NAMESPACE
00083 
00084 template <class _Tp>
00085 struct _Deque_iterator_base {
00086 
00087   enum _Constants { 
00088     _blocksize = _MAX_BYTES, 
00089     __buffer_size = (sizeof(_Tp) < (size_t)_blocksize ?
00090                     ( (size_t)_blocksize / sizeof(_Tp)) : size_t(1))
00091   };
00092 
00093   typedef random_access_iterator_tag iterator_category;
00094 
00095   typedef _Tp value_type;
00096   typedef size_t size_type;
00097   typedef ptrdiff_t difference_type;
00098 
00099   typedef value_type** _Map_pointer;
00100 
00101   typedef _Deque_iterator_base< _Tp > _Self;
00102 
00103   value_type* _M_cur;
00104   value_type* _M_first;
00105   value_type* _M_last;
00106   _Map_pointer _M_node;
00107 
00108   _Deque_iterator_base(value_type* __x, _Map_pointer __y) 
00109     : _M_cur(__x), _M_first(*__y),
00110       _M_last(*__y + __buffer_size), _M_node(__y) {}
00111   _Deque_iterator_base() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
00112 
00113   difference_type _M_subtract(const _Self& __x) const {
00114     return difference_type(__buffer_size) * (_M_node - __x._M_node - 1) +
00115       (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
00116   }
00117 
00118   void _M_increment() {
00119     if (++_M_cur == _M_last) {
00120       _M_set_node(_M_node + 1);
00121       _M_cur = _M_first;
00122     }
00123   }
00124 
00125   void _M_decrement() {
00126     if (_M_cur == _M_first) {
00127       _M_set_node(_M_node - 1);
00128       _M_cur = _M_last;
00129     }
00130     --_M_cur;
00131   }
00132 
00133   void _M_advance(difference_type __n)
00134   {
00135     difference_type __offset = __n + (_M_cur - _M_first);
00136     if (__offset >= 0 && __offset < difference_type(__buffer_size))
00137       _M_cur += __n;
00138     else {
00139       difference_type __node_offset =
00140         __offset > 0 ? __offset / __buffer_size
00141                    : -difference_type((-__offset - 1) / __buffer_size) - 1;
00142       _M_set_node(_M_node + __node_offset);
00143       _M_cur = _M_first + 
00144         (__offset - __node_offset * difference_type(__buffer_size));
00145     }
00146   }
00147 
00148   void _M_set_node(_Map_pointer __new_node) {
00149     _M_last = (_M_first = *(_M_node = __new_node)) + difference_type(__buffer_size);
00150   }
00151 };
00152 
00153 
00154 
00155 template <class _Tp, class _Traits>
00156 struct _Deque_iterator : public _Deque_iterator_base< _Tp> {
00157 
00158   typedef random_access_iterator_tag iterator_category;
00159   typedef _Tp value_type;
00160   typedef typename _Traits::reference  reference;
00161   typedef typename _Traits::pointer    pointer;
00162   typedef size_t size_type;
00163   typedef ptrdiff_t difference_type;
00164   typedef value_type** _Map_pointer;
00165 
00166   typedef _Deque_iterator_base< _Tp > _Base;
00167   typedef _Deque_iterator<_Tp, _Traits> _Self;
00168   typedef _Deque_iterator<_Tp, _Nonconst_traits<_Tp> > _Nonconst_self;
00169   typedef _Deque_iterator<_Tp, _Const_traits<_Tp> > _Const_self;
00170 
00171   _Deque_iterator(value_type* __x, _Map_pointer __y) :
00172     _Deque_iterator_base<value_type>(__x,__y) {}
00173 
00174   _Deque_iterator() {}
00175   _Deque_iterator(const _Nonconst_self& __x) : 
00176     _Deque_iterator_base<value_type>(__x) {}
00177 
00178   reference operator*() const { 
00179       return *this->_M_cur; 
00180   }
00181 
00182   _STLP_DEFINE_ARROW_OPERATOR
00183 
00184   difference_type operator-(const _Self& __x) const { return this->_M_subtract(__x); }
00185 
00186   _Self& operator++() { this->_M_increment(); return *this; }
00187   _Self operator++(int)  {
00188     _Self __tmp = *this;
00189     ++*this;
00190     return __tmp;
00191   }
00192 
00193   _Self& operator--() { this->_M_decrement(); return *this; }
00194   _Self operator--(int) {
00195     _Self __tmp = *this;
00196     --*this;
00197     return __tmp;
00198   }
00199 
00200   _Self& operator+=(difference_type __n) { this->_M_advance(__n); return *this; }
00201   _Self operator+(difference_type __n) const
00202   {
00203     _Self __tmp = *this;
00204     return __tmp += __n;
00205   }
00206 
00207   _Self& operator-=(difference_type __n) { return *this += -__n; }
00208   _Self operator-(difference_type __n) const {
00209     _Self __tmp = *this;
00210     return __tmp -= __n;
00211   }
00212 
00213   reference operator[](difference_type __n) const { return *(*this + __n); }
00214 };
00215 
00216 template <class _Tp, class _Traits>
00217 inline _Deque_iterator<_Tp, _Traits> _STLP_CALL
00218 operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Traits>& __x)
00219 {
00220    return __x + __n;
00221 }
00222 
00223 
00224 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00225 
00226 template <class _Tp>
00227 inline bool _STLP_CALL 
00228 operator==(const _Deque_iterator_base<_Tp >& __x,
00229            const _Deque_iterator_base<_Tp >& __y) { 
00230     return __x._M_cur == __y._M_cur; 
00231 }
00232 
00233 template <class _Tp>
00234 inline bool _STLP_CALL 
00235 operator < (const _Deque_iterator_base<_Tp >& __x,
00236             const _Deque_iterator_base<_Tp >& __y) { 
00237   return (__x._M_node == __y._M_node) ? 
00238     (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
00239 }
00240 
00241 template <class _Tp>
00242 inline bool _STLP_CALL 
00243 operator!=(const _Deque_iterator_base<_Tp >& __x,
00244            const _Deque_iterator_base<_Tp >& __y) { 
00245     return __x._M_cur != __y._M_cur; 
00246 }
00247 template <class _Tp>
00248 inline bool _STLP_CALL 
00249 operator>(const _Deque_iterator_base<_Tp >& __x,
00250           const _Deque_iterator_base<_Tp >& __y) { 
00251     return __y < __x;
00252 }
00253 template <class _Tp>
00254 inline bool  _STLP_CALL operator>=(const _Deque_iterator_base<_Tp >& __x,
00255                                    const _Deque_iterator_base<_Tp >& __y) { 
00256     return !(__x < __y);
00257 }
00258 template <class _Tp>
00259 inline bool  _STLP_CALL operator<=(const _Deque_iterator_base<_Tp >& __x,
00260                                    const _Deque_iterator_base<_Tp >& __y) { 
00261     return !(__y < __x);
00262 }
00263 
00264 # else
00265 
00266 template <class _Tp, class _Traits1, class _Traits2>
00267 inline bool  _STLP_CALL
00268 operator==(const _Deque_iterator<_Tp, _Traits1 >& __x,
00269            const _Deque_iterator<_Tp, _Traits2 >& __y) { 
00270     return __x._M_cur == __y._M_cur; 
00271 }
00272 
00273 template <class _Tp, class _Traits1, class _Traits2>
00274 inline bool _STLP_CALL 
00275 operator < (const _Deque_iterator<_Tp, _Traits1 >& __x,
00276             const _Deque_iterator<_Tp, _Traits2 >& __y) { 
00277   return (__x._M_node == __y._M_node) ? 
00278     (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
00279 }
00280 
00281 template <class _Tp>
00282 inline bool _STLP_CALL 
00283 operator!=(const _Deque_iterator<_Tp, _Nonconst_traits<_Tp> >& __x,
00284            const _Deque_iterator<_Tp, _Const_traits<_Tp> >& __y) { 
00285     return __x._M_cur != __y._M_cur; 
00286 }
00287 template <class _Tp>
00288 inline bool _STLP_CALL 
00289 operator>(const _Deque_iterator<_Tp, _Nonconst_traits<_Tp> >& __x,
00290           const _Deque_iterator<_Tp, _Const_traits<_Tp> >& __y) { 
00291     return __y < __x;
00292 }
00293 template <class _Tp>
00294 inline bool  _STLP_CALL
00295 operator>=(const _Deque_iterator<_Tp, _Nonconst_traits<_Tp> >& __x,
00296            const _Deque_iterator<_Tp, _Const_traits<_Tp> >& __y) { 
00297     return !(__x < __y);
00298 }
00299 template <class _Tp>
00300 inline bool _STLP_CALL
00301 operator<=(const _Deque_iterator<_Tp, _Nonconst_traits<_Tp> >& __x,
00302            const _Deque_iterator<_Tp, _Const_traits<_Tp> >& __y) { 
00303     return !(__y < __x);
00304 }
00305 # endif
00306 
00307 # ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00308 template <class _Tp, class _Traits> inline _Tp*  _STLP_CALL value_type(const _Deque_iterator<_Tp, _Traits  >&) { return (_Tp*)0; }
00309 template <class _Tp, class _Traits> inline random_access_iterator_tag _STLP_CALL 
00310 iterator_category(const _Deque_iterator<_Tp, _Traits  >&) { return random_access_iterator_tag(); }
00311 template <class _Tp, class _Traits> inline ptrdiff_t* _STLP_CALL 
00312 distance_type(const _Deque_iterator<_Tp, _Traits  >&) { return 0; }
00313 #endif
00314 
00315 // Deque base class.  It has two purposes.  First, its constructor
00316 //  and destructor allocate (but don't initialize) storage.  This makes
00317 //  exception safety easier.  Second, the base class encapsulates all of
00318 //  the differences between SGI-style allocators and standard-conforming
00319 //  allocators.
00320 
00321 template <class _Tp, class _Alloc>
00322 class _Deque_base {
00323 public:
00324   typedef _Tp value_type;
00325   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00326   typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type  allocator_type;
00327   typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type _Map_alloc_type;
00328 
00329   typedef _Deque_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
00330   typedef _Deque_iterator<_Tp, _Const_traits<_Tp> >   const_iterator;
00331 
00332   static size_t  _STLP_CALL buffer_size() { return (size_t)_Deque_iterator_base<_Tp>::__buffer_size; } 
00333 
00334   _Deque_base(const allocator_type& __a, size_t __num_elements)
00335     : _M_start(), _M_finish(), _M_map(_STLP_CONVERT_ALLOCATOR(__a, _Tp*), 0),
00336       _M_map_size(__a, (size_t)0) {
00337         _M_initialize_map(__num_elements);
00338   }
00339   _Deque_base(const allocator_type& __a)
00340     : _M_start(), _M_finish(), _M_map(_STLP_CONVERT_ALLOCATOR(__a, _Tp*), 0), 
00341       _M_map_size(__a, (size_t)0) {
00342   }
00343   ~_Deque_base();    
00344   allocator_type get_allocator() const { return _M_map_size; }
00345 
00346 protected:
00347   void _M_initialize_map(size_t);
00348   void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
00349   void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
00350   enum { _S_initial_map_size = 8 };
00351 
00352 protected:
00353   iterator _M_start;
00354   iterator _M_finish;
00355   _STLP_alloc_proxy<value_type**, value_type*, _Map_alloc_type>  _M_map;
00356   _STLP_alloc_proxy<size_t, value_type,  allocator_type>   _M_map_size;  
00357 };
00358 
00359 
00360 template <class _Tp, _STLP_DEFAULT_ALLOCATOR_SELECT(_Tp) >
00361 class deque : protected _Deque_base<_Tp, _Alloc> {
00362   typedef _Deque_base<_Tp, _Alloc> _Base;
00363   typedef deque<_Tp, _Alloc> _Self;
00364 public:                         // Basic types
00365   typedef _Tp value_type;
00366   typedef value_type* pointer;
00367   typedef const value_type* const_pointer;
00368   typedef value_type& reference;
00369   typedef const value_type& const_reference;
00370   typedef size_t size_type;
00371   typedef ptrdiff_t difference_type;
00372   typedef random_access_iterator_tag _Iterator_category;
00373   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00374   typedef typename _Base::allocator_type allocator_type;
00375 
00376 public:                         // Iterators
00377   typedef typename _Base::iterator       iterator;
00378   typedef typename _Base::const_iterator const_iterator;
00379 
00380   _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
00381 
00382 protected:                      // Internal typedefs
00383   typedef pointer* _Map_pointer;
00384   typedef typename  __type_traits<_Tp>::has_trivial_assignment_operator _TrivialAss;
00385   typedef typename  __type_traits<_Tp>::has_trivial_assignment_operator _IsPODType;
00386 
00387 public:                         // Basic accessors
00388   iterator begin() { return this->_M_start; }
00389   iterator end() { return this->_M_finish; }
00390   const_iterator begin() const { return const_iterator(this->_M_start); }
00391   const_iterator end() const { return const_iterator(this->_M_finish); }
00392 
00393   reverse_iterator rbegin() { return reverse_iterator(this->_M_finish); }
00394   reverse_iterator rend() { return reverse_iterator(this->_M_start); }
00395   const_reverse_iterator rbegin() const 
00396     { return const_reverse_iterator(this->_M_finish); }
00397   const_reverse_iterator rend() const 
00398     { return const_reverse_iterator(this->_M_start); }
00399 
00400   reference operator[](size_type __n)
00401     { return this->_M_start[difference_type(__n)]; }
00402   const_reference operator[](size_type __n) const 
00403     { return this->_M_start[difference_type(__n)]; }
00404 
00405   void _M_range_check(size_type __n) const {
00406     if (__n >= this->size())
00407       __stl_throw_out_of_range("deque");
00408   }
00409   reference at(size_type __n)
00410     { _M_range_check(__n); return (*this)[__n]; }
00411   const_reference at(size_type __n) const
00412     { _M_range_check(__n); return (*this)[__n]; }
00413 
00414   reference front() { return *this->_M_start; }
00415   reference back() {
00416     iterator __tmp = this->_M_finish;
00417     --__tmp;
00418     return *__tmp;
00419   }
00420   const_reference front() const { return *this->_M_start; }
00421   const_reference back() const {
00422     const_iterator __tmp = this->_M_finish;
00423     --__tmp;
00424     return *__tmp;
00425   }
00426 
00427   size_type size() const { return this->_M_finish - this->_M_start; }
00428   size_type max_size() const { return size_type(-1); }
00429   bool empty() const { return this->_M_finish == this->_M_start; }
00430 
00431 public:                         // Constructor, destructor.
00432   explicit deque(const allocator_type& __a = allocator_type()) 
00433     : _Deque_base<_Tp, _Alloc>(__a, 0) {}
00434 
00435   deque(const _Self& __x) : 
00436     _Deque_base<_Tp, _Alloc>(__x.get_allocator(), __x.size()) { 
00437       __uninitialized_copy(__x.begin(), __x.end(), this->_M_start, _IsPODType()); 
00438   }
00439 
00440   deque(size_type __n, const value_type& __value,
00441         const allocator_type& __a = allocator_type()) : 
00442     _Deque_base<_Tp, _Alloc>(__a, __n)
00443     { _M_fill_initialize(__value); }
00444   // int,long variants may be needed 
00445   explicit deque(size_type __n) : _Deque_base<_Tp, _Alloc>(allocator_type(), __n)
00446     { _M_fill_initialize(value_type()); }
00447 
00448 #ifdef _STLP_MEMBER_TEMPLATES
00449 
00450   template <class _Integer>
00451   void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type&) {
00452     this->_M_initialize_map(__n);
00453     _M_fill_initialize(__x);
00454   }
00455 
00456   template <class _InputIter>
00457   void _M_initialize_dispatch(_InputIter __first, _InputIter __last,
00458                               const __false_type&) {
00459     _M_range_initialize(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
00460   }
00461 
00462 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
00463   // VC++ needs this
00464   template <class _InputIterator>
00465   deque(_InputIterator __first, _InputIterator __last) : 
00466     _Deque_base<_Tp, _Alloc>(allocator_type()) {
00467     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00468     _M_initialize_dispatch(__first, __last, _Integral());
00469   }
00470 # endif
00471 
00472   // Check whether it's an integral type.  If so, it's not an iterator.
00473   template <class _InputIterator>
00474   deque(_InputIterator __first, _InputIterator __last,
00475         const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) : 
00476     _Deque_base<_Tp, _Alloc>(__a) {
00477     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00478     _M_initialize_dispatch(__first, __last, _Integral());
00479   }
00480 
00481 # else
00482   deque(const value_type* __first, const value_type* __last,
00483         const allocator_type& __a = allocator_type() ) 
00484     : _Deque_base<_Tp, _Alloc>(__a, __last - __first) { 
00485     __uninitialized_copy(__first, __last, this->_M_start, _IsPODType()); 
00486   }
00487 
00488   deque(const_iterator __first, const_iterator __last,
00489         const allocator_type& __a = allocator_type() ) 
00490     : _Deque_base<_Tp, _Alloc>(__a, __last - __first) { 
00491     __uninitialized_copy(__first, __last, this->_M_start, _IsPODType()); 
00492   }
00493 #endif /* _STLP_MEMBER_TEMPLATES */
00494 
00495   ~deque() { 
00496     _Destroy(this->_M_start, this->_M_finish); 
00497   }
00498 
00499   _Self& operator= (const _Self& __x);
00500 
00501   void swap(_Self& __x) {
00502     _STLP_STD::swap(this->_M_start, __x._M_start);
00503     _STLP_STD::swap(this->_M_finish, __x._M_finish);
00504     _STLP_STD::swap(this->_M_map, __x._M_map);
00505     _STLP_STD::swap(this->_M_map_size, __x._M_map_size);
00506   }
00507 
00508 public: 
00509   // assign(), a generalized assignment member function.  Two
00510   // versions: one that takes a count, and one that takes a range.
00511   // The range version is a member template, so we dispatch on whether
00512   // or not the type is an integer.
00513 
00514   void _M_fill_assign(size_type __n, const _Tp& __val) {
00515     if (__n > size()) {
00516       _STLP_STD::fill(begin(), end(), __val);
00517       insert(end(), __n - size(), __val);
00518     }
00519     else {
00520       erase(begin() + __n, end());
00521       _STLP_STD::fill(begin(), end(), __val);
00522     }
00523   }
00524 
00525   void assign(size_type __n, const _Tp& __val) {
00526     _M_fill_assign(__n, __val);
00527   }
00528 
00529 #ifdef _STLP_MEMBER_TEMPLATES
00530 
00531   template <class _InputIterator>
00532   void assign(_InputIterator __first, _InputIterator __last) {
00533     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00534     _M_assign_dispatch(__first, __last, _Integral());
00535   }
00536 
00537 private:                        // helper functions for assign() 
00538 
00539   template <class _Integer>
00540   void _M_assign_dispatch(_Integer __n, _Integer __val, const __true_type&)
00541     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00542 
00543   template <class _InputIterator>
00544   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00545                           const __false_type&) {
00546     _M_assign_aux(__first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));
00547   }
00548 
00549   template <class _InputIter>
00550   void _M_assign_aux(_InputIter __first, _InputIter __last, const input_iterator_tag &) {
00551     iterator __cur = begin();
00552     for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
00553       *__cur = *__first;
00554     if (__first == __last)
00555       erase(__cur, end());
00556     else
00557       insert(end(), __first, __last);
00558   }
00559 
00560   template <class _ForwardIterator>
00561   void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00562                      const forward_iterator_tag &) {
00563     size_type __len = distance(__first, __last);
00564     if (__len > size()) {
00565       _ForwardIterator __mid = __first;
00566       advance(__mid, size());
00567       copy(__first, __mid, begin());
00568       insert(end(), __mid, __last);
00569     }
00570     else
00571       erase(copy(__first, __last, begin()), end());
00572   }
00573 
00574 #endif /* _STLP_MEMBER_TEMPLATES */
00575 
00576 public:                         // push_* and pop_*
00577   
00578   void push_back(const value_type& __t) {
00579     if (this->_M_finish._M_cur != this->_M_finish._M_last - 1) {
00580       _Construct(this->_M_finish._M_cur, __t);
00581       ++this->_M_finish._M_cur;
00582     }
00583     else
00584       _M_push_back_aux_v(__t);
00585   }
00586   void push_front(const value_type& __t) {
00587     if (this->_M_start._M_cur != this->_M_start._M_first) {
00588       _Construct(this->_M_start._M_cur - 1, __t);
00589       --this->_M_start._M_cur;
00590     }
00591     else
00592       _M_push_front_aux_v(__t);
00593   }
00594 
00595 # ifndef _STLP_NO_ANACHRONISMS
00596   void push_back() {
00597     if (this->_M_finish._M_cur != this->_M_finish._M_last - 1) {
00598       _Construct(this->_M_finish._M_cur);
00599       ++this->_M_finish._M_cur;
00600     }
00601     else
00602       _M_push_back_aux();
00603   }
00604   void push_front() {
00605     if (this->_M_start._M_cur != this->_M_start._M_first) {
00606       _Construct(this->_M_start._M_cur - 1);
00607       --this->_M_start._M_cur;
00608     }
00609     else
00610       _M_push_front_aux();
00611   }
00612 # endif
00613 
00614   void pop_back() {
00615     if (this->_M_finish._M_cur != this->_M_finish._M_first) {
00616       --this->_M_finish._M_cur;
00617       _Destroy(this->_M_finish._M_cur);
00618     }
00619     else
00620       _M_pop_back_aux();
00621   }
00622 
00623   void pop_front() {
00624     if (this->_M_start._M_cur != this->_M_start._M_last - 1) {
00625       _Destroy(this->_M_start._M_cur);
00626       ++this->_M_start._M_cur;
00627     }
00628     else 
00629       _M_pop_front_aux();
00630   }
00631 
00632 public:                         // Insert
00633 
00634   iterator insert(iterator __position, const value_type& __x) {
00635     if (__position._M_cur == this->_M_start._M_cur) {
00636       push_front(__x);
00637       return this->_M_start;
00638     }
00639     else if (__position._M_cur == this->_M_finish._M_cur) {
00640       push_back(__x);
00641       iterator __tmp = this->_M_finish;
00642       --__tmp;
00643       return __tmp;
00644     }
00645     else {
00646       return _M_insert_aux(__position, __x);
00647     }
00648   }
00649 
00650   iterator insert(iterator __position)
00651     { return insert(__position, value_type()); }
00652 
00653   void insert(iterator __pos, size_type __n, const value_type& __x) {
00654     _M_fill_insert(__pos, __n, __x);
00655   }
00656 
00657   void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
00658 
00659 #ifdef _STLP_MEMBER_TEMPLATES  
00660 
00661   // Check whether it's an integral type.  If so, it's not an iterator.
00662   template <class _InputIterator>
00663   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00664     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00665     _M_insert_dispatch(__pos, __first, __last, _Integral());
00666   }
00667 
00668   template <class _Integer>
00669   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
00670                           const __true_type&) {
00671     _M_fill_insert(__pos, (size_type) __n, (value_type) __x);
00672   }
00673 
00674   template <class _InputIterator>
00675   void _M_insert_dispatch(iterator __pos,
00676                           _InputIterator __first, _InputIterator __last,
00677                           const __false_type&) {
00678     insert(__pos, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIterator));
00679   }
00680 
00681 #else /* _STLP_MEMBER_TEMPLATES */
00682 
00683   void insert(iterator __pos,
00684               const value_type* __first, const value_type* __last);
00685   void insert(iterator __pos,
00686               const_iterator __first, const_iterator __last);
00687 
00688 #endif /* _STLP_MEMBER_TEMPLATES */
00689 
00690   void resize(size_type __new_size, const value_type& __x) {
00691     const size_type __len = size();
00692     if (__new_size < __len) 
00693       erase(this->_M_start + __new_size, this->_M_finish);
00694     else
00695       insert(this->_M_finish, __new_size - __len, __x);
00696   }
00697 
00698   void resize(size_type new_size) { resize(new_size, value_type()); }
00699 
00700 public:                         // Erase
00701   iterator erase(iterator __pos) {
00702     iterator __next = __pos;
00703     ++__next;
00704     difference_type __index = __pos - this->_M_start;
00705     if (size_type(__index) < this->size() >> 1) {
00706       copy_backward(this->_M_start, __pos, __next);
00707       pop_front();
00708     }
00709     else {
00710       copy(__next, this->_M_finish, __pos);
00711       pop_back();
00712     }
00713     return this->_M_start + __index;
00714   }
00715 
00716   iterator erase(iterator __first, iterator __last);
00717   void clear(); 
00718 
00719 protected:                        // Internal construction/destruction
00720 
00721   void _M_fill_initialize(const value_type& __value);
00722 
00723 #ifdef _STLP_MEMBER_TEMPLATES 
00724 
00725   template <class _InputIterator>
00726   void _M_range_initialize(_InputIterator __first,
00727                            _InputIterator __last,
00728                            const input_iterator_tag &) {
00729     this->_M_initialize_map(0);
00730     _STLP_TRY {
00731       for ( ; __first != __last; ++__first)
00732         push_back(*__first);
00733     }
00734     _STLP_UNWIND(clear());
00735   }
00736  template <class _ForwardIterator>
00737  void  _M_range_initialize(_ForwardIterator __first,
00738                            _ForwardIterator __last,
00739                            const forward_iterator_tag &)  {
00740    size_type __n = distance(__first, __last);
00741    this->_M_initialize_map(__n);
00742    _Map_pointer __cur_node;
00743    _STLP_TRY {
00744     for (__cur_node = this->_M_start._M_node; 
00745          __cur_node < this->_M_finish._M_node; 
00746          ++__cur_node) {
00747       _ForwardIterator __mid = __first;
00748       advance(__mid, this->buffer_size());
00749       uninitialized_copy(__first, __mid, *__cur_node);
00750       __first = __mid;
00751     }
00752     uninitialized_copy(__first, __last, this->_M_finish._M_first);
00753    }
00754   _STLP_UNWIND(_Destroy(this->_M_start, iterator(*__cur_node, __cur_node)));
00755  }
00756 #endif /* _STLP_MEMBER_TEMPLATES */
00757 
00758 protected:                        // Internal push_* and pop_*
00759 
00760   void _M_push_back_aux_v(const value_type&);
00761   void _M_push_front_aux_v(const value_type&);
00762 # ifndef _STLP_NO_ANACHRONISMS
00763   void _M_push_back_aux();
00764   void _M_push_front_aux();
00765 # endif
00766   void _M_pop_back_aux();
00767   void _M_pop_front_aux();
00768 
00769 protected:                        // Internal insert functions
00770 
00771 #ifdef _STLP_MEMBER_TEMPLATES
00772 
00773 template <class _InputIterator>
00774 void 
00775 insert(iterator __pos,
00776        _InputIterator __first,
00777        _InputIterator __last,
00778        const input_iterator_tag &)
00779 {
00780   copy(__first, __last, inserter(*this, __pos));
00781 }
00782 
00783 template <class _ForwardIterator>
00784 void  insert(iterator __pos,
00785              _ForwardIterator __first,
00786              _ForwardIterator __last,
00787              const forward_iterator_tag &)
00788  {
00789   size_type __n = distance(__first, __last);
00790   if (__pos._M_cur == this->_M_start._M_cur) {
00791     iterator __new_start = _M_reserve_elements_at_front(__n);
00792     _STLP_TRY {
00793       uninitialized_copy(__first, __last, __new_start);
00794       this->_M_start = __new_start;
00795     }
00796     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
00797   }
00798   else if (__pos._M_cur == this->_M_finish._M_cur) {
00799     iterator __new_finish = _M_reserve_elements_at_back(__n);
00800     _STLP_TRY {
00801       uninitialized_copy(__first, __last, this->_M_finish);
00802       this->_M_finish = __new_finish;
00803     }
00804     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1));
00805   }
00806   else
00807     _M_insert_aux(__pos, __first, __last, __n);
00808 }
00809 #endif /* _STLP_MEMBER_TEMPLATES */
00810 
00811   iterator _M_insert_aux(iterator __pos, const value_type& __x);
00812   iterator _M_insert_aux(iterator __pos);
00813   iterator _M_insert_aux_prepare(iterator __pos);
00814 
00815   void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
00816 
00817 #ifdef _STLP_MEMBER_TEMPLATES  
00818   template <class _ForwardIterator>
00819   void _M_insert_aux(iterator __pos,
00820                      _ForwardIterator __first,
00821                      _ForwardIterator __last,
00822                      size_type __n) {
00823     
00824     const difference_type __elemsbefore = __pos - this->_M_start;
00825     size_type __length = size();
00826     if (__elemsbefore < difference_type(__length / 2)) {
00827       iterator __new_start = _M_reserve_elements_at_front(__n);
00828       iterator __old_start = this->_M_start;
00829       __pos = this->_M_start + __elemsbefore;
00830       _STLP_TRY {
00831         if (__elemsbefore >= difference_type(__n)) {
00832           iterator __start_n = this->_M_start + difference_type(__n); 
00833           uninitialized_copy(this->_M_start, __start_n, __new_start);
00834           this->_M_start = __new_start;
00835           copy(__start_n, __pos, __old_start);
00836           copy(__first, __last, __pos - difference_type(__n));
00837         }
00838         else {
00839           _ForwardIterator __mid = __first;
00840           advance(__mid, difference_type(__n) - __elemsbefore);
00841           __uninitialized_copy_copy(this->_M_start, __pos, __first, __mid,
00842                                     __new_start, _IsPODType());
00843           this->_M_start = __new_start;
00844           copy(__mid, __last, __old_start);
00845         }
00846       }
00847       _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
00848     }
00849     else {
00850       iterator __new_finish = _M_reserve_elements_at_back(__n);
00851       iterator __old_finish = this->_M_finish;
00852       const difference_type __elemsafter = 
00853         difference_type(__length) - __elemsbefore;
00854       __pos = this->_M_finish - __elemsafter;
00855       _STLP_TRY {
00856       if (__elemsafter > difference_type(__n)) {
00857         iterator __finish_n = this->_M_finish - difference_type(__n);
00858         uninitialized_copy(__finish_n, this->_M_finish, this->_M_finish);
00859         this->_M_finish = __new_finish;
00860         copy_backward(__pos, __finish_n, __old_finish);
00861         copy(__first, __last, __pos);
00862       }
00863       else {
00864         _ForwardIterator __mid = __first;
00865         advance(__mid, __elemsafter);
00866         __uninitialized_copy_copy(__mid, __last, __pos, this->_M_finish, this->_M_finish, _IsPODType());
00867         this->_M_finish = __new_finish;
00868         copy(__first, __mid, __pos);
00869       }
00870       }
00871       _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1));
00872     }
00873   }
00874 #else /* _STLP_MEMBER_TEMPLATES */
00875   
00876   void _M_insert_aux(iterator __pos,
00877                      const value_type* __first, const value_type* __last,
00878                      size_type __n);
00879 
00880   void _M_insert_aux(iterator __pos, 
00881                      const_iterator __first, const_iterator __last,
00882                      size_type __n);
00883  
00884 #endif /* _STLP_MEMBER_TEMPLATES */
00885 
00886   iterator _M_reserve_elements_at_front(size_type __n) {
00887     size_type __vacancies = this->_M_start._M_cur - this->_M_start._M_first;
00888     if (__n > __vacancies) 
00889       _M_new_elements_at_front(__n - __vacancies);
00890     return this->_M_start - difference_type(__n);
00891   }
00892 
00893   iterator _M_reserve_elements_at_back(size_type __n) {
00894     size_type __vacancies = (this->_M_finish._M_last - this->_M_finish._M_cur) - 1;
00895     if (__n > __vacancies)
00896       _M_new_elements_at_back(__n - __vacancies);
00897     return this->_M_finish + difference_type(__n);
00898   }
00899 
00900   void _M_new_elements_at_front(size_type __new_elements);
00901   void _M_new_elements_at_back(size_type __new_elements);
00902 
00903 protected:                      // Allocation of _M_map and nodes
00904 
00905   // Makes sure the _M_map has space for new nodes.  Does not actually
00906   //  add the nodes.  Can invalidate _M_map pointers.  (And consequently, 
00907   //  deque iterators.)
00908 
00909   void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
00910     if (__nodes_to_add + 1 > this->_M_map_size._M_data - (this->_M_finish._M_node - this->_M_map._M_data))
00911       _M_reallocate_map(__nodes_to_add, false);
00912   }
00913 
00914   void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
00915     if (__nodes_to_add > size_type(this->_M_start._M_node - this->_M_map._M_data))
00916       _M_reallocate_map(__nodes_to_add, true);
00917   }
00918 
00919   void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
00920  
00921 };
00922 
00923 // Nonmember functions.
00924 
00925 template <class _Tp, class _Alloc >
00926 inline bool  _STLP_CALL operator==(const deque<_Tp, _Alloc>& __x,
00927                                    const deque<_Tp, _Alloc>& __y)
00928 {
00929   return __x.size() == __y.size() &&
00930   equal(__x.begin(), __x.end(), __y.begin());
00931 }
00932 
00933 template <class _Tp, class _Alloc >
00934 inline bool  _STLP_CALL operator<(const deque<_Tp, _Alloc>& __x,
00935                                   const deque<_Tp, _Alloc>& __y)
00936 {
00937   return lexicographical_compare(__x.begin(), __x.end(), 
00938                                  __y.begin(), __y.end());
00939 }
00940 
00941 #if defined(_STLP_USE_SEPARATE_RELOPS_NAMESPACE)
00942 
00943 template <class _Tp, class _Alloc >
00944 inline bool  _STLP_CALL operator!=(const deque<_Tp, _Alloc>& __x,
00945                                   const deque<_Tp, _Alloc>& __y)
00946 {
00947   return  !(__x == __y); 
00948 }
00949 
00950 template <class _Tp, class _Alloc >
00951 inline bool  _STLP_CALL operator>(const deque<_Tp, _Alloc>& __x,
00952                                   const deque<_Tp, _Alloc>& __y)
00953 {
00954   return __y < __x; 
00955 }
00956 
00957 template <class _Tp, class _Alloc >
00958 inline bool _STLP_CALL operator>=(const deque<_Tp, _Alloc>& __x,
00959                                   const deque<_Tp, _Alloc>& __y)
00960 {
00961   return !(__x < __y); 
00962 }
00963 
00964 template <class _Tp, class _Alloc >
00965 inline bool _STLP_CALL operator<=(const deque<_Tp, _Alloc>& __x,
00966                                   const deque<_Tp, _Alloc>& __y)
00967 {
00968  return !(__y < __x); 
00969 }
00970 
00971 
00972 # endif /* _STLP_SEPARATE_RELOPS_NAMESPACE */
00973 
00974 # if defined(_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
00975 
00976 template <class _Tp, class _Alloc>
00977 inline void _STLP_CALL 
00978 swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
00979 {
00980   __x.swap(__y);
00981 }
00982 
00983 # endif
00984 
00985 _STLP_END_NAMESPACE 
00986 
00987 // do a cleanup
00988 # undef deque
00989 # undef __deque__
00990 # define __deque__ __WORKAROUND_DBG_RENAME(deque)
00991 
00992 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00993 #  include <stl/_deque.c>
00994 # endif
00995 
00996 #if defined (_STLP_DEBUG)
00997 # include <stl/debug/_deque.h>
00998 #endif
00999 
01000 # if defined (_STLP_USE_WRAPPER_FOR_ALLOC_PARAM)
01001 #  include <stl/wrappers/_deque.h>
01002 # endif
01003   
01004 #endif /* _STLP_INTERNAL_DEQUE_H */
01005 
01006 // Local Variables:
01007 // mode:C++
01008 // End:
01009 

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