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