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