LCOV - code coverage report
Current view: top level - usr/include/c++/4.8/bits - deque.tcc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 51 88 58.0 %
Date: 2015-10-10 Functions: 7 16 43.8 %

          Line data    Source code
       1             : // Deque implementation (out of line) -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2001-2013 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /*
      26             :  *
      27             :  * Copyright (c) 1994
      28             :  * Hewlett-Packard Company
      29             :  *
      30             :  * Permission to use, copy, modify, distribute and sell this software
      31             :  * and its documentation for any purpose is hereby granted without fee,
      32             :  * provided that the above copyright notice appear in all copies and
      33             :  * that both that copyright notice and this permission notice appear
      34             :  * in supporting documentation.  Hewlett-Packard Company makes no
      35             :  * representations about the suitability of this software for any
      36             :  * purpose.  It is provided "as is" without express or implied warranty.
      37             :  *
      38             :  *
      39             :  * Copyright (c) 1997
      40             :  * Silicon Graphics Computer Systems, Inc.
      41             :  *
      42             :  * Permission to use, copy, modify, distribute and sell this software
      43             :  * and its documentation for any purpose is hereby granted without fee,
      44             :  * provided that the above copyright notice appear in all copies and
      45             :  * that both that copyright notice and this permission notice appear
      46             :  * in supporting documentation.  Silicon Graphics makes no
      47             :  * representations about the suitability of this software for any
      48             :  * purpose.  It is provided "as is" without express or implied warranty.
      49             :  */
      50             : 
      51             : /** @file bits/deque.tcc
      52             :  *  This is an internal header file, included by other library headers.
      53             :  *  Do not attempt to use it directly. @headername{deque}
      54             :  */
      55             : 
      56             : #ifndef _DEQUE_TCC
      57             : #define _DEQUE_TCC 1
      58             : 
      59             : namespace std _GLIBCXX_VISIBILITY(default)
      60             : {
      61             : _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
      62             : 
      63             : #if __cplusplus >= 201103L
      64             :   template <typename _Tp, typename _Alloc>
      65             :     void
      66             :     deque<_Tp, _Alloc>::
      67             :     _M_default_initialize()
      68             :     {
      69             :       _Map_pointer __cur;
      70             :       __try
      71             :         {
      72             :           for (__cur = this->_M_impl._M_start._M_node;
      73             :                __cur < this->_M_impl._M_finish._M_node;
      74             :                ++__cur)
      75             :             std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
      76             :                                            _M_get_Tp_allocator());
      77             :           std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
      78             :                                          this->_M_impl._M_finish._M_cur,
      79             :                                          _M_get_Tp_allocator());
      80             :         }
      81             :       __catch(...)
      82             :         {
      83             :           std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
      84             :                         _M_get_Tp_allocator());
      85             :           __throw_exception_again;
      86             :         }
      87             :     }
      88             : #endif
      89             : 
      90             :   template <typename _Tp, typename _Alloc>
      91             :     deque<_Tp, _Alloc>&
      92             :     deque<_Tp, _Alloc>::
      93             :     operator=(const deque& __x)
      94             :     {
      95             :       const size_type __len = size();
      96             :       if (&__x != this)
      97             :         {
      98             :           if (__len >= __x.size())
      99             :             _M_erase_at_end(std::copy(__x.begin(), __x.end(),
     100             :                                       this->_M_impl._M_start));
     101             :           else
     102             :             {
     103             :               const_iterator __mid = __x.begin() + difference_type(__len);
     104             :               std::copy(__x.begin(), __mid, this->_M_impl._M_start);
     105             :               insert(this->_M_impl._M_finish, __mid, __x.end());
     106             :             }
     107             :         }
     108             :       return *this;
     109             :     }
     110             : 
     111             : #if __cplusplus >= 201103L
     112             :   template<typename _Tp, typename _Alloc>
     113             :     template<typename... _Args>
     114             :       void
     115          12 :       deque<_Tp, _Alloc>::
     116             :       emplace_front(_Args&&... __args)
     117             :       {
     118          12 :         if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
     119             :           {
     120           6 :             this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1,
     121           6 :                                     std::forward<_Args>(__args)...);
     122           6 :             --this->_M_impl._M_start._M_cur;
     123             :           }
     124             :         else
     125           6 :           _M_push_front_aux(std::forward<_Args>(__args)...);
     126          12 :       }
     127             : 
     128             :   template<typename _Tp, typename _Alloc>
     129             :     template<typename... _Args>
     130             :       void
     131           0 :       deque<_Tp, _Alloc>::
     132             :       emplace_back(_Args&&... __args)
     133             :       {
     134           0 :         if (this->_M_impl._M_finish._M_cur
     135           0 :             != this->_M_impl._M_finish._M_last - 1)
     136             :           {
     137           0 :             this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
     138           0 :                                     std::forward<_Args>(__args)...);
     139           0 :             ++this->_M_impl._M_finish._M_cur;
     140             :           }
     141             :         else
     142           0 :           _M_push_back_aux(std::forward<_Args>(__args)...);
     143           0 :       }
     144             : #endif
     145             : 
     146             :   template <typename _Tp, typename _Alloc>
     147             :     typename deque<_Tp, _Alloc>::iterator
     148             :     deque<_Tp, _Alloc>::
     149             :     insert(iterator __position, const value_type& __x)
     150             :     {
     151             :       if (__position._M_cur == this->_M_impl._M_start._M_cur)
     152             :         {
     153             :           push_front(__x);
     154             :           return this->_M_impl._M_start;
     155             :         }
     156             :       else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
     157             :         {
     158             :           push_back(__x);
     159             :           iterator __tmp = this->_M_impl._M_finish;
     160             :           --__tmp;
     161             :           return __tmp;
     162             :         }
     163             :       else
     164             :         return _M_insert_aux(__position, __x);
     165             :     }
     166             : 
     167             : #if __cplusplus >= 201103L
     168             :   template<typename _Tp, typename _Alloc>
     169             :     template<typename... _Args>
     170             :       typename deque<_Tp, _Alloc>::iterator
     171             :       deque<_Tp, _Alloc>::
     172             :       emplace(iterator __position, _Args&&... __args)
     173             :       {
     174             :         if (__position._M_cur == this->_M_impl._M_start._M_cur)
     175             :           {
     176             :             emplace_front(std::forward<_Args>(__args)...);
     177             :             return this->_M_impl._M_start;
     178             :           }
     179             :         else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
     180             :           {
     181             :             emplace_back(std::forward<_Args>(__args)...);
     182             :             iterator __tmp = this->_M_impl._M_finish;
     183             :             --__tmp;
     184             :             return __tmp;
     185             :           }
     186             :         else
     187             :           return _M_insert_aux(__position, std::forward<_Args>(__args)...);
     188             :       }
     189             : #endif
     190             : 
     191             :   template <typename _Tp, typename _Alloc>
     192             :     typename deque<_Tp, _Alloc>::iterator
     193             :     deque<_Tp, _Alloc>::
     194             :     erase(iterator __position)
     195             :     {
     196             :       iterator __next = __position;
     197             :       ++__next;
     198             :       const difference_type __index = __position - begin();
     199             :       if (static_cast<size_type>(__index) < (size() >> 1))
     200             :         {
     201             :           if (__position != begin())
     202             :             _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
     203             :           pop_front();
     204             :         }
     205             :       else
     206             :         {
     207             :           if (__next != end())
     208             :             _GLIBCXX_MOVE3(__next, end(), __position);
     209             :           pop_back();
     210             :         }
     211             :       return begin() + __index;
     212             :     }
     213             : 
     214             :   template <typename _Tp, typename _Alloc>
     215             :     typename deque<_Tp, _Alloc>::iterator
     216             :     deque<_Tp, _Alloc>::
     217             :     erase(iterator __first, iterator __last)
     218             :     {
     219             :       if (__first == __last)
     220             :         return __first;
     221             :       else if (__first == begin() && __last == end())
     222             :         {
     223             :           clear();
     224             :           return end();
     225             :         }
     226             :       else
     227             :         {
     228             :           const difference_type __n = __last - __first;
     229             :           const difference_type __elems_before = __first - begin();
     230             :           if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
     231             :             {
     232             :               if (__first != begin())
     233             :                 _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
     234             :               _M_erase_at_begin(begin() + __n);
     235             :             }
     236             :           else
     237             :             {
     238             :               if (__last != end())
     239             :                 _GLIBCXX_MOVE3(__last, end(), __first);
     240             :               _M_erase_at_end(end() - __n);
     241             :             }
     242             :           return begin() + __elems_before;
     243             :         }
     244             :     }
     245             : 
     246             :   template <typename _Tp, class _Alloc>
     247             :     template <typename _InputIterator>
     248             :       void
     249             :       deque<_Tp, _Alloc>::
     250             :       _M_assign_aux(_InputIterator __first, _InputIterator __last,
     251             :                     std::input_iterator_tag)
     252             :       {
     253             :         iterator __cur = begin();
     254             :         for (; __first != __last && __cur != end(); ++__cur, ++__first)
     255             :           *__cur = *__first;
     256             :         if (__first == __last)
     257             :           _M_erase_at_end(__cur);
     258             :         else
     259             :           insert(end(), __first, __last);
     260             :       }
     261             : 
     262             :   template <typename _Tp, typename _Alloc>
     263             :     void
     264             :     deque<_Tp, _Alloc>::
     265             :     _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
     266             :     {
     267             :       if (__pos._M_cur == this->_M_impl._M_start._M_cur)
     268             :         {
     269             :           iterator __new_start = _M_reserve_elements_at_front(__n);
     270             :           __try
     271             :             {
     272             :               std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
     273             :                                           __x, _M_get_Tp_allocator());
     274             :               this->_M_impl._M_start = __new_start;
     275             :             }
     276             :           __catch(...)
     277             :             {
     278             :               _M_destroy_nodes(__new_start._M_node,
     279             :                                this->_M_impl._M_start._M_node);
     280             :               __throw_exception_again;
     281             :             }
     282             :         }
     283             :       else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
     284             :         {
     285             :           iterator __new_finish = _M_reserve_elements_at_back(__n);
     286             :           __try
     287             :             {
     288             :               std::__uninitialized_fill_a(this->_M_impl._M_finish,
     289             :                                           __new_finish, __x,
     290             :                                           _M_get_Tp_allocator());
     291             :               this->_M_impl._M_finish = __new_finish;
     292             :             }
     293             :           __catch(...)
     294             :             {
     295             :               _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
     296             :                                __new_finish._M_node + 1);
     297             :               __throw_exception_again;
     298             :             }
     299             :         }
     300             :       else
     301             :         _M_insert_aux(__pos, __n, __x);
     302             :     }
     303             : 
     304             : #if __cplusplus >= 201103L
     305             :   template <typename _Tp, typename _Alloc>
     306             :     void
     307           0 :     deque<_Tp, _Alloc>::
     308             :     _M_default_append(size_type __n)
     309             :     {
     310           0 :       if (__n)
     311             :         {
     312           0 :           iterator __new_finish = _M_reserve_elements_at_back(__n);
     313             :           __try
     314             :             {
     315           0 :               std::__uninitialized_default_a(this->_M_impl._M_finish,
     316             :                                              __new_finish,
     317           0 :                                              _M_get_Tp_allocator());
     318           0 :               this->_M_impl._M_finish = __new_finish;
     319             :             }
     320             :           __catch(...)
     321             :             {
     322             :               _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
     323             :                                __new_finish._M_node + 1);
     324             :               __throw_exception_again;
     325             :             }
     326             :         }
     327           0 :     }
     328             : 
     329             :   template <typename _Tp, typename _Alloc>
     330             :     bool
     331             :     deque<_Tp, _Alloc>::
     332             :     _M_shrink_to_fit()
     333             :     {
     334             :       const difference_type __front_capacity
     335             :         = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first);
     336             :       if (__front_capacity == 0)
     337             :         return false;
     338             : 
     339             :       const difference_type __back_capacity
     340             :         = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur);
     341             :       if (__front_capacity + __back_capacity < _S_buffer_size())
     342             :         return false;
     343             : 
     344             :       return std::__shrink_to_fit_aux<deque>::_S_do_it(*this);
     345             :     }
     346             : #endif
     347             : 
     348             :   template <typename _Tp, typename _Alloc>
     349             :     void
     350             :     deque<_Tp, _Alloc>::
     351             :     _M_fill_initialize(const value_type& __value)
     352             :     {
     353             :       _Map_pointer __cur;
     354             :       __try
     355             :         {
     356             :           for (__cur = this->_M_impl._M_start._M_node;
     357             :                __cur < this->_M_impl._M_finish._M_node;
     358             :                ++__cur)
     359             :             std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
     360             :                                         __value, _M_get_Tp_allocator());
     361             :           std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
     362             :                                       this->_M_impl._M_finish._M_cur,
     363             :                                       __value, _M_get_Tp_allocator());
     364             :         }
     365             :       __catch(...)
     366             :         {
     367             :           std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
     368             :                         _M_get_Tp_allocator());
     369             :           __throw_exception_again;
     370             :         }
     371             :     }
     372             : 
     373             :   template <typename _Tp, typename _Alloc>
     374             :     template <typename _InputIterator>
     375             :       void
     376             :       deque<_Tp, _Alloc>::
     377             :       _M_range_initialize(_InputIterator __first, _InputIterator __last,
     378             :                           std::input_iterator_tag)
     379             :       {
     380             :         this->_M_initialize_map(0);
     381             :         __try
     382             :           {
     383             :             for (; __first != __last; ++__first)
     384             : #if __cplusplus >= 201103L
     385             :               emplace_back(*__first);
     386             : #else
     387             :               push_back(*__first);
     388             : #endif
     389             :           }
     390             :         __catch(...)
     391             :           {
     392             :             clear();
     393             :             __throw_exception_again;
     394             :           }
     395             :       }
     396             : 
     397             :   template <typename _Tp, typename _Alloc>
     398             :     template <typename _ForwardIterator>
     399             :       void
     400             :       deque<_Tp, _Alloc>::
     401             :       _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
     402             :                           std::forward_iterator_tag)
     403             :       {
     404             :         const size_type __n = std::distance(__first, __last);
     405             :         this->_M_initialize_map(__n);
     406             : 
     407             :         _Map_pointer __cur_node;
     408             :         __try
     409             :           {
     410             :             for (__cur_node = this->_M_impl._M_start._M_node;
     411             :                  __cur_node < this->_M_impl._M_finish._M_node;
     412             :                  ++__cur_node)
     413             :               {
     414             :                 _ForwardIterator __mid = __first;
     415             :                 std::advance(__mid, _S_buffer_size());
     416             :                 std::__uninitialized_copy_a(__first, __mid, *__cur_node,
     417             :                                             _M_get_Tp_allocator());
     418             :                 __first = __mid;
     419             :               }
     420             :             std::__uninitialized_copy_a(__first, __last,
     421             :                                         this->_M_impl._M_finish._M_first,
     422             :                                         _M_get_Tp_allocator());
     423             :           }
     424             :         __catch(...)
     425             :           {
     426             :             std::_Destroy(this->_M_impl._M_start,
     427             :                           iterator(*__cur_node, __cur_node),
     428             :                           _M_get_Tp_allocator());
     429             :             __throw_exception_again;
     430             :           }
     431             :       }
     432             : 
     433             :   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
     434             :   template<typename _Tp, typename _Alloc>
     435             : #if __cplusplus >= 201103L
     436             :     template<typename... _Args>
     437             :       void
     438        9961 :       deque<_Tp, _Alloc>::
     439             :       _M_push_back_aux(_Args&&... __args)
     440             : #else
     441             :       void
     442             :       deque<_Tp, _Alloc>::
     443             :       _M_push_back_aux(const value_type& __t)
     444             : #endif
     445             :       {
     446        9961 :         _M_reserve_map_at_back();
     447        9961 :         *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
     448             :         __try
     449             :           {
     450             : #if __cplusplus >= 201103L
     451        9961 :             this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
     452        9961 :                                     std::forward<_Args>(__args)...);
     453             : #else
     454             :             this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
     455             : #endif
     456        9961 :             this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
     457             :                                                 + 1);
     458        9961 :             this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
     459             :           }
     460             :         __catch(...)
     461             :           {
     462             :             _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
     463             :             __throw_exception_again;
     464             :           }
     465        9961 :       }
     466             : 
     467             :   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
     468             :   template<typename _Tp, typename _Alloc>
     469             : #if __cplusplus >= 201103L
     470             :     template<typename... _Args>
     471             :       void
     472           6 :       deque<_Tp, _Alloc>::
     473             :       _M_push_front_aux(_Args&&... __args)
     474             : #else
     475             :       void
     476             :       deque<_Tp, _Alloc>::
     477             :       _M_push_front_aux(const value_type& __t)
     478             : #endif
     479             :       {
     480           6 :         _M_reserve_map_at_front();
     481           6 :         *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
     482             :         __try
     483             :           {
     484           6 :             this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
     485             :                                                - 1);
     486           6 :             this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
     487             : #if __cplusplus >= 201103L
     488           6 :             this->_M_impl.construct(this->_M_impl._M_start._M_cur,
     489           6 :                                     std::forward<_Args>(__args)...);
     490             : #else
     491             :             this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
     492             : #endif
     493             :           }
     494             :         __catch(...)
     495             :           {
     496             :             ++this->_M_impl._M_start;
     497             :             _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
     498             :             __throw_exception_again;
     499             :           }
     500           6 :       }
     501             : 
     502             :   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
     503             :   template <typename _Tp, typename _Alloc>
     504             :     void deque<_Tp, _Alloc>::
     505             :     _M_pop_back_aux()
     506             :     {
     507             :       _M_deallocate_node(this->_M_impl._M_finish._M_first);
     508             :       this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
     509             :       this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
     510             :       this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
     511             :     }
     512             : 
     513             :   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
     514             :   // Note that if the deque has at least one element (a precondition for this
     515             :   // member function), and if
     516             :   //   _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
     517             :   // then the deque must have at least two nodes.
     518             :   template <typename _Tp, typename _Alloc>
     519        9961 :     void deque<_Tp, _Alloc>::
     520             :     _M_pop_front_aux()
     521             :     {
     522        9961 :       this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
     523        9961 :       _M_deallocate_node(this->_M_impl._M_start._M_first);
     524        9961 :       this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
     525        9961 :       this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
     526        9961 :     }
     527             : 
     528             :   template <typename _Tp, typename _Alloc>
     529             :     template <typename _InputIterator>
     530             :       void
     531             :       deque<_Tp, _Alloc>::
     532             :       _M_range_insert_aux(iterator __pos,
     533             :                           _InputIterator __first, _InputIterator __last,
     534             :                           std::input_iterator_tag)
     535             :       { std::copy(__first, __last, std::inserter(*this, __pos)); }
     536             : 
     537             :   template <typename _Tp, typename _Alloc>
     538             :     template <typename _ForwardIterator>
     539             :       void
     540             :       deque<_Tp, _Alloc>::
     541             :       _M_range_insert_aux(iterator __pos,
     542             :                           _ForwardIterator __first, _ForwardIterator __last,
     543             :                           std::forward_iterator_tag)
     544             :       {
     545             :         const size_type __n = std::distance(__first, __last);
     546             :         if (__pos._M_cur == this->_M_impl._M_start._M_cur)
     547             :           {
     548             :             iterator __new_start = _M_reserve_elements_at_front(__n);
     549             :             __try
     550             :               {
     551             :                 std::__uninitialized_copy_a(__first, __last, __new_start,
     552             :                                             _M_get_Tp_allocator());
     553             :                 this->_M_impl._M_start = __new_start;
     554             :               }
     555             :             __catch(...)
     556             :               {
     557             :                 _M_destroy_nodes(__new_start._M_node,
     558             :                                  this->_M_impl._M_start._M_node);
     559             :                 __throw_exception_again;
     560             :               }
     561             :           }
     562             :         else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
     563             :           {
     564             :             iterator __new_finish = _M_reserve_elements_at_back(__n);
     565             :             __try
     566             :               {
     567             :                 std::__uninitialized_copy_a(__first, __last,
     568             :                                             this->_M_impl._M_finish,
     569             :                                             _M_get_Tp_allocator());
     570             :                 this->_M_impl._M_finish = __new_finish;
     571             :               }
     572             :             __catch(...)
     573             :               {
     574             :                 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
     575             :                                  __new_finish._M_node + 1);
     576             :                 __throw_exception_again;
     577             :               }
     578             :           }
     579             :         else
     580             :           _M_insert_aux(__pos, __first, __last, __n);
     581             :       }
     582             : 
     583             :   template<typename _Tp, typename _Alloc>
     584             : #if __cplusplus >= 201103L
     585             :     template<typename... _Args>
     586             :       typename deque<_Tp, _Alloc>::iterator
     587             :       deque<_Tp, _Alloc>::
     588             :       _M_insert_aux(iterator __pos, _Args&&... __args)
     589             :       {
     590             :         value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
     591             : #else
     592             :     typename deque<_Tp, _Alloc>::iterator
     593             :       deque<_Tp, _Alloc>::
     594             :       _M_insert_aux(iterator __pos, const value_type& __x)
     595             :       {
     596             :         value_type __x_copy = __x; // XXX copy
     597             : #endif
     598             :         difference_type __index = __pos - this->_M_impl._M_start;
     599             :         if (static_cast<size_type>(__index) < size() / 2)
     600             :           {
     601             :             push_front(_GLIBCXX_MOVE(front()));
     602             :             iterator __front1 = this->_M_impl._M_start;
     603             :             ++__front1;
     604             :             iterator __front2 = __front1;
     605             :             ++__front2;
     606             :             __pos = this->_M_impl._M_start + __index;
     607             :             iterator __pos1 = __pos;
     608             :             ++__pos1;
     609             :             _GLIBCXX_MOVE3(__front2, __pos1, __front1);
     610             :           }
     611             :         else
     612             :           {
     613             :             push_back(_GLIBCXX_MOVE(back()));
     614             :             iterator __back1 = this->_M_impl._M_finish;
     615             :             --__back1;
     616             :             iterator __back2 = __back1;
     617             :             --__back2;
     618             :             __pos = this->_M_impl._M_start + __index;
     619             :             _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
     620             :           }
     621             :         *__pos = _GLIBCXX_MOVE(__x_copy);
     622             :         return __pos;
     623             :       }
     624             : 
     625             :   template <typename _Tp, typename _Alloc>
     626             :     void
     627             :     deque<_Tp, _Alloc>::
     628             :     _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
     629             :     {
     630             :       const difference_type __elems_before = __pos - this->_M_impl._M_start;
     631             :       const size_type __length = this->size();
     632             :       value_type __x_copy = __x;
     633             :       if (__elems_before < difference_type(__length / 2))
     634             :         {
     635             :           iterator __new_start = _M_reserve_elements_at_front(__n);
     636             :           iterator __old_start = this->_M_impl._M_start;
     637             :           __pos = this->_M_impl._M_start + __elems_before;
     638             :           __try
     639             :             {
     640             :               if (__elems_before >= difference_type(__n))
     641             :                 {
     642             :                   iterator __start_n = (this->_M_impl._M_start
     643             :                                         + difference_type(__n));
     644             :                   std::__uninitialized_move_a(this->_M_impl._M_start,
     645             :                                               __start_n, __new_start,
     646             :                                               _M_get_Tp_allocator());
     647             :                   this->_M_impl._M_start = __new_start;
     648             :                   _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
     649             :                   std::fill(__pos - difference_type(__n), __pos, __x_copy);
     650             :                 }
     651             :               else
     652             :                 {
     653             :                   std::__uninitialized_move_fill(this->_M_impl._M_start,
     654             :                                                  __pos, __new_start,
     655             :                                                  this->_M_impl._M_start,
     656             :                                                  __x_copy,
     657             :                                                  _M_get_Tp_allocator());
     658             :                   this->_M_impl._M_start = __new_start;
     659             :                   std::fill(__old_start, __pos, __x_copy);
     660             :                 }
     661             :             }
     662             :           __catch(...)
     663             :             {
     664             :               _M_destroy_nodes(__new_start._M_node,
     665             :                                this->_M_impl._M_start._M_node);
     666             :               __throw_exception_again;
     667             :             }
     668             :         }
     669             :       else
     670             :         {
     671             :           iterator __new_finish = _M_reserve_elements_at_back(__n);
     672             :           iterator __old_finish = this->_M_impl._M_finish;
     673             :           const difference_type __elems_after =
     674             :             difference_type(__length) - __elems_before;
     675             :           __pos = this->_M_impl._M_finish - __elems_after;
     676             :           __try
     677             :             {
     678             :               if (__elems_after > difference_type(__n))
     679             :                 {
     680             :                   iterator __finish_n = (this->_M_impl._M_finish
     681             :                                          - difference_type(__n));
     682             :                   std::__uninitialized_move_a(__finish_n,
     683             :                                               this->_M_impl._M_finish,
     684             :                                               this->_M_impl._M_finish,
     685             :                                               _M_get_Tp_allocator());
     686             :                   this->_M_impl._M_finish = __new_finish;
     687             :                   _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
     688             :                   std::fill(__pos, __pos + difference_type(__n), __x_copy);
     689             :                 }
     690             :               else
     691             :                 {
     692             :                   std::__uninitialized_fill_move(this->_M_impl._M_finish,
     693             :                                                  __pos + difference_type(__n),
     694             :                                                  __x_copy, __pos,
     695             :                                                  this->_M_impl._M_finish,
     696             :                                                  _M_get_Tp_allocator());
     697             :                   this->_M_impl._M_finish = __new_finish;
     698             :                   std::fill(__pos, __old_finish, __x_copy);
     699             :                 }
     700             :             }
     701             :           __catch(...)
     702             :             {
     703             :               _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
     704             :                                __new_finish._M_node + 1);
     705             :               __throw_exception_again;
     706             :             }
     707             :         }
     708             :     }
     709             : 
     710             :   template <typename _Tp, typename _Alloc>
     711             :     template <typename _ForwardIterator>
     712             :       void
     713             :       deque<_Tp, _Alloc>::
     714             :       _M_insert_aux(iterator __pos,
     715             :                     _ForwardIterator __first, _ForwardIterator __last,
     716             :                     size_type __n)
     717             :       {
     718             :         const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
     719             :         const size_type __length = size();
     720             :         if (static_cast<size_type>(__elemsbefore) < __length / 2)
     721             :           {
     722             :             iterator __new_start = _M_reserve_elements_at_front(__n);
     723             :             iterator __old_start = this->_M_impl._M_start;
     724             :             __pos = this->_M_impl._M_start + __elemsbefore;
     725             :             __try
     726             :               {
     727             :                 if (__elemsbefore >= difference_type(__n))
     728             :                   {
     729             :                     iterator __start_n = (this->_M_impl._M_start
     730             :                                           + difference_type(__n));
     731             :                     std::__uninitialized_move_a(this->_M_impl._M_start,
     732             :                                                 __start_n, __new_start,
     733             :                                                 _M_get_Tp_allocator());
     734             :                     this->_M_impl._M_start = __new_start;
     735             :                     _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
     736             :                     std::copy(__first, __last, __pos - difference_type(__n));
     737             :                   }
     738             :                 else
     739             :                   {
     740             :                     _ForwardIterator __mid = __first;
     741             :                     std::advance(__mid, difference_type(__n) - __elemsbefore);
     742             :                     std::__uninitialized_move_copy(this->_M_impl._M_start,
     743             :                                                    __pos, __first, __mid,
     744             :                                                    __new_start,
     745             :                                                    _M_get_Tp_allocator());
     746             :                     this->_M_impl._M_start = __new_start;
     747             :                     std::copy(__mid, __last, __old_start);
     748             :                   }
     749             :               }
     750             :             __catch(...)
     751             :               {
     752             :                 _M_destroy_nodes(__new_start._M_node,
     753             :                                  this->_M_impl._M_start._M_node);
     754             :                 __throw_exception_again;
     755             :               }
     756             :           }
     757             :         else
     758             :         {
     759             :           iterator __new_finish = _M_reserve_elements_at_back(__n);
     760             :           iterator __old_finish = this->_M_impl._M_finish;
     761             :           const difference_type __elemsafter =
     762             :             difference_type(__length) - __elemsbefore;
     763             :           __pos = this->_M_impl._M_finish - __elemsafter;
     764             :           __try
     765             :             {
     766             :               if (__elemsafter > difference_type(__n))
     767             :                 {
     768             :                   iterator __finish_n = (this->_M_impl._M_finish
     769             :                                          - difference_type(__n));
     770             :                   std::__uninitialized_move_a(__finish_n,
     771             :                                               this->_M_impl._M_finish,
     772             :                                               this->_M_impl._M_finish,
     773             :                                               _M_get_Tp_allocator());
     774             :                   this->_M_impl._M_finish = __new_finish;
     775             :                   _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
     776             :                   std::copy(__first, __last, __pos);
     777             :                 }
     778             :               else
     779             :                 {
     780             :                   _ForwardIterator __mid = __first;
     781             :                   std::advance(__mid, __elemsafter);
     782             :                   std::__uninitialized_copy_move(__mid, __last, __pos,
     783             :                                                  this->_M_impl._M_finish,
     784             :                                                  this->_M_impl._M_finish,
     785             :                                                  _M_get_Tp_allocator());
     786             :                   this->_M_impl._M_finish = __new_finish;
     787             :                   std::copy(__first, __mid, __pos);
     788             :                 }
     789             :             }
     790             :           __catch(...)
     791             :             {
     792             :               _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
     793             :                                __new_finish._M_node + 1);
     794             :               __throw_exception_again;
     795             :             }
     796             :         }
     797             :       }
     798             : 
     799             :    template<typename _Tp, typename _Alloc>
     800             :      void
     801         362 :      deque<_Tp, _Alloc>::
     802             :      _M_destroy_data_aux(iterator __first, iterator __last)
     803             :      {
     804         362 :        for (_Map_pointer __node = __first._M_node + 1;
     805             :             __node < __last._M_node; ++__node)
     806           0 :          std::_Destroy(*__node, *__node + _S_buffer_size(),
     807           0 :                        _M_get_Tp_allocator());
     808             : 
     809         362 :        if (__first._M_node != __last._M_node)
     810             :          {
     811           6 :            std::_Destroy(__first._M_cur, __first._M_last,
     812           6 :                          _M_get_Tp_allocator());
     813           6 :            std::_Destroy(__last._M_first, __last._M_cur,
     814           6 :                          _M_get_Tp_allocator());
     815             :          }
     816             :        else
     817         356 :          std::_Destroy(__first._M_cur, __last._M_cur,
     818         356 :                        _M_get_Tp_allocator());
     819         362 :      }
     820             : 
     821             :   template <typename _Tp, typename _Alloc>
     822             :     void
     823             :     deque<_Tp, _Alloc>::
     824             :     _M_new_elements_at_front(size_type __new_elems)
     825             :     {
     826             :       if (this->max_size() - this->size() < __new_elems)
     827             :         __throw_length_error(__N("deque::_M_new_elements_at_front"));
     828             : 
     829             :       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
     830             :                                      / _S_buffer_size());
     831             :       _M_reserve_map_at_front(__new_nodes);
     832             :       size_type __i;
     833             :       __try
     834             :         {
     835             :           for (__i = 1; __i <= __new_nodes; ++__i)
     836             :             *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
     837             :         }
     838             :       __catch(...)
     839             :         {
     840             :           for (size_type __j = 1; __j < __i; ++__j)
     841             :             _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
     842             :           __throw_exception_again;
     843             :         }
     844             :     }
     845             : 
     846             :   template <typename _Tp, typename _Alloc>
     847             :     void
     848           0 :     deque<_Tp, _Alloc>::
     849             :     _M_new_elements_at_back(size_type __new_elems)
     850             :     {
     851           0 :       if (this->max_size() - this->size() < __new_elems)
     852           0 :         __throw_length_error(__N("deque::_M_new_elements_at_back"));
     853             : 
     854           0 :       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
     855           0 :                                      / _S_buffer_size());
     856           0 :       _M_reserve_map_at_back(__new_nodes);
     857             :       size_type __i;
     858             :       __try
     859             :         {
     860           0 :           for (__i = 1; __i <= __new_nodes; ++__i)
     861           0 :             *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
     862             :         }
     863             :       __catch(...)
     864             :         {
     865             :           for (size_type __j = 1; __j < __i; ++__j)
     866             :             _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
     867             :           __throw_exception_again;
     868             :         }
     869           0 :     }
     870             : 
     871             :   template <typename _Tp, typename _Alloc>
     872             :     void
     873        2486 :     deque<_Tp, _Alloc>::
     874             :     _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
     875             :     {
     876             :       const size_type __old_num_nodes
     877        2486 :         = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
     878        2486 :       const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
     879             : 
     880             :       _Map_pointer __new_nstart;
     881        2486 :       if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
     882             :         {
     883        2486 :           __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
     884             :                                          - __new_num_nodes) / 2
     885        2486 :                          + (__add_at_front ? __nodes_to_add : 0);
     886        2486 :           if (__new_nstart < this->_M_impl._M_start._M_node)
     887        2486 :             std::copy(this->_M_impl._M_start._M_node,
     888             :                       this->_M_impl._M_finish._M_node + 1,
     889        2486 :                       __new_nstart);
     890             :           else
     891           0 :             std::copy_backward(this->_M_impl._M_start._M_node,
     892             :                                this->_M_impl._M_finish._M_node + 1,
     893           0 :                                __new_nstart + __old_num_nodes);
     894             :         }
     895             :       else
     896             :         {
     897             :           size_type __new_map_size = this->_M_impl._M_map_size
     898             :                                      + std::max(this->_M_impl._M_map_size,
     899           0 :                                                 __nodes_to_add) + 2;
     900             : 
     901           0 :           _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
     902           0 :           __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
     903           0 :                          + (__add_at_front ? __nodes_to_add : 0);
     904           0 :           std::copy(this->_M_impl._M_start._M_node,
     905             :                     this->_M_impl._M_finish._M_node + 1,
     906           0 :                     __new_nstart);
     907           0 :           _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
     908             : 
     909           0 :           this->_M_impl._M_map = __new_map;
     910           0 :           this->_M_impl._M_map_size = __new_map_size;
     911             :         }
     912             : 
     913        2486 :       this->_M_impl._M_start._M_set_node(__new_nstart);
     914        2486 :       this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
     915        2486 :     }
     916             : 
     917             :   // Overload for deque::iterators, exploiting the "segmented-iterator
     918             :   // optimization".
     919             :   template<typename _Tp>
     920             :     void
     921             :     fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
     922             :          const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
     923             :     {
     924             :       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
     925             : 
     926             :       for (typename _Self::_Map_pointer __node = __first._M_node + 1;
     927             :            __node < __last._M_node; ++__node)
     928             :         std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
     929             : 
     930             :       if (__first._M_node != __last._M_node)
     931             :         {
     932             :           std::fill(__first._M_cur, __first._M_last, __value);
     933             :           std::fill(__last._M_first, __last._M_cur, __value);
     934             :         }
     935             :       else
     936             :         std::fill(__first._M_cur, __last._M_cur, __value);
     937             :     }
     938             : 
     939             :   template<typename _Tp>
     940             :     _Deque_iterator<_Tp, _Tp&, _Tp*>
     941             :     copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
     942             :          _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
     943             :          _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
     944             :     {
     945             :       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
     946             :       typedef typename _Self::difference_type difference_type;
     947             : 
     948             :       difference_type __len = __last - __first;
     949             :       while (__len > 0)
     950             :         {
     951             :           const difference_type __clen
     952             :             = std::min(__len, std::min(__first._M_last - __first._M_cur,
     953             :                                        __result._M_last - __result._M_cur));
     954             :           std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur);
     955             :           __first += __clen;
     956             :           __result += __clen;
     957             :           __len -= __clen;
     958             :         }
     959             :       return __result;
     960             :     }
     961             : 
     962             :   template<typename _Tp>
     963             :     _Deque_iterator<_Tp, _Tp&, _Tp*>
     964             :     copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
     965             :                   _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
     966             :                   _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
     967             :     {
     968             :       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
     969             :       typedef typename _Self::difference_type difference_type;
     970             : 
     971             :       difference_type __len = __last - __first;
     972             :       while (__len > 0)
     973             :         {
     974             :           difference_type __llen = __last._M_cur - __last._M_first;
     975             :           _Tp* __lend = __last._M_cur;
     976             : 
     977             :           difference_type __rlen = __result._M_cur - __result._M_first;
     978             :           _Tp* __rend = __result._M_cur;
     979             : 
     980             :           if (!__llen)
     981             :             {
     982             :               __llen = _Self::_S_buffer_size();
     983             :               __lend = *(__last._M_node - 1) + __llen;
     984             :             }
     985             :           if (!__rlen)
     986             :             {
     987             :               __rlen = _Self::_S_buffer_size();
     988             :               __rend = *(__result._M_node - 1) + __rlen;
     989             :             }
     990             : 
     991             :           const difference_type __clen = std::min(__len,
     992             :                                                   std::min(__llen, __rlen));
     993             :           std::copy_backward(__lend - __clen, __lend, __rend);
     994             :           __last -= __clen;
     995             :           __result -= __clen;
     996             :           __len -= __clen;
     997             :         }
     998             :       return __result;
     999             :     }
    1000             : 
    1001             : #if __cplusplus >= 201103L
    1002             :   template<typename _Tp>
    1003             :     _Deque_iterator<_Tp, _Tp&, _Tp*>
    1004             :     move(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
    1005             :          _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
    1006             :          _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
    1007             :     {
    1008             :       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
    1009             :       typedef typename _Self::difference_type difference_type;
    1010             : 
    1011             :       difference_type __len = __last - __first;
    1012             :       while (__len > 0)
    1013             :         {
    1014             :           const difference_type __clen
    1015             :             = std::min(__len, std::min(__first._M_last - __first._M_cur,
    1016             :                                        __result._M_last - __result._M_cur));
    1017             :           std::move(__first._M_cur, __first._M_cur + __clen, __result._M_cur);
    1018             :           __first += __clen;
    1019             :           __result += __clen;
    1020             :           __len -= __clen;
    1021             :         }
    1022             :       return __result;
    1023             :     }
    1024             : 
    1025             :   template<typename _Tp>
    1026             :     _Deque_iterator<_Tp, _Tp&, _Tp*>
    1027             :     move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
    1028             :                   _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
    1029             :                   _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
    1030             :     {
    1031             :       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
    1032             :       typedef typename _Self::difference_type difference_type;
    1033             : 
    1034             :       difference_type __len = __last - __first;
    1035             :       while (__len > 0)
    1036             :         {
    1037             :           difference_type __llen = __last._M_cur - __last._M_first;
    1038             :           _Tp* __lend = __last._M_cur;
    1039             : 
    1040             :           difference_type __rlen = __result._M_cur - __result._M_first;
    1041             :           _Tp* __rend = __result._M_cur;
    1042             : 
    1043             :           if (!__llen)
    1044             :             {
    1045             :               __llen = _Self::_S_buffer_size();
    1046             :               __lend = *(__last._M_node - 1) + __llen;
    1047             :             }
    1048             :           if (!__rlen)
    1049             :             {
    1050             :               __rlen = _Self::_S_buffer_size();
    1051             :               __rend = *(__result._M_node - 1) + __rlen;
    1052             :             }
    1053             : 
    1054             :           const difference_type __clen = std::min(__len,
    1055             :                                                   std::min(__llen, __rlen));
    1056             :           std::move_backward(__lend - __clen, __lend, __rend);
    1057             :           __last -= __clen;
    1058             :           __result -= __clen;
    1059             :           __len -= __clen;
    1060             :         }
    1061             :       return __result;
    1062             :     }
    1063             : #endif
    1064             : 
    1065             : _GLIBCXX_END_NAMESPACE_CONTAINER
    1066             : } // namespace std
    1067             : 
    1068             : #endif

Generated by: LCOV version 1.10