1 // Deque implementation (out of line) -*- C++ -*-
3 // Copyright (C) 2001-2014 Free Software Foundation, Inc.
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)
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.
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.
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/>.
28 * Hewlett-Packard Company
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.
40 * Silicon Graphics Computer Systems, Inc.
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.
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}
59 namespace std _GLIBCXX_VISIBILITY(default)
61 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
63 #if __cplusplus >= 201103L
64 template <typename _Tp, typename _Alloc>
67 _M_default_initialize()
72 for (__cur = this->_M_impl._M_start._M_node;
73 __cur < this->_M_impl._M_finish._M_node;
75 std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
76 _M_get_Tp_allocator());
77 std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
78 this->_M_impl._M_finish._M_cur,
79 _M_get_Tp_allocator());
83 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
84 _M_get_Tp_allocator());
85 __throw_exception_again;
90 template <typename _Tp, typename _Alloc>
93 operator=(const deque& __x)
95 const size_type __len = size();
98 if (__len >= __x.size())
99 _M_erase_at_end(std::copy(__x.begin(), __x.end(),
100 this->_M_impl._M_start));
103 const_iterator __mid = __x.begin() + difference_type(__len);
104 std::copy(__x.begin(), __mid, this->_M_impl._M_start);
105 insert(this->_M_impl._M_finish, __mid, __x.end());
111 #if __cplusplus >= 201103L
112 template<typename _Tp, typename _Alloc>
113 template<typename... _Args>
116 emplace_front(_Args&&... __args)
118 if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
120 this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1,
121 std::forward<_Args>(__args)...);
122 --this->_M_impl._M_start._M_cur;
125 _M_push_front_aux(std::forward<_Args>(__args)...);
128 template<typename _Tp, typename _Alloc>
129 template<typename... _Args>
132 emplace_back(_Args&&... __args)
134 if (this->_M_impl._M_finish._M_cur
135 != this->_M_impl._M_finish._M_last - 1)
137 this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
138 std::forward<_Args>(__args)...);
139 ++this->_M_impl._M_finish._M_cur;
142 _M_push_back_aux(std::forward<_Args>(__args)...);
146 #if __cplusplus >= 201103L
147 template<typename _Tp, typename _Alloc>
148 template<typename... _Args>
149 typename deque<_Tp, _Alloc>::iterator
151 emplace(const_iterator __position, _Args&&... __args)
153 if (__position._M_cur == this->_M_impl._M_start._M_cur)
155 emplace_front(std::forward<_Args>(__args)...);
156 return this->_M_impl._M_start;
158 else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
160 emplace_back(std::forward<_Args>(__args)...);
161 iterator __tmp = this->_M_impl._M_finish;
166 return _M_insert_aux(__position._M_const_cast(),
167 std::forward<_Args>(__args)...);
171 template <typename _Tp, typename _Alloc>
172 typename deque<_Tp, _Alloc>::iterator
174 #if __cplusplus >= 201103L
175 insert(const_iterator __position, const value_type& __x)
177 insert(iterator __position, const value_type& __x)
180 if (__position._M_cur == this->_M_impl._M_start._M_cur)
183 return this->_M_impl._M_start;
185 else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
188 iterator __tmp = this->_M_impl._M_finish;
193 return _M_insert_aux(__position._M_const_cast(), __x);
196 template <typename _Tp, typename _Alloc>
197 typename deque<_Tp, _Alloc>::iterator
199 _M_erase(iterator __position)
201 iterator __next = __position;
203 const difference_type __index = __position - begin();
204 if (static_cast<size_type>(__index) < (size() >> 1))
206 if (__position != begin())
207 _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
213 _GLIBCXX_MOVE3(__next, end(), __position);
216 return begin() + __index;
219 template <typename _Tp, typename _Alloc>
220 typename deque<_Tp, _Alloc>::iterator
222 _M_erase(iterator __first, iterator __last)
224 if (__first == __last)
226 else if (__first == begin() && __last == end())
233 const difference_type __n = __last - __first;
234 const difference_type __elems_before = __first - begin();
235 if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
237 if (__first != begin())
238 _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
239 _M_erase_at_begin(begin() + __n);
244 _GLIBCXX_MOVE3(__last, end(), __first);
245 _M_erase_at_end(end() - __n);
247 return begin() + __elems_before;
251 template <typename _Tp, class _Alloc>
252 template <typename _InputIterator>
255 _M_assign_aux(_InputIterator __first, _InputIterator __last,
256 std::input_iterator_tag)
258 iterator __cur = begin();
259 for (; __first != __last && __cur != end(); ++__cur, ++__first)
261 if (__first == __last)
262 _M_erase_at_end(__cur);
264 insert(end(), __first, __last);
267 template <typename _Tp, typename _Alloc>
270 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
272 if (__pos._M_cur == this->_M_impl._M_start._M_cur)
274 iterator __new_start = _M_reserve_elements_at_front(__n);
277 std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
278 __x, _M_get_Tp_allocator());
279 this->_M_impl._M_start = __new_start;
283 _M_destroy_nodes(__new_start._M_node,
284 this->_M_impl._M_start._M_node);
285 __throw_exception_again;
288 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
290 iterator __new_finish = _M_reserve_elements_at_back(__n);
293 std::__uninitialized_fill_a(this->_M_impl._M_finish,
295 _M_get_Tp_allocator());
296 this->_M_impl._M_finish = __new_finish;
300 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
301 __new_finish._M_node + 1);
302 __throw_exception_again;
306 _M_insert_aux(__pos, __n, __x);
309 #if __cplusplus >= 201103L
310 template <typename _Tp, typename _Alloc>
313 _M_default_append(size_type __n)
317 iterator __new_finish = _M_reserve_elements_at_back(__n);
320 std::__uninitialized_default_a(this->_M_impl._M_finish,
322 _M_get_Tp_allocator());
323 this->_M_impl._M_finish = __new_finish;
327 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
328 __new_finish._M_node + 1);
329 __throw_exception_again;
334 template <typename _Tp, typename _Alloc>
339 const difference_type __front_capacity
340 = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first);
341 if (__front_capacity == 0)
344 const difference_type __back_capacity
345 = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur);
346 if (__front_capacity + __back_capacity < _S_buffer_size())
349 return std::__shrink_to_fit_aux<deque>::_S_do_it(*this);
353 template <typename _Tp, typename _Alloc>
356 _M_fill_initialize(const value_type& __value)
361 for (__cur = this->_M_impl._M_start._M_node;
362 __cur < this->_M_impl._M_finish._M_node;
364 std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
365 __value, _M_get_Tp_allocator());
366 std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
367 this->_M_impl._M_finish._M_cur,
368 __value, _M_get_Tp_allocator());
372 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
373 _M_get_Tp_allocator());
374 __throw_exception_again;
378 template <typename _Tp, typename _Alloc>
379 template <typename _InputIterator>
382 _M_range_initialize(_InputIterator __first, _InputIterator __last,
383 std::input_iterator_tag)
385 this->_M_initialize_map(0);
388 for (; __first != __last; ++__first)
389 #if __cplusplus >= 201103L
390 emplace_back(*__first);
398 __throw_exception_again;
402 template <typename _Tp, typename _Alloc>
403 template <typename _ForwardIterator>
406 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
407 std::forward_iterator_tag)
409 const size_type __n = std::distance(__first, __last);
410 this->_M_initialize_map(__n);
412 _Map_pointer __cur_node;
415 for (__cur_node = this->_M_impl._M_start._M_node;
416 __cur_node < this->_M_impl._M_finish._M_node;
419 _ForwardIterator __mid = __first;
420 std::advance(__mid, _S_buffer_size());
421 std::__uninitialized_copy_a(__first, __mid, *__cur_node,
422 _M_get_Tp_allocator());
425 std::__uninitialized_copy_a(__first, __last,
426 this->_M_impl._M_finish._M_first,
427 _M_get_Tp_allocator());
431 std::_Destroy(this->_M_impl._M_start,
432 iterator(*__cur_node, __cur_node),
433 _M_get_Tp_allocator());
434 __throw_exception_again;
438 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
439 template<typename _Tp, typename _Alloc>
440 #if __cplusplus >= 201103L
441 template<typename... _Args>
444 _M_push_back_aux(_Args&&... __args)
448 _M_push_back_aux(const value_type& __t)
451 _M_reserve_map_at_back();
452 *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
455 #if __cplusplus >= 201103L
456 this->_M_impl.construct(this->_M_impl._M_finish._M_cur,
457 std::forward<_Args>(__args)...);
459 this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
461 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
463 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
467 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
468 __throw_exception_again;
472 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
473 template<typename _Tp, typename _Alloc>
474 #if __cplusplus >= 201103L
475 template<typename... _Args>
478 _M_push_front_aux(_Args&&... __args)
482 _M_push_front_aux(const value_type& __t)
485 _M_reserve_map_at_front();
486 *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
489 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
491 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
492 #if __cplusplus >= 201103L
493 this->_M_impl.construct(this->_M_impl._M_start._M_cur,
494 std::forward<_Args>(__args)...);
496 this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
501 ++this->_M_impl._M_start;
502 _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
503 __throw_exception_again;
507 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
508 template <typename _Tp, typename _Alloc>
509 void deque<_Tp, _Alloc>::
512 _M_deallocate_node(this->_M_impl._M_finish._M_first);
513 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
514 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
515 this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
518 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
519 // Note that if the deque has at least one element (a precondition for this
520 // member function), and if
521 // _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
522 // then the deque must have at least two nodes.
523 template <typename _Tp, typename _Alloc>
524 void deque<_Tp, _Alloc>::
527 this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
528 _M_deallocate_node(this->_M_impl._M_start._M_first);
529 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
530 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
533 template <typename _Tp, typename _Alloc>
534 template <typename _InputIterator>
537 _M_range_insert_aux(iterator __pos,
538 _InputIterator __first, _InputIterator __last,
539 std::input_iterator_tag)
540 { std::copy(__first, __last, std::inserter(*this, __pos)); }
542 template <typename _Tp, typename _Alloc>
543 template <typename _ForwardIterator>
546 _M_range_insert_aux(iterator __pos,
547 _ForwardIterator __first, _ForwardIterator __last,
548 std::forward_iterator_tag)
550 const size_type __n = std::distance(__first, __last);
551 if (__pos._M_cur == this->_M_impl._M_start._M_cur)
553 iterator __new_start = _M_reserve_elements_at_front(__n);
556 std::__uninitialized_copy_a(__first, __last, __new_start,
557 _M_get_Tp_allocator());
558 this->_M_impl._M_start = __new_start;
562 _M_destroy_nodes(__new_start._M_node,
563 this->_M_impl._M_start._M_node);
564 __throw_exception_again;
567 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
569 iterator __new_finish = _M_reserve_elements_at_back(__n);
572 std::__uninitialized_copy_a(__first, __last,
573 this->_M_impl._M_finish,
574 _M_get_Tp_allocator());
575 this->_M_impl._M_finish = __new_finish;
579 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
580 __new_finish._M_node + 1);
581 __throw_exception_again;
585 _M_insert_aux(__pos, __first, __last, __n);
588 template<typename _Tp, typename _Alloc>
589 #if __cplusplus >= 201103L
590 template<typename... _Args>
591 typename deque<_Tp, _Alloc>::iterator
593 _M_insert_aux(iterator __pos, _Args&&... __args)
595 value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy
597 typename deque<_Tp, _Alloc>::iterator
599 _M_insert_aux(iterator __pos, const value_type& __x)
601 value_type __x_copy = __x; // XXX copy
603 difference_type __index = __pos - this->_M_impl._M_start;
604 if (static_cast<size_type>(__index) < size() / 2)
606 push_front(_GLIBCXX_MOVE(front()));
607 iterator __front1 = this->_M_impl._M_start;
609 iterator __front2 = __front1;
611 __pos = this->_M_impl._M_start + __index;
612 iterator __pos1 = __pos;
614 _GLIBCXX_MOVE3(__front2, __pos1, __front1);
618 push_back(_GLIBCXX_MOVE(back()));
619 iterator __back1 = this->_M_impl._M_finish;
621 iterator __back2 = __back1;
623 __pos = this->_M_impl._M_start + __index;
624 _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
626 *__pos = _GLIBCXX_MOVE(__x_copy);
630 template <typename _Tp, typename _Alloc>
633 _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
635 const difference_type __elems_before = __pos - this->_M_impl._M_start;
636 const size_type __length = this->size();
637 value_type __x_copy = __x;
638 if (__elems_before < difference_type(__length / 2))
640 iterator __new_start = _M_reserve_elements_at_front(__n);
641 iterator __old_start = this->_M_impl._M_start;
642 __pos = this->_M_impl._M_start + __elems_before;
645 if (__elems_before >= difference_type(__n))
647 iterator __start_n = (this->_M_impl._M_start
648 + difference_type(__n));
649 std::__uninitialized_move_a(this->_M_impl._M_start,
650 __start_n, __new_start,
651 _M_get_Tp_allocator());
652 this->_M_impl._M_start = __new_start;
653 _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
654 std::fill(__pos - difference_type(__n), __pos, __x_copy);
658 std::__uninitialized_move_fill(this->_M_impl._M_start,
660 this->_M_impl._M_start,
662 _M_get_Tp_allocator());
663 this->_M_impl._M_start = __new_start;
664 std::fill(__old_start, __pos, __x_copy);
669 _M_destroy_nodes(__new_start._M_node,
670 this->_M_impl._M_start._M_node);
671 __throw_exception_again;
676 iterator __new_finish = _M_reserve_elements_at_back(__n);
677 iterator __old_finish = this->_M_impl._M_finish;
678 const difference_type __elems_after =
679 difference_type(__length) - __elems_before;
680 __pos = this->_M_impl._M_finish - __elems_after;
683 if (__elems_after > difference_type(__n))
685 iterator __finish_n = (this->_M_impl._M_finish
686 - difference_type(__n));
687 std::__uninitialized_move_a(__finish_n,
688 this->_M_impl._M_finish,
689 this->_M_impl._M_finish,
690 _M_get_Tp_allocator());
691 this->_M_impl._M_finish = __new_finish;
692 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
693 std::fill(__pos, __pos + difference_type(__n), __x_copy);
697 std::__uninitialized_fill_move(this->_M_impl._M_finish,
698 __pos + difference_type(__n),
700 this->_M_impl._M_finish,
701 _M_get_Tp_allocator());
702 this->_M_impl._M_finish = __new_finish;
703 std::fill(__pos, __old_finish, __x_copy);
708 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
709 __new_finish._M_node + 1);
710 __throw_exception_again;
715 template <typename _Tp, typename _Alloc>
716 template <typename _ForwardIterator>
719 _M_insert_aux(iterator __pos,
720 _ForwardIterator __first, _ForwardIterator __last,
723 const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
724 const size_type __length = size();
725 if (static_cast<size_type>(__elemsbefore) < __length / 2)
727 iterator __new_start = _M_reserve_elements_at_front(__n);
728 iterator __old_start = this->_M_impl._M_start;
729 __pos = this->_M_impl._M_start + __elemsbefore;
732 if (__elemsbefore >= difference_type(__n))
734 iterator __start_n = (this->_M_impl._M_start
735 + difference_type(__n));
736 std::__uninitialized_move_a(this->_M_impl._M_start,
737 __start_n, __new_start,
738 _M_get_Tp_allocator());
739 this->_M_impl._M_start = __new_start;
740 _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
741 std::copy(__first, __last, __pos - difference_type(__n));
745 _ForwardIterator __mid = __first;
746 std::advance(__mid, difference_type(__n) - __elemsbefore);
747 std::__uninitialized_move_copy(this->_M_impl._M_start,
748 __pos, __first, __mid,
750 _M_get_Tp_allocator());
751 this->_M_impl._M_start = __new_start;
752 std::copy(__mid, __last, __old_start);
757 _M_destroy_nodes(__new_start._M_node,
758 this->_M_impl._M_start._M_node);
759 __throw_exception_again;
764 iterator __new_finish = _M_reserve_elements_at_back(__n);
765 iterator __old_finish = this->_M_impl._M_finish;
766 const difference_type __elemsafter =
767 difference_type(__length) - __elemsbefore;
768 __pos = this->_M_impl._M_finish - __elemsafter;
771 if (__elemsafter > difference_type(__n))
773 iterator __finish_n = (this->_M_impl._M_finish
774 - difference_type(__n));
775 std::__uninitialized_move_a(__finish_n,
776 this->_M_impl._M_finish,
777 this->_M_impl._M_finish,
778 _M_get_Tp_allocator());
779 this->_M_impl._M_finish = __new_finish;
780 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
781 std::copy(__first, __last, __pos);
785 _ForwardIterator __mid = __first;
786 std::advance(__mid, __elemsafter);
787 std::__uninitialized_copy_move(__mid, __last, __pos,
788 this->_M_impl._M_finish,
789 this->_M_impl._M_finish,
790 _M_get_Tp_allocator());
791 this->_M_impl._M_finish = __new_finish;
792 std::copy(__first, __mid, __pos);
797 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
798 __new_finish._M_node + 1);
799 __throw_exception_again;
804 template<typename _Tp, typename _Alloc>
807 _M_destroy_data_aux(iterator __first, iterator __last)
809 for (_Map_pointer __node = __first._M_node + 1;
810 __node < __last._M_node; ++__node)
811 std::_Destroy(*__node, *__node + _S_buffer_size(),
812 _M_get_Tp_allocator());
814 if (__first._M_node != __last._M_node)
816 std::_Destroy(__first._M_cur, __first._M_last,
817 _M_get_Tp_allocator());
818 std::_Destroy(__last._M_first, __last._M_cur,
819 _M_get_Tp_allocator());
822 std::_Destroy(__first._M_cur, __last._M_cur,
823 _M_get_Tp_allocator());
826 template <typename _Tp, typename _Alloc>
829 _M_new_elements_at_front(size_type __new_elems)
831 if (this->max_size() - this->size() < __new_elems)
832 __throw_length_error(__N("deque::_M_new_elements_at_front"));
834 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
836 _M_reserve_map_at_front(__new_nodes);
840 for (__i = 1; __i <= __new_nodes; ++__i)
841 *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
845 for (size_type __j = 1; __j < __i; ++__j)
846 _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
847 __throw_exception_again;
851 template <typename _Tp, typename _Alloc>
854 _M_new_elements_at_back(size_type __new_elems)
856 if (this->max_size() - this->size() < __new_elems)
857 __throw_length_error(__N("deque::_M_new_elements_at_back"));
859 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
861 _M_reserve_map_at_back(__new_nodes);
865 for (__i = 1; __i <= __new_nodes; ++__i)
866 *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
870 for (size_type __j = 1; __j < __i; ++__j)
871 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
872 __throw_exception_again;
876 template <typename _Tp, typename _Alloc>
879 _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
881 const size_type __old_num_nodes
882 = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
883 const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
885 _Map_pointer __new_nstart;
886 if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
888 __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
889 - __new_num_nodes) / 2
890 + (__add_at_front ? __nodes_to_add : 0);
891 if (__new_nstart < this->_M_impl._M_start._M_node)
892 std::copy(this->_M_impl._M_start._M_node,
893 this->_M_impl._M_finish._M_node + 1,
896 std::copy_backward(this->_M_impl._M_start._M_node,
897 this->_M_impl._M_finish._M_node + 1,
898 __new_nstart + __old_num_nodes);
902 size_type __new_map_size = this->_M_impl._M_map_size
903 + std::max(this->_M_impl._M_map_size,
906 _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
907 __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
908 + (__add_at_front ? __nodes_to_add : 0);
909 std::copy(this->_M_impl._M_start._M_node,
910 this->_M_impl._M_finish._M_node + 1,
912 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
914 this->_M_impl._M_map = __new_map;
915 this->_M_impl._M_map_size = __new_map_size;
918 this->_M_impl._M_start._M_set_node(__new_nstart);
919 this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
922 // Overload for deque::iterators, exploiting the "segmented-iterator
924 template<typename _Tp>
926 fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
927 const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value)
929 typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
931 for (typename _Self::_Map_pointer __node = __first._M_node + 1;
932 __node < __last._M_node; ++__node)
933 std::fill(*__node, *__node + _Self::_S_buffer_size(), __value);
935 if (__first._M_node != __last._M_node)
937 std::fill(__first._M_cur, __first._M_last, __value);
938 std::fill(__last._M_first, __last._M_cur, __value);
941 std::fill(__first._M_cur, __last._M_cur, __value);
944 template<typename _Tp>
945 _Deque_iterator<_Tp, _Tp&, _Tp*>
946 copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
947 _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
948 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
950 typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
951 typedef typename _Self::difference_type difference_type;
953 difference_type __len = __last - __first;
956 const difference_type __clen
957 = std::min(__len, std::min(__first._M_last - __first._M_cur,
958 __result._M_last - __result._M_cur));
959 std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur);
967 template<typename _Tp>
968 _Deque_iterator<_Tp, _Tp&, _Tp*>
969 copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
970 _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
971 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
973 typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
974 typedef typename _Self::difference_type difference_type;
976 difference_type __len = __last - __first;
979 difference_type __llen = __last._M_cur - __last._M_first;
980 _Tp* __lend = __last._M_cur;
982 difference_type __rlen = __result._M_cur - __result._M_first;
983 _Tp* __rend = __result._M_cur;
987 __llen = _Self::_S_buffer_size();
988 __lend = *(__last._M_node - 1) + __llen;
992 __rlen = _Self::_S_buffer_size();
993 __rend = *(__result._M_node - 1) + __rlen;
996 const difference_type __clen = std::min(__len,
997 std::min(__llen, __rlen));
998 std::copy_backward(__lend - __clen, __lend, __rend);
1006 #if __cplusplus >= 201103L
1007 template<typename _Tp>
1008 _Deque_iterator<_Tp, _Tp&, _Tp*>
1009 move(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
1010 _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
1011 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1013 typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
1014 typedef typename _Self::difference_type difference_type;
1016 difference_type __len = __last - __first;
1019 const difference_type __clen
1020 = std::min(__len, std::min(__first._M_last - __first._M_cur,
1021 __result._M_last - __result._M_cur));
1022 std::move(__first._M_cur, __first._M_cur + __clen, __result._M_cur);
1030 template<typename _Tp>
1031 _Deque_iterator<_Tp, _Tp&, _Tp*>
1032 move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first,
1033 _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last,
1034 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1036 typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self;
1037 typedef typename _Self::difference_type difference_type;
1039 difference_type __len = __last - __first;
1042 difference_type __llen = __last._M_cur - __last._M_first;
1043 _Tp* __lend = __last._M_cur;
1045 difference_type __rlen = __result._M_cur - __result._M_first;
1046 _Tp* __rend = __result._M_cur;
1050 __llen = _Self::_S_buffer_size();
1051 __lend = *(__last._M_node - 1) + __llen;
1055 __rlen = _Self::_S_buffer_size();
1056 __rend = *(__result._M_node - 1) + __rlen;
1059 const difference_type __clen = std::min(__len,
1060 std::min(__llen, __rlen));
1061 std::move_backward(__lend - __clen, __lend, __rend);
1070 _GLIBCXX_END_NAMESPACE_CONTAINER