xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/bits/deque.tcc (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // Deque implementation (out of line) -*- C++ -*-
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4*404b540aSrobert // Free Software Foundation, Inc.
5*404b540aSrobert //
6*404b540aSrobert // This file is part of the GNU ISO C++ Library.  This library is free
7*404b540aSrobert // software; you can redistribute it and/or modify it under the
8*404b540aSrobert // terms of the GNU General Public License as published by the
9*404b540aSrobert // Free Software Foundation; either version 2, or (at your option)
10*404b540aSrobert // any later version.
11*404b540aSrobert 
12*404b540aSrobert // This library is distributed in the hope that it will be useful,
13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*404b540aSrobert // GNU General Public License for more details.
16*404b540aSrobert 
17*404b540aSrobert // You should have received a copy of the GNU General Public License along
18*404b540aSrobert // with this library; see the file COPYING.  If not, write to the Free
19*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20*404b540aSrobert // USA.
21*404b540aSrobert 
22*404b540aSrobert // As a special exception, you may use this file as part of a free software
23*404b540aSrobert // library without restriction.  Specifically, if other files instantiate
24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
25*404b540aSrobert // this file and link it with other files to produce an executable, this
26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
27*404b540aSrobert // the GNU General Public License.  This exception does not however
28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
29*404b540aSrobert // the GNU General Public License.
30*404b540aSrobert 
31*404b540aSrobert /*
32*404b540aSrobert  *
33*404b540aSrobert  * Copyright (c) 1994
34*404b540aSrobert  * Hewlett-Packard Company
35*404b540aSrobert  *
36*404b540aSrobert  * Permission to use, copy, modify, distribute and sell this software
37*404b540aSrobert  * and its documentation for any purpose is hereby granted without fee,
38*404b540aSrobert  * provided that the above copyright notice appear in all copies and
39*404b540aSrobert  * that both that copyright notice and this permission notice appear
40*404b540aSrobert  * in supporting documentation.  Hewlett-Packard Company makes no
41*404b540aSrobert  * representations about the suitability of this software for any
42*404b540aSrobert  * purpose.  It is provided "as is" without express or implied warranty.
43*404b540aSrobert  *
44*404b540aSrobert  *
45*404b540aSrobert  * Copyright (c) 1997
46*404b540aSrobert  * Silicon Graphics Computer Systems, Inc.
47*404b540aSrobert  *
48*404b540aSrobert  * Permission to use, copy, modify, distribute and sell this software
49*404b540aSrobert  * and its documentation for any purpose is hereby granted without fee,
50*404b540aSrobert  * provided that the above copyright notice appear in all copies and
51*404b540aSrobert  * that both that copyright notice and this permission notice appear
52*404b540aSrobert  * in supporting documentation.  Silicon Graphics makes no
53*404b540aSrobert  * representations about the suitability of this software for any
54*404b540aSrobert  * purpose.  It is provided "as is" without express or implied warranty.
55*404b540aSrobert  */
56*404b540aSrobert 
57*404b540aSrobert /** @file deque.tcc
58*404b540aSrobert  *  This is an internal header file, included by other library headers.
59*404b540aSrobert  *  You should not attempt to use it directly.
60*404b540aSrobert  */
61*404b540aSrobert 
62*404b540aSrobert #ifndef _DEQUE_TCC
63*404b540aSrobert #define _DEQUE_TCC 1
64*404b540aSrobert 
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std,_GLIBCXX_STD)65*404b540aSrobert _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
66*404b540aSrobert 
67*404b540aSrobert   template <typename _Tp, typename _Alloc>
68*404b540aSrobert     deque<_Tp, _Alloc>&
69*404b540aSrobert     deque<_Tp, _Alloc>::
70*404b540aSrobert     operator=(const deque& __x)
71*404b540aSrobert     {
72*404b540aSrobert       const size_type __len = size();
73*404b540aSrobert       if (&__x != this)
74*404b540aSrobert 	{
75*404b540aSrobert 	  if (__len >= __x.size())
76*404b540aSrobert 	    _M_erase_at_end(std::copy(__x.begin(), __x.end(),
77*404b540aSrobert 				      this->_M_impl._M_start));
78*404b540aSrobert 	  else
79*404b540aSrobert 	    {
80*404b540aSrobert 	      const_iterator __mid = __x.begin() + difference_type(__len);
81*404b540aSrobert 	      std::copy(__x.begin(), __mid, this->_M_impl._M_start);
82*404b540aSrobert 	      insert(this->_M_impl._M_finish, __mid, __x.end());
83*404b540aSrobert 	    }
84*404b540aSrobert 	}
85*404b540aSrobert       return *this;
86*404b540aSrobert     }
87*404b540aSrobert 
88*404b540aSrobert   template <typename _Tp, typename _Alloc>
89*404b540aSrobert     typename deque<_Tp, _Alloc>::iterator
90*404b540aSrobert     deque<_Tp, _Alloc>::
insert(iterator __position,const value_type & __x)91*404b540aSrobert     insert(iterator __position, const value_type& __x)
92*404b540aSrobert     {
93*404b540aSrobert       if (__position._M_cur == this->_M_impl._M_start._M_cur)
94*404b540aSrobert 	{
95*404b540aSrobert 	  push_front(__x);
96*404b540aSrobert 	  return this->_M_impl._M_start;
97*404b540aSrobert 	}
98*404b540aSrobert       else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
99*404b540aSrobert 	{
100*404b540aSrobert 	  push_back(__x);
101*404b540aSrobert 	  iterator __tmp = this->_M_impl._M_finish;
102*404b540aSrobert 	  --__tmp;
103*404b540aSrobert 	  return __tmp;
104*404b540aSrobert 	}
105*404b540aSrobert       else
106*404b540aSrobert         return _M_insert_aux(__position, __x);
107*404b540aSrobert     }
108*404b540aSrobert 
109*404b540aSrobert   template <typename _Tp, typename _Alloc>
110*404b540aSrobert     typename deque<_Tp, _Alloc>::iterator
111*404b540aSrobert     deque<_Tp, _Alloc>::
erase(iterator __position)112*404b540aSrobert     erase(iterator __position)
113*404b540aSrobert     {
114*404b540aSrobert       iterator __next = __position;
115*404b540aSrobert       ++__next;
116*404b540aSrobert       const difference_type __index = __position - begin();
117*404b540aSrobert       if (static_cast<size_type>(__index) < (size() >> 1))
118*404b540aSrobert 	{
119*404b540aSrobert 	  if (__position != begin())
120*404b540aSrobert 	    std::copy_backward(begin(), __position, __next);
121*404b540aSrobert 	  pop_front();
122*404b540aSrobert 	}
123*404b540aSrobert       else
124*404b540aSrobert 	{
125*404b540aSrobert 	  if (__next != end())
126*404b540aSrobert 	    std::copy(__next, end(), __position);
127*404b540aSrobert 	  pop_back();
128*404b540aSrobert 	}
129*404b540aSrobert       return begin() + __index;
130*404b540aSrobert     }
131*404b540aSrobert 
132*404b540aSrobert   template <typename _Tp, typename _Alloc>
133*404b540aSrobert     typename deque<_Tp, _Alloc>::iterator
134*404b540aSrobert     deque<_Tp, _Alloc>::
erase(iterator __first,iterator __last)135*404b540aSrobert     erase(iterator __first, iterator __last)
136*404b540aSrobert     {
137*404b540aSrobert       if (__first == begin() && __last == end())
138*404b540aSrobert 	{
139*404b540aSrobert 	  clear();
140*404b540aSrobert 	  return end();
141*404b540aSrobert 	}
142*404b540aSrobert       else
143*404b540aSrobert 	{
144*404b540aSrobert 	  const difference_type __n = __last - __first;
145*404b540aSrobert 	  const difference_type __elems_before = __first - begin();
146*404b540aSrobert 	  if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
147*404b540aSrobert 	    {
148*404b540aSrobert 	      if (__first != begin())
149*404b540aSrobert 		std::copy_backward(begin(), __first, __last);
150*404b540aSrobert 	      _M_erase_at_begin(begin() + __n);
151*404b540aSrobert 	    }
152*404b540aSrobert 	  else
153*404b540aSrobert 	    {
154*404b540aSrobert 	      if (__last != end())
155*404b540aSrobert 		std::copy(__last, end(), __first);
156*404b540aSrobert 	      _M_erase_at_end(end() - __n);
157*404b540aSrobert 	    }
158*404b540aSrobert 	  return begin() + __elems_before;
159*404b540aSrobert 	}
160*404b540aSrobert     }
161*404b540aSrobert 
162*404b540aSrobert   template <typename _Tp, class _Alloc>
163*404b540aSrobert     template <typename _InputIterator>
164*404b540aSrobert       void
165*404b540aSrobert       deque<_Tp, _Alloc>::
_M_assign_aux(_InputIterator __first,_InputIterator __last,std::input_iterator_tag)166*404b540aSrobert       _M_assign_aux(_InputIterator __first, _InputIterator __last,
167*404b540aSrobert 		    std::input_iterator_tag)
168*404b540aSrobert       {
169*404b540aSrobert         iterator __cur = begin();
170*404b540aSrobert         for (; __first != __last && __cur != end(); ++__cur, ++__first)
171*404b540aSrobert           *__cur = *__first;
172*404b540aSrobert         if (__first == __last)
173*404b540aSrobert           _M_erase_at_end(__cur);
174*404b540aSrobert         else
175*404b540aSrobert           insert(end(), __first, __last);
176*404b540aSrobert       }
177*404b540aSrobert 
178*404b540aSrobert   template <typename _Tp, typename _Alloc>
179*404b540aSrobert     void
180*404b540aSrobert     deque<_Tp, _Alloc>::
_M_fill_insert(iterator __pos,size_type __n,const value_type & __x)181*404b540aSrobert     _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
182*404b540aSrobert     {
183*404b540aSrobert       if (__pos._M_cur == this->_M_impl._M_start._M_cur)
184*404b540aSrobert 	{
185*404b540aSrobert 	  iterator __new_start = _M_reserve_elements_at_front(__n);
186*404b540aSrobert 	  try
187*404b540aSrobert 	    {
188*404b540aSrobert 	      std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
189*404b540aSrobert 					  __x, _M_get_Tp_allocator());
190*404b540aSrobert 	      this->_M_impl._M_start = __new_start;
191*404b540aSrobert 	    }
192*404b540aSrobert 	  catch(...)
193*404b540aSrobert 	    {
194*404b540aSrobert 	      _M_destroy_nodes(__new_start._M_node,
195*404b540aSrobert 			       this->_M_impl._M_start._M_node);
196*404b540aSrobert 	      __throw_exception_again;
197*404b540aSrobert 	    }
198*404b540aSrobert 	}
199*404b540aSrobert       else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
200*404b540aSrobert 	{
201*404b540aSrobert 	  iterator __new_finish = _M_reserve_elements_at_back(__n);
202*404b540aSrobert 	  try
203*404b540aSrobert 	    {
204*404b540aSrobert 	      std::__uninitialized_fill_a(this->_M_impl._M_finish,
205*404b540aSrobert 					  __new_finish, __x,
206*404b540aSrobert 					  _M_get_Tp_allocator());
207*404b540aSrobert 	      this->_M_impl._M_finish = __new_finish;
208*404b540aSrobert 	    }
209*404b540aSrobert 	  catch(...)
210*404b540aSrobert 	    {
211*404b540aSrobert 	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
212*404b540aSrobert 			       __new_finish._M_node + 1);
213*404b540aSrobert 	      __throw_exception_again;
214*404b540aSrobert 	    }
215*404b540aSrobert 	}
216*404b540aSrobert       else
217*404b540aSrobert         _M_insert_aux(__pos, __n, __x);
218*404b540aSrobert     }
219*404b540aSrobert 
220*404b540aSrobert   template <typename _Tp, typename _Alloc>
221*404b540aSrobert     void
222*404b540aSrobert     deque<_Tp, _Alloc>::
_M_fill_initialize(const value_type & __value)223*404b540aSrobert     _M_fill_initialize(const value_type& __value)
224*404b540aSrobert     {
225*404b540aSrobert       _Map_pointer __cur;
226*404b540aSrobert       try
227*404b540aSrobert         {
228*404b540aSrobert           for (__cur = this->_M_impl._M_start._M_node;
229*404b540aSrobert 	       __cur < this->_M_impl._M_finish._M_node;
230*404b540aSrobert 	       ++__cur)
231*404b540aSrobert             std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
232*404b540aSrobert 					__value, _M_get_Tp_allocator());
233*404b540aSrobert           std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
234*404b540aSrobert 				      this->_M_impl._M_finish._M_cur,
235*404b540aSrobert 				      __value, _M_get_Tp_allocator());
236*404b540aSrobert         }
237*404b540aSrobert       catch(...)
238*404b540aSrobert         {
239*404b540aSrobert           std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
240*404b540aSrobert 			_M_get_Tp_allocator());
241*404b540aSrobert           __throw_exception_again;
242*404b540aSrobert         }
243*404b540aSrobert     }
244*404b540aSrobert 
245*404b540aSrobert   template <typename _Tp, typename _Alloc>
246*404b540aSrobert     template <typename _InputIterator>
247*404b540aSrobert       void
248*404b540aSrobert       deque<_Tp, _Alloc>::
_M_range_initialize(_InputIterator __first,_InputIterator __last,std::input_iterator_tag)249*404b540aSrobert       _M_range_initialize(_InputIterator __first, _InputIterator __last,
250*404b540aSrobert                           std::input_iterator_tag)
251*404b540aSrobert       {
252*404b540aSrobert         this->_M_initialize_map(0);
253*404b540aSrobert         try
254*404b540aSrobert           {
255*404b540aSrobert             for (; __first != __last; ++__first)
256*404b540aSrobert               push_back(*__first);
257*404b540aSrobert           }
258*404b540aSrobert         catch(...)
259*404b540aSrobert           {
260*404b540aSrobert             clear();
261*404b540aSrobert             __throw_exception_again;
262*404b540aSrobert           }
263*404b540aSrobert       }
264*404b540aSrobert 
265*404b540aSrobert   template <typename _Tp, typename _Alloc>
266*404b540aSrobert     template <typename _ForwardIterator>
267*404b540aSrobert       void
268*404b540aSrobert       deque<_Tp, _Alloc>::
_M_range_initialize(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)269*404b540aSrobert       _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
270*404b540aSrobert                           std::forward_iterator_tag)
271*404b540aSrobert       {
272*404b540aSrobert         const size_type __n = std::distance(__first, __last);
273*404b540aSrobert         this->_M_initialize_map(__n);
274*404b540aSrobert 
275*404b540aSrobert         _Map_pointer __cur_node;
276*404b540aSrobert         try
277*404b540aSrobert           {
278*404b540aSrobert             for (__cur_node = this->_M_impl._M_start._M_node;
279*404b540aSrobert                  __cur_node < this->_M_impl._M_finish._M_node;
280*404b540aSrobert                  ++__cur_node)
281*404b540aSrobert 	      {
282*404b540aSrobert 		_ForwardIterator __mid = __first;
283*404b540aSrobert 		std::advance(__mid, _S_buffer_size());
284*404b540aSrobert 		std::__uninitialized_copy_a(__first, __mid, *__cur_node,
285*404b540aSrobert 					    _M_get_Tp_allocator());
286*404b540aSrobert 		__first = __mid;
287*404b540aSrobert 	      }
288*404b540aSrobert             std::__uninitialized_copy_a(__first, __last,
289*404b540aSrobert 					this->_M_impl._M_finish._M_first,
290*404b540aSrobert 					_M_get_Tp_allocator());
291*404b540aSrobert           }
292*404b540aSrobert         catch(...)
293*404b540aSrobert           {
294*404b540aSrobert             std::_Destroy(this->_M_impl._M_start,
295*404b540aSrobert 			  iterator(*__cur_node, __cur_node),
296*404b540aSrobert 			  _M_get_Tp_allocator());
297*404b540aSrobert             __throw_exception_again;
298*404b540aSrobert           }
299*404b540aSrobert       }
300*404b540aSrobert 
301*404b540aSrobert   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
302*404b540aSrobert   template <typename _Tp, typename _Alloc>
303*404b540aSrobert     void
304*404b540aSrobert     deque<_Tp, _Alloc>::
_M_push_back_aux(const value_type & __t)305*404b540aSrobert     _M_push_back_aux(const value_type& __t)
306*404b540aSrobert     {
307*404b540aSrobert       value_type __t_copy = __t;
308*404b540aSrobert       _M_reserve_map_at_back();
309*404b540aSrobert       *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
310*404b540aSrobert       try
311*404b540aSrobert         {
312*404b540aSrobert           this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t_copy);
313*404b540aSrobert           this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
314*404b540aSrobert 					      + 1);
315*404b540aSrobert           this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
316*404b540aSrobert         }
317*404b540aSrobert       catch(...)
318*404b540aSrobert         {
319*404b540aSrobert           _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
320*404b540aSrobert           __throw_exception_again;
321*404b540aSrobert         }
322*404b540aSrobert     }
323*404b540aSrobert 
324*404b540aSrobert   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
325*404b540aSrobert   template <typename _Tp, typename _Alloc>
326*404b540aSrobert     void
327*404b540aSrobert     deque<_Tp, _Alloc>::
_M_push_front_aux(const value_type & __t)328*404b540aSrobert     _M_push_front_aux(const value_type& __t)
329*404b540aSrobert     {
330*404b540aSrobert       value_type __t_copy = __t;
331*404b540aSrobert       _M_reserve_map_at_front();
332*404b540aSrobert       *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
333*404b540aSrobert       try
334*404b540aSrobert         {
335*404b540aSrobert           this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
336*404b540aSrobert 					     - 1);
337*404b540aSrobert           this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
338*404b540aSrobert           this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t_copy);
339*404b540aSrobert         }
340*404b540aSrobert       catch(...)
341*404b540aSrobert         {
342*404b540aSrobert           ++this->_M_impl._M_start;
343*404b540aSrobert           _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
344*404b540aSrobert           __throw_exception_again;
345*404b540aSrobert         }
346*404b540aSrobert     }
347*404b540aSrobert 
348*404b540aSrobert   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
349*404b540aSrobert   template <typename _Tp, typename _Alloc>
350*404b540aSrobert     void deque<_Tp, _Alloc>::
_M_pop_back_aux()351*404b540aSrobert     _M_pop_back_aux()
352*404b540aSrobert     {
353*404b540aSrobert       _M_deallocate_node(this->_M_impl._M_finish._M_first);
354*404b540aSrobert       this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
355*404b540aSrobert       this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
356*404b540aSrobert       this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
357*404b540aSrobert     }
358*404b540aSrobert 
359*404b540aSrobert   // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
360*404b540aSrobert   // Note that if the deque has at least one element (a precondition for this
361*404b540aSrobert   // member function), and if
362*404b540aSrobert   //   _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
363*404b540aSrobert   // then the deque must have at least two nodes.
364*404b540aSrobert   template <typename _Tp, typename _Alloc>
365*404b540aSrobert     void deque<_Tp, _Alloc>::
_M_pop_front_aux()366*404b540aSrobert     _M_pop_front_aux()
367*404b540aSrobert     {
368*404b540aSrobert       this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
369*404b540aSrobert       _M_deallocate_node(this->_M_impl._M_start._M_first);
370*404b540aSrobert       this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
371*404b540aSrobert       this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
372*404b540aSrobert     }
373*404b540aSrobert 
374*404b540aSrobert   template <typename _Tp, typename _Alloc>
375*404b540aSrobert     template <typename _InputIterator>
376*404b540aSrobert       void
377*404b540aSrobert       deque<_Tp, _Alloc>::
_M_range_insert_aux(iterator __pos,_InputIterator __first,_InputIterator __last,std::input_iterator_tag)378*404b540aSrobert       _M_range_insert_aux(iterator __pos,
379*404b540aSrobert                           _InputIterator __first, _InputIterator __last,
380*404b540aSrobert                           std::input_iterator_tag)
381*404b540aSrobert       { std::copy(__first, __last, std::inserter(*this, __pos)); }
382*404b540aSrobert 
383*404b540aSrobert   template <typename _Tp, typename _Alloc>
384*404b540aSrobert     template <typename _ForwardIterator>
385*404b540aSrobert       void
386*404b540aSrobert       deque<_Tp, _Alloc>::
_M_range_insert_aux(iterator __pos,_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)387*404b540aSrobert       _M_range_insert_aux(iterator __pos,
388*404b540aSrobert                           _ForwardIterator __first, _ForwardIterator __last,
389*404b540aSrobert                           std::forward_iterator_tag)
390*404b540aSrobert       {
391*404b540aSrobert         const size_type __n = std::distance(__first, __last);
392*404b540aSrobert         if (__pos._M_cur == this->_M_impl._M_start._M_cur)
393*404b540aSrobert 	  {
394*404b540aSrobert 	    iterator __new_start = _M_reserve_elements_at_front(__n);
395*404b540aSrobert 	    try
396*404b540aSrobert 	      {
397*404b540aSrobert 		std::__uninitialized_copy_a(__first, __last, __new_start,
398*404b540aSrobert 					    _M_get_Tp_allocator());
399*404b540aSrobert 		this->_M_impl._M_start = __new_start;
400*404b540aSrobert 	      }
401*404b540aSrobert 	    catch(...)
402*404b540aSrobert 	      {
403*404b540aSrobert 		_M_destroy_nodes(__new_start._M_node,
404*404b540aSrobert 				 this->_M_impl._M_start._M_node);
405*404b540aSrobert 		__throw_exception_again;
406*404b540aSrobert 	      }
407*404b540aSrobert 	  }
408*404b540aSrobert         else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
409*404b540aSrobert 	  {
410*404b540aSrobert 	    iterator __new_finish = _M_reserve_elements_at_back(__n);
411*404b540aSrobert 	    try
412*404b540aSrobert 	      {
413*404b540aSrobert 		std::__uninitialized_copy_a(__first, __last,
414*404b540aSrobert 					    this->_M_impl._M_finish,
415*404b540aSrobert 					    _M_get_Tp_allocator());
416*404b540aSrobert 		this->_M_impl._M_finish = __new_finish;
417*404b540aSrobert 	      }
418*404b540aSrobert 	    catch(...)
419*404b540aSrobert 	      {
420*404b540aSrobert 		_M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
421*404b540aSrobert 				 __new_finish._M_node + 1);
422*404b540aSrobert 		__throw_exception_again;
423*404b540aSrobert 	      }
424*404b540aSrobert 	  }
425*404b540aSrobert         else
426*404b540aSrobert           _M_insert_aux(__pos, __first, __last, __n);
427*404b540aSrobert       }
428*404b540aSrobert 
429*404b540aSrobert   template <typename _Tp, typename _Alloc>
430*404b540aSrobert     typename deque<_Tp, _Alloc>::iterator
431*404b540aSrobert     deque<_Tp, _Alloc>::
_M_insert_aux(iterator __pos,const value_type & __x)432*404b540aSrobert     _M_insert_aux(iterator __pos, const value_type& __x)
433*404b540aSrobert     {
434*404b540aSrobert       difference_type __index = __pos - this->_M_impl._M_start;
435*404b540aSrobert       value_type __x_copy = __x; // XXX copy
436*404b540aSrobert       if (static_cast<size_type>(__index) < size() / 2)
437*404b540aSrobert 	{
438*404b540aSrobert 	  push_front(front());
439*404b540aSrobert 	  iterator __front1 = this->_M_impl._M_start;
440*404b540aSrobert 	  ++__front1;
441*404b540aSrobert 	  iterator __front2 = __front1;
442*404b540aSrobert 	  ++__front2;
443*404b540aSrobert 	  __pos = this->_M_impl._M_start + __index;
444*404b540aSrobert 	  iterator __pos1 = __pos;
445*404b540aSrobert 	  ++__pos1;
446*404b540aSrobert 	  std::copy(__front2, __pos1, __front1);
447*404b540aSrobert 	}
448*404b540aSrobert       else
449*404b540aSrobert 	{
450*404b540aSrobert 	  push_back(back());
451*404b540aSrobert 	  iterator __back1 = this->_M_impl._M_finish;
452*404b540aSrobert 	  --__back1;
453*404b540aSrobert 	  iterator __back2 = __back1;
454*404b540aSrobert 	  --__back2;
455*404b540aSrobert 	  __pos = this->_M_impl._M_start + __index;
456*404b540aSrobert 	  std::copy_backward(__pos, __back2, __back1);
457*404b540aSrobert 	}
458*404b540aSrobert       *__pos = __x_copy;
459*404b540aSrobert       return __pos;
460*404b540aSrobert     }
461*404b540aSrobert 
462*404b540aSrobert   template <typename _Tp, typename _Alloc>
463*404b540aSrobert     void
464*404b540aSrobert     deque<_Tp, _Alloc>::
_M_insert_aux(iterator __pos,size_type __n,const value_type & __x)465*404b540aSrobert     _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
466*404b540aSrobert     {
467*404b540aSrobert       const difference_type __elems_before = __pos - this->_M_impl._M_start;
468*404b540aSrobert       const size_type __length = this->size();
469*404b540aSrobert       value_type __x_copy = __x;
470*404b540aSrobert       if (__elems_before < difference_type(__length / 2))
471*404b540aSrobert 	{
472*404b540aSrobert 	  iterator __new_start = _M_reserve_elements_at_front(__n);
473*404b540aSrobert 	  iterator __old_start = this->_M_impl._M_start;
474*404b540aSrobert 	  __pos = this->_M_impl._M_start + __elems_before;
475*404b540aSrobert 	  try
476*404b540aSrobert 	    {
477*404b540aSrobert 	      if (__elems_before >= difference_type(__n))
478*404b540aSrobert 		{
479*404b540aSrobert 		  iterator __start_n = (this->_M_impl._M_start
480*404b540aSrobert 					+ difference_type(__n));
481*404b540aSrobert 		  std::__uninitialized_copy_a(this->_M_impl._M_start,
482*404b540aSrobert 					      __start_n, __new_start,
483*404b540aSrobert 					      _M_get_Tp_allocator());
484*404b540aSrobert 		  this->_M_impl._M_start = __new_start;
485*404b540aSrobert 		  std::copy(__start_n, __pos, __old_start);
486*404b540aSrobert 		  std::fill(__pos - difference_type(__n), __pos, __x_copy);
487*404b540aSrobert 		}
488*404b540aSrobert 	      else
489*404b540aSrobert 		{
490*404b540aSrobert 		  std::__uninitialized_copy_fill(this->_M_impl._M_start,
491*404b540aSrobert 						 __pos, __new_start,
492*404b540aSrobert 						 this->_M_impl._M_start,
493*404b540aSrobert 						 __x_copy,
494*404b540aSrobert 						 _M_get_Tp_allocator());
495*404b540aSrobert 		  this->_M_impl._M_start = __new_start;
496*404b540aSrobert 		  std::fill(__old_start, __pos, __x_copy);
497*404b540aSrobert 		}
498*404b540aSrobert 	    }
499*404b540aSrobert 	  catch(...)
500*404b540aSrobert 	    {
501*404b540aSrobert 	      _M_destroy_nodes(__new_start._M_node,
502*404b540aSrobert 			       this->_M_impl._M_start._M_node);
503*404b540aSrobert 	      __throw_exception_again;
504*404b540aSrobert 	    }
505*404b540aSrobert 	}
506*404b540aSrobert       else
507*404b540aSrobert 	{
508*404b540aSrobert 	  iterator __new_finish = _M_reserve_elements_at_back(__n);
509*404b540aSrobert 	  iterator __old_finish = this->_M_impl._M_finish;
510*404b540aSrobert 	  const difference_type __elems_after =
511*404b540aSrobert 	    difference_type(__length) - __elems_before;
512*404b540aSrobert 	  __pos = this->_M_impl._M_finish - __elems_after;
513*404b540aSrobert 	  try
514*404b540aSrobert 	    {
515*404b540aSrobert 	      if (__elems_after > difference_type(__n))
516*404b540aSrobert 		{
517*404b540aSrobert 		  iterator __finish_n = (this->_M_impl._M_finish
518*404b540aSrobert 					 - difference_type(__n));
519*404b540aSrobert 		  std::__uninitialized_copy_a(__finish_n,
520*404b540aSrobert 					      this->_M_impl._M_finish,
521*404b540aSrobert 					      this->_M_impl._M_finish,
522*404b540aSrobert 					      _M_get_Tp_allocator());
523*404b540aSrobert 		  this->_M_impl._M_finish = __new_finish;
524*404b540aSrobert 		  std::copy_backward(__pos, __finish_n, __old_finish);
525*404b540aSrobert 		  std::fill(__pos, __pos + difference_type(__n), __x_copy);
526*404b540aSrobert 		}
527*404b540aSrobert 	      else
528*404b540aSrobert 		{
529*404b540aSrobert 		  std::__uninitialized_fill_copy(this->_M_impl._M_finish,
530*404b540aSrobert 						 __pos + difference_type(__n),
531*404b540aSrobert 						 __x_copy, __pos,
532*404b540aSrobert 						 this->_M_impl._M_finish,
533*404b540aSrobert 						 _M_get_Tp_allocator());
534*404b540aSrobert 		  this->_M_impl._M_finish = __new_finish;
535*404b540aSrobert 		  std::fill(__pos, __old_finish, __x_copy);
536*404b540aSrobert 		}
537*404b540aSrobert 	    }
538*404b540aSrobert 	  catch(...)
539*404b540aSrobert 	    {
540*404b540aSrobert 	      _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
541*404b540aSrobert 			       __new_finish._M_node + 1);
542*404b540aSrobert 	      __throw_exception_again;
543*404b540aSrobert 	    }
544*404b540aSrobert 	}
545*404b540aSrobert     }
546*404b540aSrobert 
547*404b540aSrobert   template <typename _Tp, typename _Alloc>
548*404b540aSrobert     template <typename _ForwardIterator>
549*404b540aSrobert       void
550*404b540aSrobert       deque<_Tp, _Alloc>::
_M_insert_aux(iterator __pos,_ForwardIterator __first,_ForwardIterator __last,size_type __n)551*404b540aSrobert       _M_insert_aux(iterator __pos,
552*404b540aSrobert                     _ForwardIterator __first, _ForwardIterator __last,
553*404b540aSrobert                     size_type __n)
554*404b540aSrobert       {
555*404b540aSrobert         const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
556*404b540aSrobert         const size_type __length = size();
557*404b540aSrobert         if (static_cast<size_type>(__elemsbefore) < __length / 2)
558*404b540aSrobert 	  {
559*404b540aSrobert 	    iterator __new_start = _M_reserve_elements_at_front(__n);
560*404b540aSrobert 	    iterator __old_start = this->_M_impl._M_start;
561*404b540aSrobert 	    __pos = this->_M_impl._M_start + __elemsbefore;
562*404b540aSrobert 	    try
563*404b540aSrobert 	      {
564*404b540aSrobert 		if (__elemsbefore >= difference_type(__n))
565*404b540aSrobert 		  {
566*404b540aSrobert 		    iterator __start_n = (this->_M_impl._M_start
567*404b540aSrobert 					  + difference_type(__n));
568*404b540aSrobert 		    std::__uninitialized_copy_a(this->_M_impl._M_start,
569*404b540aSrobert 						__start_n, __new_start,
570*404b540aSrobert 						_M_get_Tp_allocator());
571*404b540aSrobert 		    this->_M_impl._M_start = __new_start;
572*404b540aSrobert 		    std::copy(__start_n, __pos, __old_start);
573*404b540aSrobert 		    std::copy(__first, __last, __pos - difference_type(__n));
574*404b540aSrobert 		  }
575*404b540aSrobert 		else
576*404b540aSrobert 		  {
577*404b540aSrobert 		    _ForwardIterator __mid = __first;
578*404b540aSrobert 		    std::advance(__mid, difference_type(__n) - __elemsbefore);
579*404b540aSrobert 		    std::__uninitialized_copy_copy(this->_M_impl._M_start,
580*404b540aSrobert 						   __pos, __first, __mid,
581*404b540aSrobert 						   __new_start,
582*404b540aSrobert 						   _M_get_Tp_allocator());
583*404b540aSrobert 		    this->_M_impl._M_start = __new_start;
584*404b540aSrobert 		    std::copy(__mid, __last, __old_start);
585*404b540aSrobert 		  }
586*404b540aSrobert 	      }
587*404b540aSrobert 	    catch(...)
588*404b540aSrobert 	      {
589*404b540aSrobert 		_M_destroy_nodes(__new_start._M_node,
590*404b540aSrobert 				 this->_M_impl._M_start._M_node);
591*404b540aSrobert 		__throw_exception_again;
592*404b540aSrobert 	      }
593*404b540aSrobert 	  }
594*404b540aSrobert         else
595*404b540aSrobert         {
596*404b540aSrobert           iterator __new_finish = _M_reserve_elements_at_back(__n);
597*404b540aSrobert           iterator __old_finish = this->_M_impl._M_finish;
598*404b540aSrobert           const difference_type __elemsafter =
599*404b540aSrobert             difference_type(__length) - __elemsbefore;
600*404b540aSrobert           __pos = this->_M_impl._M_finish - __elemsafter;
601*404b540aSrobert           try
602*404b540aSrobert             {
603*404b540aSrobert               if (__elemsafter > difference_type(__n))
604*404b540aSrobert 		{
605*404b540aSrobert 		  iterator __finish_n = (this->_M_impl._M_finish
606*404b540aSrobert 					 - difference_type(__n));
607*404b540aSrobert 		  std::__uninitialized_copy_a(__finish_n,
608*404b540aSrobert 					      this->_M_impl._M_finish,
609*404b540aSrobert 					      this->_M_impl._M_finish,
610*404b540aSrobert 					      _M_get_Tp_allocator());
611*404b540aSrobert 		  this->_M_impl._M_finish = __new_finish;
612*404b540aSrobert 		  std::copy_backward(__pos, __finish_n, __old_finish);
613*404b540aSrobert 		  std::copy(__first, __last, __pos);
614*404b540aSrobert 		}
615*404b540aSrobert               else
616*404b540aSrobert 		{
617*404b540aSrobert 		  _ForwardIterator __mid = __first;
618*404b540aSrobert 		  std::advance(__mid, __elemsafter);
619*404b540aSrobert 		  std::__uninitialized_copy_copy(__mid, __last, __pos,
620*404b540aSrobert 						 this->_M_impl._M_finish,
621*404b540aSrobert 						 this->_M_impl._M_finish,
622*404b540aSrobert 						 _M_get_Tp_allocator());
623*404b540aSrobert 		  this->_M_impl._M_finish = __new_finish;
624*404b540aSrobert 		  std::copy(__first, __mid, __pos);
625*404b540aSrobert 		}
626*404b540aSrobert             }
627*404b540aSrobert           catch(...)
628*404b540aSrobert             {
629*404b540aSrobert               _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
630*404b540aSrobert 			       __new_finish._M_node + 1);
631*404b540aSrobert               __throw_exception_again;
632*404b540aSrobert             }
633*404b540aSrobert         }
634*404b540aSrobert       }
635*404b540aSrobert 
636*404b540aSrobert    template<typename _Tp, typename _Alloc>
637*404b540aSrobert      void
638*404b540aSrobert      deque<_Tp, _Alloc>::
_M_destroy_data_aux(iterator __first,iterator __last)639*404b540aSrobert      _M_destroy_data_aux(iterator __first, iterator __last)
640*404b540aSrobert      {
641*404b540aSrobert        for (_Map_pointer __node = __first._M_node + 1;
642*404b540aSrobert 	    __node < __last._M_node; ++__node)
643*404b540aSrobert 	 std::_Destroy(*__node, *__node + _S_buffer_size(),
644*404b540aSrobert 		       _M_get_Tp_allocator());
645*404b540aSrobert 
646*404b540aSrobert        if (__first._M_node != __last._M_node)
647*404b540aSrobert 	 {
648*404b540aSrobert 	   std::_Destroy(__first._M_cur, __first._M_last,
649*404b540aSrobert 			 _M_get_Tp_allocator());
650*404b540aSrobert 	   std::_Destroy(__last._M_first, __last._M_cur,
651*404b540aSrobert 			 _M_get_Tp_allocator());
652*404b540aSrobert 	 }
653*404b540aSrobert        else
654*404b540aSrobert 	 std::_Destroy(__first._M_cur, __last._M_cur,
655*404b540aSrobert 		       _M_get_Tp_allocator());
656*404b540aSrobert      }
657*404b540aSrobert 
658*404b540aSrobert   template <typename _Tp, typename _Alloc>
659*404b540aSrobert     void
660*404b540aSrobert     deque<_Tp, _Alloc>::
_M_new_elements_at_front(size_type __new_elems)661*404b540aSrobert     _M_new_elements_at_front(size_type __new_elems)
662*404b540aSrobert     {
663*404b540aSrobert       if (this->max_size() - this->size() < __new_elems)
664*404b540aSrobert 	__throw_length_error(__N("deque::_M_new_elements_at_front"));
665*404b540aSrobert 
666*404b540aSrobert       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
667*404b540aSrobert 				     / _S_buffer_size());
668*404b540aSrobert       _M_reserve_map_at_front(__new_nodes);
669*404b540aSrobert       size_type __i;
670*404b540aSrobert       try
671*404b540aSrobert         {
672*404b540aSrobert           for (__i = 1; __i <= __new_nodes; ++__i)
673*404b540aSrobert             *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
674*404b540aSrobert         }
675*404b540aSrobert       catch(...)
676*404b540aSrobert         {
677*404b540aSrobert           for (size_type __j = 1; __j < __i; ++__j)
678*404b540aSrobert             _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
679*404b540aSrobert           __throw_exception_again;
680*404b540aSrobert         }
681*404b540aSrobert     }
682*404b540aSrobert 
683*404b540aSrobert   template <typename _Tp, typename _Alloc>
684*404b540aSrobert     void
685*404b540aSrobert     deque<_Tp, _Alloc>::
_M_new_elements_at_back(size_type __new_elems)686*404b540aSrobert     _M_new_elements_at_back(size_type __new_elems)
687*404b540aSrobert     {
688*404b540aSrobert       if (this->max_size() - this->size() < __new_elems)
689*404b540aSrobert 	__throw_length_error(__N("deque::_M_new_elements_at_back"));
690*404b540aSrobert 
691*404b540aSrobert       const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
692*404b540aSrobert 				     / _S_buffer_size());
693*404b540aSrobert       _M_reserve_map_at_back(__new_nodes);
694*404b540aSrobert       size_type __i;
695*404b540aSrobert       try
696*404b540aSrobert         {
697*404b540aSrobert           for (__i = 1; __i <= __new_nodes; ++__i)
698*404b540aSrobert             *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
699*404b540aSrobert         }
700*404b540aSrobert       catch(...)
701*404b540aSrobert         {
702*404b540aSrobert           for (size_type __j = 1; __j < __i; ++__j)
703*404b540aSrobert             _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
704*404b540aSrobert           __throw_exception_again;
705*404b540aSrobert         }
706*404b540aSrobert     }
707*404b540aSrobert 
708*404b540aSrobert   template <typename _Tp, typename _Alloc>
709*404b540aSrobert     void
710*404b540aSrobert     deque<_Tp, _Alloc>::
_M_reallocate_map(size_type __nodes_to_add,bool __add_at_front)711*404b540aSrobert     _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
712*404b540aSrobert     {
713*404b540aSrobert       const size_type __old_num_nodes
714*404b540aSrobert 	= this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
715*404b540aSrobert       const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
716*404b540aSrobert 
717*404b540aSrobert       _Map_pointer __new_nstart;
718*404b540aSrobert       if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
719*404b540aSrobert 	{
720*404b540aSrobert 	  __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
721*404b540aSrobert 					 - __new_num_nodes) / 2
722*404b540aSrobert 	                 + (__add_at_front ? __nodes_to_add : 0);
723*404b540aSrobert 	  if (__new_nstart < this->_M_impl._M_start._M_node)
724*404b540aSrobert 	    std::copy(this->_M_impl._M_start._M_node,
725*404b540aSrobert 		      this->_M_impl._M_finish._M_node + 1,
726*404b540aSrobert 		      __new_nstart);
727*404b540aSrobert 	  else
728*404b540aSrobert 	    std::copy_backward(this->_M_impl._M_start._M_node,
729*404b540aSrobert 			       this->_M_impl._M_finish._M_node + 1,
730*404b540aSrobert 			       __new_nstart + __old_num_nodes);
731*404b540aSrobert 	}
732*404b540aSrobert       else
733*404b540aSrobert 	{
734*404b540aSrobert 	  size_type __new_map_size = this->_M_impl._M_map_size
735*404b540aSrobert 	                             + std::max(this->_M_impl._M_map_size,
736*404b540aSrobert 						__nodes_to_add) + 2;
737*404b540aSrobert 
738*404b540aSrobert 	  _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
739*404b540aSrobert 	  __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
740*404b540aSrobert 	                 + (__add_at_front ? __nodes_to_add : 0);
741*404b540aSrobert 	  std::copy(this->_M_impl._M_start._M_node,
742*404b540aSrobert 		    this->_M_impl._M_finish._M_node + 1,
743*404b540aSrobert 		    __new_nstart);
744*404b540aSrobert 	  _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
745*404b540aSrobert 
746*404b540aSrobert 	  this->_M_impl._M_map = __new_map;
747*404b540aSrobert 	  this->_M_impl._M_map_size = __new_map_size;
748*404b540aSrobert 	}
749*404b540aSrobert 
750*404b540aSrobert       this->_M_impl._M_start._M_set_node(__new_nstart);
751*404b540aSrobert       this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
752*404b540aSrobert     }
753*404b540aSrobert 
754*404b540aSrobert   // Overload for deque::iterators, exploiting the "segmented-iterator
755*404b540aSrobert   // optimization".  NB: leave const_iterators alone!
756*404b540aSrobert   template<typename _Tp>
757*404b540aSrobert     void
fill(const _Deque_iterator<_Tp,_Tp &,_Tp * > & __first,const _Deque_iterator<_Tp,_Tp &,_Tp * > & __last,const _Tp & __value)758*404b540aSrobert     fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
759*404b540aSrobert 	 const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
760*404b540aSrobert     {
761*404b540aSrobert       typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
762*404b540aSrobert 
763*404b540aSrobert       for (typename _Self::_Map_pointer __node = __first._M_node + 1;
764*404b540aSrobert            __node < __last._M_node; ++__node)
765*404b540aSrobert 	std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
766*404b540aSrobert 
767*404b540aSrobert       if (__first._M_node != __last._M_node)
768*404b540aSrobert 	{
769*404b540aSrobert 	  std::fill(__first._M_cur, __first._M_last, __value);
770*404b540aSrobert 	  std::fill(__last._M_first, __last._M_cur, __value);
771*404b540aSrobert 	}
772*404b540aSrobert       else
773*404b540aSrobert 	std::fill(__first._M_cur, __last._M_cur, __value);
774*404b540aSrobert     }
775*404b540aSrobert 
776*404b540aSrobert _GLIBCXX_END_NESTED_NAMESPACE
777*404b540aSrobert 
778*404b540aSrobert #endif
779