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

Generated on Tue Apr 21 13:13:26 2009 for libstdc++ by  doxygen 1.5.8