# deque.tcc

Go to the documentation of this file.

    00001 // Deque implementation (out of line) -*- C++ -*-
    00002
    00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
    00004 // Free Software Foundation, Inc.
    00005 //
    00006 // This file is part of the GNU ISO C++ Library.  This library is free
    00007 // software; you can redistribute it and/or modify it under the
    00008 // terms of the GNU General Public License as published by the
    00009 // Free Software Foundation; either version 2, or (at your option)
    00010 // any later version.
    00011
    00012 // This library is distributed in the hope that it will be useful,
    00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00015 // GNU General Public License for more details.
    00016
    00017 // You should have received a copy of the GNU General Public License along
    00018 // with this library; see the file COPYING.  If not, write to the Free
    00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00020 // USA.
    00021
    00022 // As a special exception, you may use this file as part of a free software
    00023 // library without restriction.  Specifically, if other files instantiate
    00024 // templates or use macros or inline functions from this file, or you compile
    00025 // this file and link it with other files to produce an executable, this
    00026 // file does not by itself cause the resulting executable to be covered by
    00027 // the GNU General Public License.  This exception does not however
    00028 // invalidate any other reasons why the executable file might be covered by
    00029 // the GNU General Public License.
    00030
    00031 /*
    00032  *
    00033  * Copyright (c) 1994
    00034  * Hewlett-Packard Company
    00035  *
    00036  * Permission to use, copy, modify, distribute and sell this software
    00037  * and its documentation for any purpose is hereby granted without fee,
    00038  * provided that the above copyright notice appear in all copies and
    00039  * that both that copyright notice and this permission notice appear
    00040  * in supporting documentation.  Hewlett-Packard Company makes no
    00041  * representations about the suitability of this software for any
    00042  * purpose.  It is provided "as is" without express or implied warranty.
    00043  *
    00044  *
    00045  * Copyright (c) 1997
    00046  * Silicon Graphics Computer Systems, Inc.
    00047  *
    00048  * Permission to use, copy, modify, distribute and sell this software
    00049  * and its documentation for any purpose is hereby granted without fee,
    00050  * provided that the above copyright notice appear in all copies and
    00051  * that both that copyright notice and this permission notice appear
    00052  * in supporting documentation.  Silicon Graphics makes no
    00053  * representations about the suitability of this software for any
    00054  * purpose.  It is provided "as is" without express or implied warranty.
    00055  */
    00056
    00057 /** @file deque.tcc
    00058  *  This is an internal header file, included by other library headers.
    00059  *  You should not attempt to use it directly.
    00060  */
    00061
    00062 #ifndef _DEQUE_TCC
    00063 #define _DEQUE_TCC 1
    00064
    00065 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
    00066
    00067   template <typename _Tp, typename _Alloc>
    00068     deque<_Tp, _Alloc>&
    00069     deque<_Tp, _Alloc>::
    00070     operator=(const deque& __x)
    00071     {
    00072       const size_type __len = size();
    00073       if (&__x != this)
    00074     {
    00075       if (__len >= __x.size())
    00076         _M_erase_at_end(std::copy(__x.begin(), __x.end(),
    00077                       this->_M_impl._M_start));
    00078       else
    00079         {
    00080           const_iterator __mid = __x.begin() + difference_type(__len);
    00081           std::copy(__x.begin(), __mid, this->_M_impl._M_start);
    00082           insert(this->_M_impl._M_finish, __mid, __x.end());
    00083         }
    00084     }
    00085       return *this;
    00086     }
    00087
    00088   template <typename _Tp, typename _Alloc>
    00089     typename deque<_Tp, _Alloc>::iterator
    00090     deque<_Tp, _Alloc>::
    00091     insert(iterator __position, const value_type& __x)
    00092     {
    00093       if (__position._M_cur == this->_M_impl._M_start._M_cur)
    00094     {
    00095       push_front(__x);
    00096       return this->_M_impl._M_start;
    00097     }
    00098       else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
    00099     {
    00100       push_back(__x);
    00101       iterator __tmp = this->_M_impl._M_finish;
    00102       --__tmp;
    00103       return __tmp;
    00104     }
    00105       else
    00106         return _M_insert_aux(__position, __x);
    00107     }
    00108
    00109 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00110   template<typename _Tp, typename _Alloc>
    00111     template<typename... _Args>
    00112       typename deque<_Tp, _Alloc>::iterator
    00113       deque<_Tp, _Alloc>::
    00114       emplace(iterator __position, _Args&&... __args)
    00115       {
    00116     if (__position._M_cur == this->_M_impl._M_start._M_cur)
    00117       {
    00118         push_front(std::forward<_Args>(__args)...);
    00119         return this->_M_impl._M_start;
    00120       }
    00121     else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
    00122       {
    00123         push_back(std::forward<_Args>(__args)...);
    00124         iterator __tmp = this->_M_impl._M_finish;
    00125         --__tmp;
    00126         return __tmp;
    00127       }
    00128     else
    00129       return _M_insert_aux(__position, std::forward<_Args>(__args)...);
    00130       }
    00131 #endif
    00132
    00133   template <typename _Tp, typename _Alloc>
    00134     typename deque<_Tp, _Alloc>::iterator
    00135     deque<_Tp, _Alloc>::
    00136     erase(iterator __position)
    00137     {
    00138       iterator __next = __position;
    00139       ++__next;
    00140       const difference_type __index = __position - begin();
    00141       if (static_cast<size_type>(__index) < (size() >> 1))
    00142     {
    00143       if (__position != begin())
    00144         _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
    00145       pop_front();
    00146     }
    00147       else
    00148     {
    00149       if (__next != end())
    00150         _GLIBCXX_MOVE3(__next, end(), __position);
    00151       pop_back();
    00152     }
    00153       return begin() + __index;
    00154     }
    00155
    00156   template <typename _Tp, typename _Alloc>
    00157     typename deque<_Tp, _Alloc>::iterator
    00158     deque<_Tp, _Alloc>::
    00159     erase(iterator __first, iterator __last)
    00160     {
    00161       if (__first == begin() && __last == end())
    00162     {
    00163       clear();
    00164       return end();
    00165     }
    00166       else
    00167     {
    00168       const difference_type __n = __last - __first;
    00169       const difference_type __elems_before = __first - begin();
    00170       if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
    00171         {
    00172           if (__first != begin())
    00173         _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
    00174           _M_erase_at_begin(begin() + __n);
    00175         }
    00176       else
    00177         {
    00178           if (__last != end())
    00179         _GLIBCXX_MOVE3(__last, end(), __first);
    00180           _M_erase_at_end(end() - __n);
    00181         }
    00182       return begin() + __elems_before;
    00183     }
    00184     }
    00185
    00186   template <typename _Tp, class _Alloc>
    00187     template <typename _InputIterator>
    00188       void
    00189       deque<_Tp, _Alloc>::
    00190       _M_assign_aux(_InputIterator __first, _InputIterator __last,
    00191             std::input_iterator_tag)
    00192       {
    00193         iterator __cur = begin();
    00194         for (; __first != __last && __cur != end(); ++__cur, ++__first)
    00195           *__cur = *__first;
    00196         if (__first == __last)
    00197           _M_erase_at_end(__cur);
    00198         else
    00199           insert(end(), __first, __last);
    00200       }
    00201
    00202   template <typename _Tp, typename _Alloc>
    00203     void
    00204     deque<_Tp, _Alloc>::
    00205     _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
    00206     {
    00207       if (__pos._M_cur == this->_M_impl._M_start._M_cur)
    00208     {
    00209       iterator __new_start = _M_reserve_elements_at_front(__n);
    00210       try
    00211         {
    00212           std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
    00213                       __x, _M_get_Tp_allocator());
    00214           this->_M_impl._M_start = __new_start;
    00215         }
    00216       catch(...)
    00217         {
    00218           _M_destroy_nodes(__new_start._M_node,
    00219                    this->_M_impl._M_start._M_node);
    00220           __throw_exception_again;
    00221         }
    00222     }
    00223       else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
    00224     {
    00225       iterator __new_finish = _M_reserve_elements_at_back(__n);
    00226       try
    00227         {
    00228           std::__uninitialized_fill_a(this->_M_impl._M_finish,
    00229                       __new_finish, __x,
    00230                       _M_get_Tp_allocator());
    00231           this->_M_impl._M_finish = __new_finish;
    00232         }
    00233       catch(...)
    00234         {
    00235           _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
    00236                    __new_finish._M_node + 1);
    00237           __throw_exception_again;
    00238         }
    00239     }
    00240       else
    00241         _M_insert_aux(__pos, __n, __x);
    00242     }
    00243
    00244   template <typename _Tp, typename _Alloc>
    00245     void
    00246     deque<_Tp, _Alloc>::
    00247     _M_fill_initialize(const value_type& __value)
    00248     {
    00249       _Map_pointer __cur;
    00250       try
    00251         {
    00252           for (__cur = this->_M_impl._M_start._M_node;
    00253            __cur < this->_M_impl._M_finish._M_node;
    00254            ++__cur)
    00255             std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
    00256                     __value, _M_get_Tp_allocator());
    00257           std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
    00258                       this->_M_impl._M_finish._M_cur,
    00259                       __value, _M_get_Tp_allocator());
    00260         }
    00261       catch(...)
    00262         {
    00263           std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
    00264             _M_get_Tp_allocator());
    00265           __throw_exception_again;
    00266         }
    00267     }
    00268
    00269   template <typename _Tp, typename _Alloc>
    00270     template <typename _InputIterator>
    00271       void
    00272       deque<_Tp, _Alloc>::
    00273       _M_range_initialize(_InputIterator __first, _InputIterator __last,
    00274                           std::input_iterator_tag)
    00275       {
    00276         this->_M_initialize_map(0);
    00277         try
    00278           {
    00279             for (; __first != __last; ++__first)
    00280               push_back(*__first);
    00281           }
    00282         catch(...)
    00283           {
    00284             clear();
    00285             __throw_exception_again;
    00286           }
    00287       }
    00288
    00289   template <typename _Tp, typename _Alloc>
    00290     template <typename _ForwardIterator>
    00291       void
    00292       deque<_Tp, _Alloc>::
    00293       _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
    00294                           std::forward_iterator_tag)
    00295       {
    00296         const size_type __n = std::distance(__first, __last);
    00297         this->_M_initialize_map(__n);
    00298
    00299         _Map_pointer __cur_node;
    00300         try
    00301           {
    00302             for (__cur_node = this->_M_impl._M_start._M_node;
    00303                  __cur_node < this->_M_impl._M_finish._M_node;
    00304                  ++__cur_node)
    00305           {
    00306         _ForwardIterator __mid = __first;
    00307         std::advance(__mid, _S_buffer_size());
    00308         std::__uninitialized_copy_a(__first, __mid, *__cur_node,
    00309                         _M_get_Tp_allocator());
    00310         __first = __mid;
    00311           }
    00312             std::__uninitialized_copy_a(__first, __last,
    00313                     this->_M_impl._M_finish._M_first,
    00314                     _M_get_Tp_allocator());
    00315           }
    00316         catch(...)
    00317           {
    00318             std::_Destroy(this->_M_impl._M_start,
    00319               iterator(*__cur_node, __cur_node),
    00320               _M_get_Tp_allocator());
    00321             __throw_exception_again;
    00322           }
    00323       }
    00324
    00325   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
    00326   template<typename _Tp, typename _Alloc>
    00327 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00328     template<typename... _Args>
    00329       void
    00330       deque<_Tp, _Alloc>::
    00331       _M_push_back_aux(_Args&&... __args)
    00332 #else
    00333       void
    00334       deque<_Tp, _Alloc>::
    00335       _M_push_back_aux(const value_type& __t)
    00336 #endif
    00337       {
    00338     _M_reserve_map_at_back();
    00339     *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
    00340     try
    00341       {
    00342 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00343         this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
    00344                     std::forward<_Args>(__args)...);
    00345 #else
    00346         this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
    00347 #endif
    00348         this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
    00349                         + 1);
    00350         this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
    00351       }
    00352     catch(...)
    00353       {
    00354         _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
    00355         __throw_exception_again;
    00356       }
    00357       }
    00358
    00359   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
    00360   template<typename _Tp, typename _Alloc>
    00361 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00362     template<typename... _Args>
    00363       void
    00364       deque<_Tp, _Alloc>::
    00365       _M_push_front_aux(_Args&&... __args)
    00366 #else
    00367       void
    00368       deque<_Tp, _Alloc>::
    00369       _M_push_front_aux(const value_type& __t)
    00370 #endif
    00371       {
    00372     _M_reserve_map_at_front();
    00373     *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
    00374     try
    00375       {
    00376         this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
    00377                            - 1);
    00378         this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
    00379 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00380         this->_M_impl.construct(this->_M_impl._M_start._M_cur,
    00381                     std::forward<_Args>(__args)...);
    00382 #else
    00383         this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
    00384 #endif
    00385       }
    00386     catch(...)
    00387       {
    00388         ++this->_M_impl._M_start;
    00389         _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
    00390         __throw_exception_again;
    00391       }
    00392       }
    00393
    00394   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
    00395   template <typename _Tp, typename _Alloc>
    00396     void deque<_Tp, _Alloc>::
    00397     _M_pop_back_aux()
    00398     {
    00399       _M_deallocate_node(this->_M_impl._M_finish._M_first);
    00400       this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
    00401       this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
    00402       this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
    00403     }
    00404
    00405   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
    00406   // Note that if the deque has at least one element (a precondition for this
    00407   // member function), and if
    00408   //   _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
    00409   // then the deque must have at least two nodes.
    00410   template <typename _Tp, typename _Alloc>
    00411     void deque<_Tp, _Alloc>::
    00412     _M_pop_front_aux()
    00413     {
    00414       this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
    00415       _M_deallocate_node(this->_M_impl._M_start._M_first);
    00416       this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
    00417       this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
    00418     }
    00419
    00420   template <typename _Tp, typename _Alloc>
    00421     template <typename _InputIterator>
    00422       void
    00423       deque<_Tp, _Alloc>::
    00424       _M_range_insert_aux(iterator __pos,
    00425                           _InputIterator __first, _InputIterator __last,
    00426                           std::input_iterator_tag)
    00427       { std::copy(__first, __last, std::inserter(*this, __pos)); }
    00428
    00429   template <typename _Tp, typename _Alloc>
    00430     template <typename _ForwardIterator>
    00431       void
    00432       deque<_Tp, _Alloc>::
    00433       _M_range_insert_aux(iterator __pos,
    00434                           _ForwardIterator __first, _ForwardIterator __last,
    00435                           std::forward_iterator_tag)
    00436       {
    00437         const size_type __n = std::distance(__first, __last);
    00438         if (__pos._M_cur == this->_M_impl._M_start._M_cur)
    00439       {
    00440         iterator __new_start = _M_reserve_elements_at_front(__n);
    00441         try
    00442           {
    00443         std::__uninitialized_copy_a(__first, __last, __new_start,
    00444                         _M_get_Tp_allocator());
    00445         this->_M_impl._M_start = __new_start;
    00446           }
    00447         catch(...)
    00448           {
    00449         _M_destroy_nodes(__new_start._M_node,
    00450                  this->_M_impl._M_start._M_node);
    00451         __throw_exception_again;
    00452           }
    00453       }
    00454         else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
    00455       {
    00456         iterator __new_finish = _M_reserve_elements_at_back(__n);
    00457         try
    00458           {
    00459         std::__uninitialized_copy_a(__first, __last,
    00460                         this->_M_impl._M_finish,
    00461                         _M_get_Tp_allocator());
    00462         this->_M_impl._M_finish = __new_finish;
    00463           }
    00464         catch(...)
    00465           {
    00466         _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
    00467                  __new_finish._M_node + 1);
    00468         __throw_exception_again;
    00469           }
    00470       }
    00471         else
    00472           _M_insert_aux(__pos, __first, __last, __n);
    00473       }
    00474
    00475   template<typename _Tp, typename _Alloc>
    00476 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00477     template<typename... _Args>
    00478       typename deque<_Tp, _Alloc>::iterator
    00479       deque<_Tp, _Alloc>::
    00480       _M_insert_aux(iterator __pos, _Args&&... __args)
    00481       {
    00482     value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
    00483 #else
    00484     typename deque<_Tp, _Alloc>::iterator
    00485       deque<_Tp, _Alloc>::
    00486       _M_insert_aux(iterator __pos, const value_type& __x)
    00487       {
    00488     value_type __x_copy = __x; // XXX copy
    00489 #endif
    00490     difference_type __index = __pos - this->_M_impl._M_start;
    00491     if (static_cast<size_type>(__index) < size() / 2)
    00492       {
    00493         push_front(_GLIBCXX_MOVE(front()));
    00494         iterator __front1 = this->_M_impl._M_start;
    00495         ++__front1;
    00496         iterator __front2 = __front1;
    00497         ++__front2;
    00498         __pos = this->_M_impl._M_start + __index;
    00499         iterator __pos1 = __pos;
    00500         ++__pos1;
    00501         _GLIBCXX_MOVE3(__front2, __pos1, __front1);
    00502       }
    00503     else
    00504       {
    00505         push_back(_GLIBCXX_MOVE(back()));
    00506         iterator __back1 = this->_M_impl._M_finish;
    00507         --__back1;
    00508         iterator __back2 = __back1;
    00509         --__back2;
    00510         __pos = this->_M_impl._M_start + __index;
    00511         _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
    00512       }
    00513     *__pos = _GLIBCXX_MOVE(__x_copy);
    00514     return __pos;
    00515       }
    00516
    00517   template <typename _Tp, typename _Alloc>
    00518     void
    00519     deque<_Tp, _Alloc>::
    00520     _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
    00521     {
    00522       const difference_type __elems_before = __pos - this->_M_impl._M_start;
    00523       const size_type __length = this->size();
    00524       value_type __x_copy = __x;
    00525       if (__elems_before < difference_type(__length / 2))
    00526     {
    00527       iterator __new_start = _M_reserve_elements_at_front(__n);
    00528       iterator __old_start = this->_M_impl._M_start;
    00529       __pos = this->_M_impl._M_start + __elems_before;
    00530       try
    00531         {
    00532           if (__elems_before >= difference_type(__n))
    00533         {
    00534           iterator __start_n = (this->_M_impl._M_start
    00535                     + difference_type(__n));
    00536           std::__uninitialized_move_a(this->_M_impl._M_start,
    00537                           __start_n, __new_start,
    00538                           _M_get_Tp_allocator());
    00539           this->_M_impl._M_start = __new_start;
    00540           _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
    00541           std::fill(__pos - difference_type(__n), __pos, __x_copy);
    00542         }
    00543           else
    00544         {
    00545           std::__uninitialized_move_fill(this->_M_impl._M_start,
    00546                          __pos, __new_start,
    00547                          this->_M_impl._M_start,
    00548                          __x_copy,
    00549                          _M_get_Tp_allocator());
    00550           this->_M_impl._M_start = __new_start;
    00551           std::fill(__old_start, __pos, __x_copy);
    00552         }
    00553         }
    00554       catch(...)
    00555         {
    00556           _M_destroy_nodes(__new_start._M_node,
    00557                    this->_M_impl._M_start._M_node);
    00558           __throw_exception_again;
    00559         }
    00560     }
    00561       else
    00562     {
    00563       iterator __new_finish = _M_reserve_elements_at_back(__n);
    00564       iterator __old_finish = this->_M_impl._M_finish;
    00565       const difference_type __elems_after =
    00566         difference_type(__length) - __elems_before;
    00567       __pos = this->_M_impl._M_finish - __elems_after;
    00568       try
    00569         {
    00570           if (__elems_after > difference_type(__n))
    00571         {
    00572           iterator __finish_n = (this->_M_impl._M_finish
    00573                      - difference_type(__n));
    00574           std::__uninitialized_move_a(__finish_n,
    00575                           this->_M_impl._M_finish,
    00576                           this->_M_impl._M_finish,
    00577                           _M_get_Tp_allocator());
    00578           this->_M_impl._M_finish = __new_finish;
    00579           _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
    00580           std::fill(__pos, __pos + difference_type(__n), __x_copy);
    00581         }
    00582           else
    00583         {
    00584           std::__uninitialized_fill_move(this->_M_impl._M_finish,
    00585                          __pos + difference_type(__n),
    00586                          __x_copy, __pos,
    00587                          this->_M_impl._M_finish,
    00588                          _M_get_Tp_allocator());
    00589           this->_M_impl._M_finish = __new_finish;
    00590           std::fill(__pos, __old_finish, __x_copy);
    00591         }
    00592         }
    00593       catch(...)
    00594         {
    00595           _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
    00596                    __new_finish._M_node + 1);
    00597           __throw_exception_again;
    00598         }
    00599     }
    00600     }
    00601
    00602   template <typename _Tp, typename _Alloc>
    00603     template <typename _ForwardIterator>
    00604       void
    00605       deque<_Tp, _Alloc>::
    00606       _M_insert_aux(iterator __pos,
    00607                     _ForwardIterator __first, _ForwardIterator __last,
    00608                     size_type __n)
    00609       {
    00610         const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
    00611         const size_type __length = size();
    00612         if (static_cast<size_type>(__elemsbefore) < __length / 2)
    00613       {
    00614         iterator __new_start = _M_reserve_elements_at_front(__n);
    00615         iterator __old_start = this->_M_impl._M_start;
    00616         __pos = this->_M_impl._M_start + __elemsbefore;
    00617         try
    00618           {
    00619         if (__elemsbefore >= difference_type(__n))
    00620           {
    00621             iterator __start_n = (this->_M_impl._M_start
    00622                       + difference_type(__n));
    00623             std::__uninitialized_move_a(this->_M_impl._M_start,
    00624                         __start_n, __new_start,
    00625                         _M_get_Tp_allocator());
    00626             this->_M_impl._M_start = __new_start;
    00627             _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
    00628             std::copy(__first, __last, __pos - difference_type(__n));
    00629           }
    00630         else
    00631           {
    00632             _ForwardIterator __mid = __first;
    00633             std::advance(__mid, difference_type(__n) - __elemsbefore);
    00634             std::__uninitialized_move_copy(this->_M_impl._M_start,
    00635                            __pos, __first, __mid,
    00636                            __new_start,
    00637                            _M_get_Tp_allocator());
    00638             this->_M_impl._M_start = __new_start;
    00639             std::copy(__mid, __last, __old_start);
    00640           }
    00641           }
    00642         catch(...)
    00643           {
    00644         _M_destroy_nodes(__new_start._M_node,
    00645                  this->_M_impl._M_start._M_node);
    00646         __throw_exception_again;
    00647           }
    00648       }
    00649         else
    00650         {
    00651           iterator __new_finish = _M_reserve_elements_at_back(__n);
    00652           iterator __old_finish = this->_M_impl._M_finish;
    00653           const difference_type __elemsafter =
    00654             difference_type(__length) - __elemsbefore;
    00655           __pos = this->_M_impl._M_finish - __elemsafter;
    00656           try
    00657             {
    00658               if (__elemsafter > difference_type(__n))
    00659         {
    00660           iterator __finish_n = (this->_M_impl._M_finish
    00661                      - difference_type(__n));
    00662           std::__uninitialized_move_a(__finish_n,
    00663                           this->_M_impl._M_finish,
    00664                           this->_M_impl._M_finish,
    00665                           _M_get_Tp_allocator());
    00666           this->_M_impl._M_finish = __new_finish;
    00667           _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
    00668           std::copy(__first, __last, __pos);
    00669         }
    00670               else
    00671         {
    00672           _ForwardIterator __mid = __first;
    00673           std::advance(__mid, __elemsafter);
    00674           std::__uninitialized_copy_move(__mid, __last, __pos,
    00675                          this->_M_impl._M_finish,
    00676                          this->_M_impl._M_finish,
    00677                          _M_get_Tp_allocator());
    00678           this->_M_impl._M_finish = __new_finish;
    00679           std::copy(__first, __mid, __pos);
    00680         }
    00681             }
    00682           catch(...)
    00683             {
    00684               _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
    00685                    __new_finish._M_node + 1);
    00686               __throw_exception_again;
    00687             }
    00688         }
    00689       }
    00690
    00691    template<typename _Tp, typename _Alloc>
    00692      void
    00693      deque<_Tp, _Alloc>::
    00694      _M_destroy_data_aux(iterator __first, iterator __last)
    00695      {
    00696        for (_Map_pointer __node = __first._M_node + 1;
    00697         __node < __last._M_node; ++__node)
    00698      std::_Destroy(*__node, *__node + _S_buffer_size(),
    00699                _M_get_Tp_allocator());
    00700
    00701        if (__first._M_node != __last._M_node)
    00702      {
    00703        std::_Destroy(__first._M_cur, __first._M_last,
    00704              _M_get_Tp_allocator());
    00705        std::_Destroy(__last._M_first, __last._M_cur,
    00706              _M_get_Tp_allocator());
    00707      }
    00708        else
    00709      std::_Destroy(__first._M_cur, __last._M_cur,
    00710                _M_get_Tp_allocator());
    00711      }
    00712
    00713   template <typename _Tp, typename _Alloc>
    00714     void
    00715     deque<_Tp, _Alloc>::
    00716     _M_new_elements_at_front(size_type __new_elems)
    00717     {
    00718       if (this->max_size() - this->size() < __new_elems)
    00719     __throw_length_error(__N("deque::_M_new_elements_at_front"));
    00720
    00721       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
    00722                      / _S_buffer_size());
    00723       _M_reserve_map_at_front(__new_nodes);
    00724       size_type __i;
    00725       try
    00726         {
    00727           for (__i = 1; __i <= __new_nodes; ++__i)
    00728             *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
    00729         }
    00730       catch(...)
    00731         {
    00732           for (size_type __j = 1; __j < __i; ++__j)
    00733             _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
    00734           __throw_exception_again;
    00735         }
    00736     }
    00737
    00738   template <typename _Tp, typename _Alloc>
    00739     void
    00740     deque<_Tp, _Alloc>::
    00741     _M_new_elements_at_back(size_type __new_elems)
    00742     {
    00743       if (this->max_size() - this->size() < __new_elems)
    00744     __throw_length_error(__N("deque::_M_new_elements_at_back"));
    00745
    00746       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
    00747                      / _S_buffer_size());
    00748       _M_reserve_map_at_back(__new_nodes);
    00749       size_type __i;
    00750       try
    00751         {
    00752           for (__i = 1; __i <= __new_nodes; ++__i)
    00753             *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
    00754         }
    00755       catch(...)
    00756         {
    00757           for (size_type __j = 1; __j < __i; ++__j)
    00758             _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
    00759           __throw_exception_again;
    00760         }
    00761     }
    00762
    00763   template <typename _Tp, typename _Alloc>
    00764     void
    00765     deque<_Tp, _Alloc>::
    00766     _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
    00767     {
    00768       const size_type __old_num_nodes
    00769     = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
    00770       const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
    00771
    00772       _Map_pointer __new_nstart;
    00773       if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
    00774     {
    00775       __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
    00776                      - __new_num_nodes) / 2
    00777                      + (__add_at_front ? __nodes_to_add : 0);
    00778       if (__new_nstart < this->_M_impl._M_start._M_node)
    00779         std::copy(this->_M_impl._M_start._M_node,
    00780               this->_M_impl._M_finish._M_node + 1,
    00781               __new_nstart);
    00782       else
    00783         std::copy_backward(this->_M_impl._M_start._M_node,
    00784                    this->_M_impl._M_finish._M_node + 1,
    00785                    __new_nstart + __old_num_nodes);
    00786     }
    00787       else
    00788     {
    00789       size_type __new_map_size = this->_M_impl._M_map_size
    00790                                  + std::max(this->_M_impl._M_map_size,
    00791                         __nodes_to_add) + 2;
    00792
    00793       _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
    00794       __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
    00795                      + (__add_at_front ? __nodes_to_add : 0);
    00796       std::copy(this->_M_impl._M_start._M_node,
    00797             this->_M_impl._M_finish._M_node + 1,
    00798             __new_nstart);
    00799       _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
    00800
    00801       this->_M_impl._M_map = __new_map;
    00802       this->_M_impl._M_map_size = __new_map_size;
    00803     }
    00804
    00805       this->_M_impl._M_start._M_set_node(__new_nstart);
    00806       this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
    00807     }
    00808
    00809   // Overload for deque::iterators, exploiting the "segmented-iterator
    00810   // optimization".  NB: leave const_iterators alone!
    00811   template<typename _Tp>
    00812     void
    00813     fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
    00814      const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
    00815     {
    00816       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
    00817
    00818       for (typename _Self::_Map_pointer __node = __first._M_node + 1;
    00819            __node < __last._M_node; ++__node)
    00820     std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
    00821
    00822       if (__first._M_node != __last._M_node)
    00823     {
    00824       std::fill(__first._M_cur, __first._M_last, __value);
    00825       std::fill(__last._M_first, __last._M_cur, __value);
    00826     }
    00827       else
    00828     std::fill(__first._M_cur, __last._M_cur, __value);
    00829     }
    00830
    00831 _GLIBCXX_END_NESTED_NAMESPACE
    00832
    00833 #endif