# stl_deque.h

Go to the documentation of this file.

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