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

Generated on Wed Mar 26 00:42:57 2008 for libstdc++ by  doxygen 1.5.1