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