libstdc++
deque.tcc
Go to the documentation of this file.
1// Deque implementation (out of line) -*- C++ -*-
2
3// Copyright (C) 2001-2026 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#include <bits/stl_algobase.h>
60
61namespace std _GLIBCXX_VISIBILITY(default)
62{
63_GLIBCXX_BEGIN_NAMESPACE_VERSION
64_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
65
66#if __cplusplus >= 201103L
67 template <typename _Tp, typename _Alloc>
68 _GLIBCXX26_CONSTEXPR void
71 {
72 _Map_pointer __cur;
73 __try
74 {
75 for (__cur = this->_M_impl._M_start._M_node;
76 __cur < this->_M_impl._M_finish._M_node;
77 ++__cur)
78 std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
79 _M_get_Tp_allocator());
80 std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
81 this->_M_impl._M_finish._M_cur,
82 _M_get_Tp_allocator());
83 }
84 __catch(...)
85 {
86 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
87 _M_get_Tp_allocator());
88 __throw_exception_again;
89 }
90 }
91#endif
92
93 template <typename _Tp, typename _Alloc>
94 _GLIBCXX26_CONSTEXPR
97 operator=(const deque& __x)
98 {
99 if (std::__addressof(__x) != this)
100 {
101#if __cplusplus >= 201103L
102 if (_Alloc_traits::_S_propagate_on_copy_assign())
103 {
104 if (!_Alloc_traits::_S_always_equal()
105 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
106 {
107 // Replacement allocator cannot free existing storage,
108 // so deallocate everything and take copy of __x's data.
109 _M_replace_map(__x, __x.get_allocator());
110 std::__alloc_on_copy(_M_get_Tp_allocator(),
111 __x._M_get_Tp_allocator());
112 return *this;
113 }
114 std::__alloc_on_copy(_M_get_Tp_allocator(),
115 __x._M_get_Tp_allocator());
116 }
117#endif
118 const size_type __len = size();
119 if (__len >= __x.size())
120 _M_erase_at_end(std::copy(__x.begin(), __x.end(),
121 this->_M_impl._M_start));
122 else
123 {
124 const_iterator __mid = __x.begin() + difference_type(__len);
125 std::copy(__x.begin(), __mid, this->_M_impl._M_start);
126 _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(),
128 }
129 }
130 return *this;
131 }
132
133#if __cplusplus >= 201103L
134 template<typename _Tp, typename _Alloc>
135 template<typename... _Args>
136#if __cplusplus > 201402L
137 _GLIBCXX26_CONSTEXPR
138 typename deque<_Tp, _Alloc>::reference
139#else
140 void
141#endif
143 emplace_front(_Args&&... __args)
144 {
145 if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
146 {
147 _Alloc_traits::construct(this->_M_impl,
148 this->_M_impl._M_start._M_cur - 1,
149 std::forward<_Args>(__args)...);
150 --this->_M_impl._M_start._M_cur;
151 }
152 else
153 _M_push_front_aux(std::forward<_Args>(__args)...);
154#if __cplusplus > 201402L
155 return front();
156#endif
157 }
158
159 template<typename _Tp, typename _Alloc>
160 template<typename... _Args>
161#if __cplusplus > 201402L
162 _GLIBCXX26_CONSTEXPR
163 typename deque<_Tp, _Alloc>::reference
164#else
165 void
166#endif
168 emplace_back(_Args&&... __args)
169 {
170 if (this->_M_impl._M_finish._M_cur
171 != this->_M_impl._M_finish._M_last - 1)
172 {
173 _Alloc_traits::construct(this->_M_impl,
174 this->_M_impl._M_finish._M_cur,
175 std::forward<_Args>(__args)...);
176 ++this->_M_impl._M_finish._M_cur;
177 }
178 else
179 _M_push_back_aux(std::forward<_Args>(__args)...);
180#if __cplusplus > 201402L
181 return back();
182#endif
183 }
184#endif
185
186#if __cplusplus >= 201103L
187 template<typename _Tp, typename _Alloc>
188 template<typename... _Args>
189 _GLIBCXX26_CONSTEXPR
190 typename deque<_Tp, _Alloc>::iterator
192 emplace(const_iterator __position, _Args&&... __args)
193 {
194 if (__position._M_cur == this->_M_impl._M_start._M_cur)
195 {
196 emplace_front(std::forward<_Args>(__args)...);
197 return this->_M_impl._M_start;
198 }
199 else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
200 {
201 emplace_back(std::forward<_Args>(__args)...);
202 iterator __tmp = this->_M_impl._M_finish;
203 --__tmp;
204 return __tmp;
205 }
206 else
207 return _M_emplace_aux(__position._M_const_cast(),
208 std::forward<_Args>(__args)...);
209 }
210#endif
211
212 template <typename _Tp, typename _Alloc>
213 _GLIBCXX26_CONSTEXPR
214 typename deque<_Tp, _Alloc>::iterator
216#if __cplusplus >= 201103L
217 insert(const_iterator __position, const value_type& __x)
218#else
219 insert(iterator __position, const value_type& __x)
220#endif
221 {
222 if (__position._M_cur == this->_M_impl._M_start._M_cur)
223 {
224 push_front(__x);
225 return this->_M_impl._M_start;
226 }
227 else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
228 {
229 push_back(__x);
230 iterator __tmp = this->_M_impl._M_finish;
231 --__tmp;
232 return __tmp;
233 }
234 else
235 return _M_insert_aux(__position._M_const_cast(), __x);
236 }
237
238 template <typename _Tp, typename _Alloc>
239 _GLIBCXX26_CONSTEXPR
240 typename deque<_Tp, _Alloc>::iterator
242 _M_erase(iterator __position)
243 {
244 iterator __next = __position;
245 ++__next;
246 const difference_type __index = __position - begin();
247 if (static_cast<size_type>(__index) < (size() >> 1))
248 {
249 if (__position != begin())
250 _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
251 pop_front();
252 }
253 else
254 {
255 if (__next != end())
256 _GLIBCXX_MOVE3(__next, end(), __position);
257 pop_back();
258 }
259 return begin() + __index;
260 }
261
262 template <typename _Tp, typename _Alloc>
263 _GLIBCXX26_CONSTEXPR
264 typename deque<_Tp, _Alloc>::iterator
266 _M_erase(iterator __first, iterator __last)
267 {
268 if (__first == __last)
269 return __first;
270 else if (__first == begin() && __last == end())
271 {
272 clear();
273 return end();
274 }
275 else
276 {
277 const difference_type __n = __last - __first;
278 const difference_type __elems_before = __first - begin();
279 if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
280 {
281 if (__first != begin())
282 _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
283 _M_erase_at_begin(begin() + __n);
284 }
285 else
286 {
287 if (__last != end())
288 _GLIBCXX_MOVE3(__last, end(), __first);
289 _M_erase_at_end(end() - __n);
290 }
291 return begin() + __elems_before;
292 }
293 }
294
295 template <typename _Tp, class _Alloc>
296 template <typename _InputIterator>
297 _GLIBCXX26_CONSTEXPR void
299 _M_assign_aux(_InputIterator __first, _InputIterator __last,
300 std::input_iterator_tag)
301 {
302 iterator __cur = begin();
303 for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
304 *__cur = *__first;
305 if (__first == __last)
306 _M_erase_at_end(__cur);
307 else
308 _M_range_insert_aux(end(), __first, __last,
309 std::__iterator_category(__first));
310 }
311
312 template <typename _Tp, typename _Alloc>
313 _GLIBCXX26_CONSTEXPR void
315 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
316 {
317 if (__pos._M_cur == this->_M_impl._M_start._M_cur)
318 {
319 iterator __new_start = _M_reserve_elements_at_front(__n);
320 __try
321 {
322 std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
323 __x, _M_get_Tp_allocator());
324 this->_M_impl._M_start = __new_start;
325 }
326 __catch(...)
327 {
328 _M_destroy_nodes(__new_start._M_node,
329 this->_M_impl._M_start._M_node);
330 __throw_exception_again;
331 }
332 }
333 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
334 {
335 iterator __new_finish = _M_reserve_elements_at_back(__n);
336 __try
337 {
338 std::__uninitialized_fill_a(this->_M_impl._M_finish,
339 __new_finish, __x,
340 _M_get_Tp_allocator());
341 this->_M_impl._M_finish = __new_finish;
342 }
343 __catch(...)
344 {
345 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
346 __new_finish._M_node + 1);
347 __throw_exception_again;
348 }
349 }
350 else
351 _M_insert_aux(__pos, __n, __x);
352 }
353
354#if __cplusplus >= 201103L
355 template <typename _Tp, typename _Alloc>
356 _GLIBCXX26_CONSTEXPR void
359 {
360 if (__n)
361 {
362 iterator __new_finish = _M_reserve_elements_at_back(__n);
363 __try
364 {
365 std::__uninitialized_default_a(this->_M_impl._M_finish,
366 __new_finish,
367 _M_get_Tp_allocator());
368 this->_M_impl._M_finish = __new_finish;
369 }
370 __catch(...)
371 {
372 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
373 __new_finish._M_node + 1);
374 __throw_exception_again;
375 }
376 }
377 }
378
379 template <typename _Tp, typename _Alloc>
380 _GLIBCXX26_CONSTEXPR bool
383 {
384 const difference_type __front_capacity
385 = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first);
386 if (__front_capacity == 0)
387 return false;
388
389 const difference_type __back_capacity
390 = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur);
391 if (size_type(__front_capacity + __back_capacity) < _S_buffer_size())
392 return false;
393
394 return std::__shrink_to_fit_aux<deque>::_S_do_it(*this);
395 }
396#endif
397
398 template <typename _Tp, typename _Alloc>
399 _GLIBCXX26_CONSTEXPR void
401 _M_fill_initialize(const value_type& __value)
402 {
403 _Map_pointer __cur;
404 __try
405 {
406 for (__cur = this->_M_impl._M_start._M_node;
407 __cur < this->_M_impl._M_finish._M_node;
408 ++__cur)
409 std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
410 __value, _M_get_Tp_allocator());
411 std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
412 this->_M_impl._M_finish._M_cur,
413 __value, _M_get_Tp_allocator());
414 }
415 __catch(...)
416 {
417 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
418 _M_get_Tp_allocator());
419 __throw_exception_again;
420 }
421 }
422
423 template <typename _Tp, typename _Alloc>
424 template <typename _InputIterator>
425 _GLIBCXX26_CONSTEXPR void
427 _M_range_initialize(_InputIterator __first, _InputIterator __last,
429 {
430 this->_M_initialize_map(0);
431 __try
432 {
433 for (; __first != __last; ++__first)
434#if __cplusplus >= 201103L
435 emplace_back(*__first);
436#else
437 push_back(*__first);
438#endif
439 }
440 __catch(...)
441 {
442 clear();
443 __throw_exception_again;
444 }
445 }
446
447 template <typename _Tp, typename _Alloc>
448 template <typename _ForwardIterator>
449 _GLIBCXX26_CONSTEXPR void
451 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
453 {
454 const size_type __n = std::distance(__first, __last);
455 this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator()));
456
457 _Map_pointer __cur_node;
458 __try
459 {
460 for (__cur_node = this->_M_impl._M_start._M_node;
461 __cur_node < this->_M_impl._M_finish._M_node;
462 ++__cur_node)
463 {
464 if (__n < _S_buffer_size())
465 __builtin_unreachable(); // See PR 100516
466
467 _ForwardIterator __mid = __first;
468 std::advance(__mid, _S_buffer_size());
469 std::__uninitialized_copy_a(__first, __mid, *__cur_node,
470 _M_get_Tp_allocator());
471 __first = __mid;
472 }
473 std::__uninitialized_copy_a(__first, __last,
474 this->_M_impl._M_finish._M_first,
475 _M_get_Tp_allocator());
476 }
477 __catch(...)
478 {
479 std::_Destroy(this->_M_impl._M_start,
480 iterator(*__cur_node, __cur_node),
481 _M_get_Tp_allocator());
482 __throw_exception_again;
483 }
484 }
485
486 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
487 template<typename _Tp, typename _Alloc>
488#if __cplusplus >= 201103L
489 template<typename... _Args>
490 _GLIBCXX26_CONSTEXPR void
492 _M_push_back_aux(_Args&&... __args)
493#else
494 void
496 _M_push_back_aux(const value_type& __t)
497#endif
498 {
499 if (size() == max_size())
500 __throw_length_error(
501 __N("cannot create std::deque larger than max_size()"));
502
504 *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
505 __try
506 {
507#if __cplusplus >= 201103L
508 _Alloc_traits::construct(this->_M_impl,
509 this->_M_impl._M_finish._M_cur,
510 std::forward<_Args>(__args)...);
511#else
512 this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
513#endif
514 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
515 + 1);
516 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
517 }
518 __catch(...)
519 {
520 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
521 __throw_exception_again;
522 }
523 }
524
525 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
526 template<typename _Tp, typename _Alloc>
527#if __cplusplus >= 201103L
528 template<typename... _Args>
529 _GLIBCXX26_CONSTEXPR void
531 _M_push_front_aux(_Args&&... __args)
532#else
533 void
535 _M_push_front_aux(const value_type& __t)
536#endif
537 {
538 if (size() == max_size())
539 __throw_length_error(
540 __N("cannot create std::deque larger than max_size()"));
541
543 *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
544 __try
545 {
546 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
547 - 1);
548 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
549#if __cplusplus >= 201103L
550 _Alloc_traits::construct(this->_M_impl,
551 this->_M_impl._M_start._M_cur,
552 std::forward<_Args>(__args)...);
553#else
554 this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
555#endif
556 }
557 __catch(...)
558 {
559 ++this->_M_impl._M_start;
560 _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
561 __throw_exception_again;
562 }
563 }
564
565 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
566 template <typename _Tp, typename _Alloc>
567 _GLIBCXX26_CONSTEXPR void
570 {
571 _M_deallocate_node(this->_M_impl._M_finish._M_first);
572 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
573 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
574 _Alloc_traits::destroy(_M_get_Tp_allocator(),
575 this->_M_impl._M_finish._M_cur);
576 }
577
578 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
579 // Note that if the deque has at least one element (a precondition for this
580 // member function), and if
581 // _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
582 // then the deque must have at least two nodes.
583 template <typename _Tp, typename _Alloc>
584 _GLIBCXX26_CONSTEXPR void
587 {
588 _Alloc_traits::destroy(_M_get_Tp_allocator(),
589 this->_M_impl._M_start._M_cur);
590 _M_deallocate_node(this->_M_impl._M_start._M_first);
591 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
592 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
593 }
594
595 template <typename _Tp, typename _Alloc>
596 template <typename _InputIterator, typename _Sentinel>
597 _GLIBCXX26_CONSTEXPR void
599 _M_range_prepend(_InputIterator __first, _Sentinel __last,
600 size_type __n)
601 {
602 iterator __new_start = _M_reserve_elements_at_front(__n);
603 __try
604 {
605 std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
606 __new_start, _M_get_Tp_allocator());
607 this->_M_impl._M_start = __new_start;
608 }
609 __catch(...)
610 {
611 _M_destroy_nodes(__new_start._M_node,
612 this->_M_impl._M_start._M_node);
613 __throw_exception_again;
614 }
615 }
616
617 template <typename _Tp, typename _Alloc>
618 template <typename _InputIterator, typename _Sentinel>
619 _GLIBCXX26_CONSTEXPR void
621 _M_range_append(_InputIterator __first, _Sentinel __last,
622 size_type __n)
623 {
624 iterator __new_finish = _M_reserve_elements_at_back(__n);
625 __try
626 {
627 std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
628 this->_M_impl._M_finish,
629 _M_get_Tp_allocator());
630 this->_M_impl._M_finish = __new_finish;
631 }
632 __catch(...)
633 {
634 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
635 __new_finish._M_node + 1);
636 __throw_exception_again;
637 }
638 }
639
640 template <typename _Tp, typename _Alloc>
641 template <typename _InputIterator>
642 _GLIBCXX26_CONSTEXPR void
645 _InputIterator __first, _InputIterator __last,
646 std::input_iterator_tag)
647 { std::copy(__first, __last, std::inserter(*this, __pos)); }
648
649 template <typename _Tp, typename _Alloc>
650 template <typename _ForwardIterator>
651 _GLIBCXX26_CONSTEXPR void
654 _ForwardIterator __first, _ForwardIterator __last,
655 std::forward_iterator_tag)
656 {
657 const size_type __n = std::distance(__first, __last);
658 if (__builtin_expect(__n == 0, 0))
659 return;
660
661 if (__pos._M_cur == this->_M_impl._M_start._M_cur)
662 _M_range_prepend(__first, __last, __n);
663 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
664 _M_range_append(__first, __last, __n);
665 else
666 _M_insert_aux(__pos, __first, __last, __n);
667 }
668
669 template<typename _Tp, typename _Alloc>
670#if __cplusplus >= 201103L
671 template<typename... _Args>
672 _GLIBCXX26_CONSTEXPR
673 typename deque<_Tp, _Alloc>::iterator
675 _M_emplace_aux(iterator __pos, _Args&&... __args)
676 {
677 // We should construct this temporary while the deque is
678 // in its current state in case something in __args...
679 // depends on that state before shuffling elements around.
680 _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
681#else
682 typename deque<_Tp, _Alloc>::iterator
684 _M_insert_aux(iterator __pos, const value_type& __x)
685 {
686 value_type __x_copy = __x; // XXX copy
687#endif
688 difference_type __index = __pos - this->_M_impl._M_start;
689 if (static_cast<size_type>(__index) < size() / 2)
690 {
691 push_front(_GLIBCXX_MOVE(front()));
692 iterator __front1 = this->_M_impl._M_start;
693 ++__front1;
694 iterator __front2 = __front1;
695 ++__front2;
696 __pos = this->_M_impl._M_start + __index;
697 iterator __pos1 = __pos;
698 ++__pos1;
699 _GLIBCXX_MOVE3(__front2, __pos1, __front1);
700 }
701 else
702 {
703 push_back(_GLIBCXX_MOVE(back()));
704 iterator __back1 = this->_M_impl._M_finish;
705 --__back1;
706 iterator __back2 = __back1;
707 --__back2;
708 __pos = this->_M_impl._M_start + __index;
709 _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1);
710 }
711#if __cplusplus >= 201103L
712 *__pos = std::move(__tmp._M_val());
713#else
714 *__pos = __x_copy;
715#endif
716 return __pos;
717 }
718
719 template <typename _Tp, typename _Alloc>
720 _GLIBCXX26_CONSTEXPR void
722 _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
723 {
724 const difference_type __elems_before = __pos - this->_M_impl._M_start;
725 const size_type __length = this->size();
726 value_type __x_copy = __x;
727 if (__elems_before < difference_type(__length / 2))
728 {
729 iterator __new_start = _M_reserve_elements_at_front(__n);
730 iterator __old_start = this->_M_impl._M_start;
731 __pos = this->_M_impl._M_start + __elems_before;
732 __try
733 {
734 if (__elems_before >= difference_type(__n))
735 {
736 iterator __start_n = (this->_M_impl._M_start
737 + difference_type(__n));
738 std::__uninitialized_move_a(this->_M_impl._M_start,
739 __start_n, __new_start,
740 _M_get_Tp_allocator());
741 this->_M_impl._M_start = __new_start;
742 _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
743 std::fill(__pos - difference_type(__n), __pos, __x_copy);
744 }
745 else
746 {
747 std::__uninitialized_move_fill(this->_M_impl._M_start,
748 __pos, __new_start,
749 this->_M_impl._M_start,
750 __x_copy,
751 _M_get_Tp_allocator());
752 this->_M_impl._M_start = __new_start;
753 std::fill(__old_start, __pos, __x_copy);
754 }
755 }
756 __catch(...)
757 {
758 _M_destroy_nodes(__new_start._M_node,
759 this->_M_impl._M_start._M_node);
760 __throw_exception_again;
761 }
762 }
763 else
764 {
765 iterator __new_finish = _M_reserve_elements_at_back(__n);
766 iterator __old_finish = this->_M_impl._M_finish;
767 const difference_type __elems_after =
768 difference_type(__length) - __elems_before;
769 __pos = this->_M_impl._M_finish - __elems_after;
770 __try
771 {
772 if (__elems_after > difference_type(__n))
773 {
774 iterator __finish_n = (this->_M_impl._M_finish
775 - difference_type(__n));
776 std::__uninitialized_move_a(__finish_n,
777 this->_M_impl._M_finish,
778 this->_M_impl._M_finish,
779 _M_get_Tp_allocator());
780 this->_M_impl._M_finish = __new_finish;
781 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
782 std::fill(__pos, __pos + difference_type(__n), __x_copy);
783 }
784 else
785 {
786 std::__uninitialized_fill_move(this->_M_impl._M_finish,
787 __pos + difference_type(__n),
788 __x_copy, __pos,
789 this->_M_impl._M_finish,
790 _M_get_Tp_allocator());
791 this->_M_impl._M_finish = __new_finish;
792 std::fill(__pos, __old_finish, __x_copy);
793 }
794 }
795 __catch(...)
796 {
797 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
798 __new_finish._M_node + 1);
799 __throw_exception_again;
800 }
801 }
802 }
803
804 template <typename _Tp, typename _Alloc>
805 template <typename _ForwardIterator>
806 _GLIBCXX26_CONSTEXPR void
809 _ForwardIterator __first, _ForwardIterator __last,
810 size_type __n)
811 {
812 const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
813 const size_type __length = size();
814 if (static_cast<size_type>(__elemsbefore) < __length / 2)
815 {
816 iterator __new_start = _M_reserve_elements_at_front(__n);
817 iterator __old_start = this->_M_impl._M_start;
818 __pos = this->_M_impl._M_start + __elemsbefore;
819 __try
820 {
821 if (__elemsbefore >= difference_type(__n))
822 {
823 iterator __start_n = (this->_M_impl._M_start
824 + difference_type(__n));
825 std::__uninitialized_move_a(this->_M_impl._M_start,
826 __start_n, __new_start,
827 _M_get_Tp_allocator());
828 this->_M_impl._M_start = __new_start;
829 _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
830 std::copy(__first, __last, __pos - difference_type(__n));
831 }
832 else
833 {
834 _ForwardIterator __mid = __first;
835 std::advance(__mid, difference_type(__n) - __elemsbefore);
836 std::__uninitialized_move_copy(this->_M_impl._M_start,
837 __pos, __first, __mid,
838 __new_start,
839 _M_get_Tp_allocator());
840 this->_M_impl._M_start = __new_start;
841 std::copy(__mid, __last, __old_start);
842 }
843 }
844 __catch(...)
845 {
846 _M_destroy_nodes(__new_start._M_node,
847 this->_M_impl._M_start._M_node);
848 __throw_exception_again;
849 }
850 }
851 else
852 {
853 iterator __new_finish = _M_reserve_elements_at_back(__n);
854 iterator __old_finish = this->_M_impl._M_finish;
855 const difference_type __elemsafter =
856 difference_type(__length) - __elemsbefore;
857 __pos = this->_M_impl._M_finish - __elemsafter;
858 __try
859 {
860 if (__elemsafter > difference_type(__n))
861 {
862 iterator __finish_n = (this->_M_impl._M_finish
863 - difference_type(__n));
864 std::__uninitialized_move_a(__finish_n,
865 this->_M_impl._M_finish,
866 this->_M_impl._M_finish,
867 _M_get_Tp_allocator());
868 this->_M_impl._M_finish = __new_finish;
869 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
870 std::copy(__first, __last, __pos);
871 }
872 else
873 {
874 _ForwardIterator __mid = __first;
875 std::advance(__mid, __elemsafter);
876 std::__uninitialized_copy_move(__mid, __last, __pos,
877 this->_M_impl._M_finish,
878 this->_M_impl._M_finish,
879 _M_get_Tp_allocator());
880 this->_M_impl._M_finish = __new_finish;
881 std::copy(__first, __mid, __pos);
882 }
883 }
884 __catch(...)
885 {
886 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
887 __new_finish._M_node + 1);
888 __throw_exception_again;
889 }
890 }
891 }
892
893#if __glibcxx_containers_ranges // C++ >= 23
894 template<ranges::forward_range _Rg>
895 _GLIBCXX26_CONSTEXPR auto
896 __advance_dist(_Rg& __rg)
897 {
898 struct _Res
899 {
900 ranges::iterator_t<_Rg> __last;
901 ranges::range_difference_t<_Rg> __size;
902 };
903 if constexpr (ranges::common_range<_Rg>)
904 return _Res{ranges::end(__rg), ranges::distance(__rg)};
905 else if constexpr (ranges::sized_range<_Rg>)
906 {
907 auto const __n = ranges::distance(__rg);
908 auto __it = ranges::begin(__rg);
910 __it += __n;
911 else
912 ranges::advance(__it, ranges::end(__rg));
913 return _Res{__it, __n};
914 }
915 else
916 {
917 auto __it = ranges::begin(__rg);
918 auto const __last = ranges::end(__rg);
919 ranges::range_difference_t<_Rg> __n(0);
920 for (; __it != __last; ++__it)
921 ++__n;
922 return _Res{__it, __n};
923 }
924 }
925
926 template<typename _Tp, typename _Alloc>
927 template<__detail::__container_compatible_range<_Tp> _Rg>
928 _GLIBCXX26_CONSTEXPR auto
930 insert_range(const_iterator __pos, _Rg&& __rg)
931 -> iterator
932 {
933 if (__pos == cend())
934 {
935 const auto __ins_idx = size();
936 append_range(std::forward<_Rg>(__rg));
937 return begin() + __ins_idx;
938 }
939
940 if (__pos == cbegin())
941 {
942 prepend_range(std::forward<_Rg>(__rg));
943 return begin();
944 }
945
946 const auto __ins_idx = __pos - cbegin();
947 if constexpr (ranges::forward_range<_Rg>)
948 {
949 auto [__last, __n] = __advance_dist(__rg);
950 if (__n != 0) [[likely]]
951 _M_insert_aux(__pos._M_const_cast(),
952 ranges::begin(__rg), __last,
953 __n);
954 }
955 else
956 {
957 auto __first = ranges::begin(__rg);
958 const auto __last = ranges::end(__rg);
959 for (auto __it = __pos._M_const_cast(); __first != __last;
960 (void)++__first, ++__it)
961 __it = _M_emplace_aux(__it, *__first);
962 }
963 return begin() + __ins_idx;
964 }
965
966 template<typename _Tp, typename _Alloc>
967 template<__detail::__container_compatible_range<_Tp> _Rg>
968 _GLIBCXX26_CONSTEXPR void
970 prepend_range(_Rg&& __rg)
971 {
972 if (empty())
973 append_range(std::forward<_Rg>(__rg));
975 {
976 const size_type __n(ranges::distance(__rg));
977 if (__n != 0) [[likely]]
978 _M_range_prepend(ranges::begin(__rg), ranges::end(__rg), __n);
979 }
980 else
981 {
982 struct _Guard_elts_front
983 {
984 deque& __self;
985 size_type __n = 0;
986
987 ~_Guard_elts_front()
988 {
989 if (__n > 0)
990 __self._M_erase_at_begin(__self.begin() + __n);
991 }
992 };
993
994 _Guard_elts_front __guard{*this};
995 auto __first = ranges::begin(__rg);
996 const auto __last = ranges::end(__rg);
997 for (; __first != __last; (void)++__first, ++__guard.__n)
998 emplace_front(*__first);
999
1000 for (auto __fins = begin(), __lins = begin() + __guard.__n;
1001 __fins != __lins && __fins != --__lins; ++__fins)
1002 std::iter_swap(__fins, __lins);
1003
1004 __guard.__n = 0;
1005 }
1006 }
1007
1008 template<typename _Tp, typename _Alloc>
1009 template<__detail::__container_compatible_range<_Tp> _Rg>
1010 _GLIBCXX26_CONSTEXPR void
1012 append_range(_Rg&& __rg)
1013 {
1015 {
1016 const size_type __n(ranges::distance(__rg));
1017 if (__n != 0) [[likely]]
1018 _M_range_append(ranges::begin(__rg), ranges::end(__rg), __n);
1019 }
1020 else
1021 {
1022 struct _Guard_elts_back
1023 {
1024 deque& __self;
1025 size_type __n = __self.size();
1026
1027 _GLIBCXX26_CONSTEXPR
1028 ~_Guard_elts_back()
1029 {
1030 if (__n < __self.size())
1031 __self._M_erase_at_end(__self.begin() + __n);
1032 }
1033 };
1034
1035 _Guard_elts_back __guard{*this};
1036 auto __first = ranges::begin(__rg);
1037 const auto __last = ranges::end(__rg);
1038 for (; __first != __last; (void)++__first)
1039 emplace_back(*__first);
1040
1041 __guard.__n = size();
1042 }
1043 }
1044#endif // containers_ranges
1045
1046 template<typename _Tp, typename _Alloc>
1047 _GLIBCXX26_CONSTEXPR void
1049 _M_destroy_data_aux(iterator __first, iterator __last)
1050 {
1051 for (_Map_pointer __node = __first._M_node + 1;
1052 __node < __last._M_node; ++__node)
1053 std::_Destroy(*__node, *__node + _S_buffer_size(),
1054 _M_get_Tp_allocator());
1055
1056 if (__first._M_node != __last._M_node)
1057 {
1058 std::_Destroy(__first._M_cur, __first._M_last,
1059 _M_get_Tp_allocator());
1060 std::_Destroy(__last._M_first, __last._M_cur,
1061 _M_get_Tp_allocator());
1062 }
1063 else
1064 std::_Destroy(__first._M_cur, __last._M_cur,
1065 _M_get_Tp_allocator());
1066 }
1067
1068 template <typename _Tp, typename _Alloc>
1069 _GLIBCXX26_CONSTEXPR void
1071 _M_new_elements_at_front(size_type __new_elems)
1072 {
1073 if (this->max_size() - this->size() < __new_elems)
1074 __throw_length_error(__N("deque::_M_new_elements_at_front"));
1075
1076 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
1077 / _S_buffer_size());
1078 _M_reserve_map_at_front(__new_nodes);
1079 size_type __i;
1080 __try
1081 {
1082 for (__i = 1; __i <= __new_nodes; ++__i)
1083 *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
1084 }
1085 __catch(...)
1086 {
1087 for (size_type __j = 1; __j < __i; ++__j)
1088 _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
1089 __throw_exception_again;
1090 }
1091 }
1092
1093 template <typename _Tp, typename _Alloc>
1094 _GLIBCXX26_CONSTEXPR void
1096 _M_new_elements_at_back(size_type __new_elems)
1097 {
1098 if (this->max_size() - this->size() < __new_elems)
1099 __throw_length_error(__N("deque::_M_new_elements_at_back"));
1100
1101 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1)
1102 / _S_buffer_size());
1103 _M_reserve_map_at_back(__new_nodes);
1104 size_type __i;
1105 __try
1106 {
1107 for (__i = 1; __i <= __new_nodes; ++__i)
1108 *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
1109 }
1110 __catch(...)
1111 {
1112 for (size_type __j = 1; __j < __i; ++__j)
1113 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
1114 __throw_exception_again;
1115 }
1116 }
1117
1118 template <typename _Tp, typename _Alloc>
1119 _GLIBCXX26_CONSTEXPR void
1121 _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
1122 {
1123 const size_type __old_num_nodes
1124 = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
1125 const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
1126
1127 _Map_pointer __new_nstart;
1128 if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
1129 {
1130 __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
1131 - __new_num_nodes) / 2
1132 + (__add_at_front ? __nodes_to_add : 0);
1133 if (__new_nstart < this->_M_impl._M_start._M_node)
1134 std::copy(this->_M_impl._M_start._M_node,
1135 this->_M_impl._M_finish._M_node + 1,
1136 __new_nstart);
1137 else
1138 std::copy_backward(this->_M_impl._M_start._M_node,
1139 this->_M_impl._M_finish._M_node + 1,
1140 __new_nstart + __old_num_nodes);
1141 }
1142 else
1143 {
1144 size_type __new_map_size = this->_M_impl._M_map_size
1145 + std::max(this->_M_impl._M_map_size,
1146 __nodes_to_add) + 2;
1147
1148 const size_t __bufsz = __deque_buf_size(sizeof(_Tp));
1149 if (__new_map_size > ((max_size() + __bufsz - 1) / __bufsz) * 2)
1150 __builtin_unreachable();
1151
1152 _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
1153 __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
1154 + (__add_at_front ? __nodes_to_add : 0);
1155 std::copy(this->_M_impl._M_start._M_node,
1156 this->_M_impl._M_finish._M_node + 1,
1157 __new_nstart);
1158 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
1159
1160 this->_M_impl._M_map = __new_map;
1161 this->_M_impl._M_map_size = __new_map_size;
1162 }
1163
1164 this->_M_impl._M_start._M_set_node(__new_nstart);
1165 this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
1166 }
1167
1168_GLIBCXX_END_NAMESPACE_CONTAINER
1169
1170 // Overload for deque::iterators, exploiting the "segmented-iterator
1171 // optimization".
1172 template<typename _Tp, typename _VTp>
1173 _GLIBCXX26_CONSTEXPR void
1174 __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
1175 const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __last,
1176 const _VTp& __value)
1177 {
1178 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
1179 if (__first._M_node != __last._M_node)
1180 {
1181 std::__fill_a1(__first._M_cur, __first._M_last, __value);
1182
1183 for (typename _Iter::_Map_pointer __node = __first._M_node + 1;
1184 __node < __last._M_node; ++__node)
1185 std::__fill_a1(*__node, *__node + _Iter::_S_buffer_size(), __value);
1186
1187 std::__fill_a1(__last._M_first, __last._M_cur, __value);
1188 }
1189 else
1190 std::__fill_a1(__first._M_cur, __last._M_cur, __value);
1191 }
1192
1193 template<bool _IsMove,
1194 typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1195 _GLIBCXX26_CONSTEXPR _OI
1196 __copy_move_dit(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1197 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1198 _OI __result)
1199 {
1200 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1201 if (__first._M_node != __last._M_node)
1202 {
1203 __result
1204 = std::__copy_move_a1<_IsMove>(__first._M_cur, __first._M_last,
1205 __result);
1206
1207 for (typename _Iter::_Map_pointer __node = __first._M_node + 1;
1208 __node != __last._M_node; ++__node)
1209 __result
1210 = std::__copy_move_a1<_IsMove>(*__node,
1211 *__node + _Iter::_S_buffer_size(),
1212 __result);
1213
1214 return std::__copy_move_a1<_IsMove>(__last._M_first, __last._M_cur,
1215 __result);
1216 }
1217
1218 return std::__copy_move_a1<_IsMove>(__first._M_cur, __last._M_cur,
1219 __result);
1220 }
1221
1222 template<bool _IsMove,
1223 typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1224 _GLIBCXX26_CONSTEXPR _OI
1225 __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1226 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1227 _OI __result)
1228 { return __copy_move_dit<_IsMove>(__first, __last, __result); }
1229
1230 template<bool _IsMove,
1231 typename _ITp, typename _IRef, typename _IPtr, typename _OTp>
1232 _GLIBCXX26_CONSTEXPR
1233 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
1234 __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
1235 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
1236 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result)
1237 { return __copy_move_dit<_IsMove>(__first, __last, __result); }
1238
1239 template<bool _IsMove, typename _II, typename _Tp>
1240 _GLIBCXX26_CONSTEXPR
1241 typename __gnu_cxx::__enable_if<
1242 __is_any_random_access_iter<_II>::__value,
1243 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type
1244 __copy_move_a1(_II __first, _II __last,
1245 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1246 {
1247 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
1248 typedef typename _Iter::difference_type difference_type;
1249
1250 difference_type __len = __last - __first;
1251 while (__len > 0)
1252 {
1253 const difference_type __clen
1254 = std::min(__len, __result._M_last - __result._M_cur);
1255 std::__copy_move_a1<_IsMove>(__first, __first + __clen,
1256 __result._M_cur);
1257
1258 __first += __clen;
1259 __result += __clen;
1260 __len -= __clen;
1261 }
1262
1263 return __result;
1264 }
1265
1266 template<bool _IsMove, typename _CharT>
1267 _GLIBCXX26_CONSTEXPR
1268 typename __gnu_cxx::__enable_if<
1269 __is_char<_CharT>::__value,
1270 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> >::__type
1271 __copy_move_a2(
1272 istreambuf_iterator<_CharT, char_traits<_CharT> > __first,
1274 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> __result)
1275 {
1276 if (__first == __last)
1277 return __result;
1278
1279 for (;;)
1280 {
1281 const std::ptrdiff_t __len = __result._M_last - __result._M_cur;
1282 const std::ptrdiff_t __nb
1283 = std::__copy_n_a(__first, __len, __result._M_cur, false)
1284 - __result._M_cur;
1285 __result += __nb;
1286
1287 if (__nb != __len)
1288 break;
1289 }
1290
1291 return __result;
1292 }
1293
1294 template<typename _CharT, typename _Size>
1295 _GLIBCXX26_CONSTEXPR
1296 typename __gnu_cxx::__enable_if<
1297 __is_char<_CharT>::__value,
1298 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> >::__type
1299 __copy_n_a(
1300 istreambuf_iterator<_CharT, char_traits<_CharT> > __it, _Size __size,
1301 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> __result,
1302 bool __strict)
1303 {
1304 if (__size == 0)
1305 return __result;
1306
1307 do
1308 {
1309 const _Size __len
1310 = std::min<_Size>(__result._M_last - __result._M_cur, __size);
1311 std::__copy_n_a(__it, __len, __result._M_cur, __strict);
1312 __result += __len;
1313 __size -= __len;
1314 }
1315 while (__size != 0);
1316 return __result;
1317 }
1318
1319 template<bool _IsMove,
1320 typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1321 _GLIBCXX26_CONSTEXPR _OI
1322 __copy_move_backward_dit(
1323 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1324 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1325 _OI __result)
1326 {
1327 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1328 if (__first._M_node != __last._M_node)
1329 {
1330 __result = std::__copy_move_backward_a1<_IsMove>(
1331 __last._M_first, __last._M_cur, __result);
1332
1333 for (typename _Iter::_Map_pointer __node = __last._M_node - 1;
1334 __node != __first._M_node; --__node)
1335 __result = std::__copy_move_backward_a1<_IsMove>(
1336 *__node, *__node + _Iter::_S_buffer_size(), __result);
1337
1338 return std::__copy_move_backward_a1<_IsMove>(
1339 __first._M_cur, __first._M_last, __result);
1340 }
1341
1342 return std::__copy_move_backward_a1<_IsMove>(
1343 __first._M_cur, __last._M_cur, __result);
1344 }
1345
1346 template<bool _IsMove,
1347 typename _Tp, typename _Ref, typename _Ptr, typename _OI>
1348 _GLIBCXX26_CONSTEXPR _OI
1349 __copy_move_backward_a1(
1350 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first,
1351 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last,
1352 _OI __result)
1353 { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); }
1354
1355 template<bool _IsMove,
1356 typename _ITp, typename _IRef, typename _IPtr, typename _OTp>
1357 _GLIBCXX26_CONSTEXPR
1358 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
1359 __copy_move_backward_a1(
1360 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
1361 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
1362 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result)
1363 { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); }
1364
1365 template<bool _IsMove, typename _II, typename _Tp>
1366 _GLIBCXX26_CONSTEXPR
1367 typename __gnu_cxx::__enable_if<
1368 __is_any_random_access_iter<_II>::__value,
1369 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type
1370 __copy_move_backward_a1(_II __first, _II __last,
1371 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result)
1372 {
1373 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter;
1374 typedef typename _Iter::difference_type difference_type;
1375
1376 difference_type __len = __last - __first;
1377 while (__len > 0)
1378 {
1379 difference_type __rlen = __result._M_cur - __result._M_first;
1380 _Tp* __rend = __result._M_cur;
1381 if (!__rlen)
1382 {
1383 __rlen = _Iter::_S_buffer_size();
1384 __rend = *(__result._M_node - 1) + __rlen;
1385 }
1386
1387 const difference_type __clen = std::min(__len, __rlen);
1388 std::__copy_move_backward_a1<_IsMove>(__last - __clen, __last, __rend);
1389
1390 __last -= __clen;
1391 __result -= __clen;
1392 __len -= __clen;
1393 }
1394
1395 return __result;
1396 }
1397
1398 template<typename _Tp, typename _Ref, typename _Ptr, typename _II>
1399 _GLIBCXX26_CONSTEXPR bool
1400 __equal_dit(
1401 const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __first1,
1402 const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __last1,
1403 _II __first2)
1404 {
1405 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1406 if (__first1._M_node != __last1._M_node)
1407 {
1408 if (!std::__equal_aux1(__first1._M_cur, __first1._M_last, __first2))
1409 return false;
1410
1411 __first2 += __first1._M_last - __first1._M_cur;
1412 for (typename _Iter::_Map_pointer __node = __first1._M_node + 1;
1413 __node != __last1._M_node;
1414 __first2 += _Iter::_S_buffer_size(), ++__node)
1415 if (!std::__equal_aux1(*__node, *__node + _Iter::_S_buffer_size(),
1416 __first2))
1417 return false;
1418
1419 return std::__equal_aux1(__last1._M_first, __last1._M_cur, __first2);
1420 }
1421
1422 return std::__equal_aux1(__first1._M_cur, __last1._M_cur, __first2);
1423 }
1424
1425 template<typename _Tp, typename _Ref, typename _Ptr, typename _II>
1426 _GLIBCXX26_CONSTEXPR
1427 typename __gnu_cxx::__enable_if<
1428 __is_any_random_access_iter<_II>::__value, bool>::__type
1429 __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first1,
1430 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last1,
1431 _II __first2)
1432 { return std::__equal_dit(__first1, __last1, __first2); }
1433
1434 template<typename _Tp1, typename _Ref1, typename _Ptr1,
1435 typename _Tp2, typename _Ref2, typename _Ptr2>
1436 _GLIBCXX26_CONSTEXPR bool
1437 __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
1438 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
1439 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2)
1440 { return std::__equal_dit(__first1, __last1, __first2); }
1441
1442 template<typename _II, typename _Tp, typename _Ref, typename _Ptr>
1443 _GLIBCXX26_CONSTEXPR
1444 typename __gnu_cxx::__enable_if<
1445 __is_any_random_access_iter<_II>::__value, bool>::__type
1446 __equal_aux1(_II __first1, _II __last1,
1447 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first2)
1448 {
1449 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter;
1450 typedef typename _Iter::difference_type difference_type;
1451
1452 difference_type __len = __last1 - __first1;
1453 while (__len > 0)
1454 {
1455 const difference_type __clen
1456 = std::min(__len, __first2._M_last - __first2._M_cur);
1457 if (!std::__equal_aux1(__first1, __first1 + __clen, __first2._M_cur))
1458 return false;
1459
1460 __first1 += __clen;
1461 __len -= __clen;
1462 __first2 += __clen;
1463 }
1464
1465 return true;
1466 }
1467
1468 template<typename _Tp1, typename _Ref, typename _Ptr, typename _Tp2>
1469 _GLIBCXX26_CONSTEXPR int
1470 __lex_cmp_dit(
1471 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref, _Ptr> __first1,
1472 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref, _Ptr> __last1,
1473 const _Tp2* __first2, const _Tp2* __last2)
1474 {
1475#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
1476 const bool __simple =
1477 (__is_memcmp_ordered_with<_Tp1, _Tp2>::__value
1478 && __is_pointer(_Ptr)
1479#if __cplusplus > 201703L && __cpp_lib_concepts
1480 // For C++20 iterator_traits<volatile T*>::value_type is non-volatile
1481 // so __is_byte<T> could be true, but we can't use memcmp with
1482 // volatile data.
1483 && !is_volatile_v<_Tp1> && !is_volatile_v<_Tp2>
1484#endif
1485 );
1486 typedef std::__lexicographical_compare<__simple> _Lc;
1487#else
1488 typedef std::__lexicographical_compare<false> _Lc;
1489#endif
1490
1491 while (__first1._M_node != __last1._M_node)
1492 {
1493 const ptrdiff_t __len1 = __first1._M_last - __first1._M_cur;
1494 const ptrdiff_t __len2 = __last2 - __first2;
1495 const ptrdiff_t __len = std::min(__len1, __len2);
1496 // if __len1 > __len2 this will return a positive value:
1497 if (int __ret = _Lc::__3way(__first1._M_cur, __first1._M_last,
1498 __first2, __first2 + __len))
1499 return __ret;
1500
1501 __first1 += __len;
1502 __first2 += __len;
1503 }
1504 return _Lc::__3way(__first1._M_cur, __last1._M_cur,
1505 __first2, __last2);
1506 }
1507
1508 template<typename _Tp1, typename _Ref1, typename _Ptr1,
1509 typename _Tp2>
1510 inline _GLIBCXX26_CONSTEXPR bool
1511 __lexicographical_compare_aux1(
1512 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
1513 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
1514 _Tp2* __first2, _Tp2* __last2)
1515 { return std::__lex_cmp_dit(__first1, __last1, __first2, __last2) < 0; }
1516
1517 template<typename _Tp1,
1518 typename _Tp2, typename _Ref2, typename _Ptr2>
1519 inline _GLIBCXX26_CONSTEXPR bool
1520 __lexicographical_compare_aux1(_Tp1* __first1, _Tp1* __last1,
1521 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2,
1522 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __last2)
1523 { return std::__lex_cmp_dit(__first2, __last2, __first1, __last1) > 0; }
1524
1525 template<typename _Tp1, typename _Ref1, typename _Ptr1,
1526 typename _Tp2, typename _Ref2, typename _Ptr2>
1527 inline _GLIBCXX26_CONSTEXPR bool
1528 __lexicographical_compare_aux1(
1529 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1,
1530 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1,
1531 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2,
1532 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __last2)
1533 {
1534#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
1535 const bool __simple =
1536 (__is_memcmp_ordered_with<_Tp1, _Tp2>::__value
1537 && __is_pointer(_Ptr1) && __is_pointer(_Ptr2)
1538#if __cplusplus > 201703L && __cpp_lib_concepts
1539 // For C++20 iterator_traits<volatile T*>::value_type is non-volatile
1540 // so __is_byte<T> could be true, but we can't use memcmp with
1541 // volatile data.
1542 && !is_volatile_v<_Tp1> && !is_volatile_v<_Tp2>
1543#endif
1544 );
1545 typedef std::__lexicographical_compare<__simple> _Lc;
1546#else
1547 typedef std::__lexicographical_compare<false> _Lc;
1548#endif
1549
1550 while (__first1 != __last1)
1551 {
1552 const ptrdiff_t __len2 = __first2._M_node == __last2._M_node
1553 ? __last2._M_cur - __first2._M_cur
1554 : __first2._M_last - __first2._M_cur;
1555 if (__len2 == 0)
1556 return false;
1557 const ptrdiff_t __len1 = __first1._M_node == __last1._M_node
1558 ? __last1._M_cur - __first1._M_cur
1559 : __first1._M_last - __first1._M_cur;
1560 const ptrdiff_t __len = std::min(__len1, __len2);
1561 if (int __ret = _Lc::__3way(__first1._M_cur, __first1._M_cur + __len,
1562 __first2._M_cur, __first2._M_cur + __len))
1563 return __ret < 0;
1564
1565 __first1 += __len;
1566 __first2 += __len;
1567 }
1568
1569 return __last2 != __first2;
1570 }
1571
1572#if __cplusplus >= 201103L
1573#pragma GCC diagnostic push
1574#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
1575 template<typename _ITp, typename _IRef, typename _IPtr, typename _OTp,
1576 typename _Tp>
1577 _GLIBCXX26_CONSTEXPR
1578 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
1579 __uninitialized_copy_a(
1580 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
1581 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
1582 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result,
1584 {
1585 // In order to unwind all initialized elements, we just use the default
1586 // implementation if construction can throw.
1587 if constexpr (!__is_nothrow_constructible(_OTp, _IRef))
1588 return std::__do_uninit_copy(__first, __last, __result);
1589 else
1590 while (__first != __last)
1591 {
1592 auto __from = __first._M_cur;
1593 ptrdiff_t __n;
1594 if (__first._M_node == __last._M_node)
1595 __n = __last._M_cur - __from;
1596 else
1597 __n = __first._M_last - __from;
1598 __n = std::min<ptrdiff_t>(__n, __result._M_last - __result._M_cur);
1599 std::uninitialized_copy(__from, __from + __n, __result._M_cur);
1600 __first += __n;
1601 __result += __n;
1602 }
1603 return __result;
1604 }
1605
1606 template<typename _Iter, typename _OTp, typename _Tp>
1607 _GLIBCXX26_CONSTEXPR
1608 __enable_if_t<__is_random_access_iter<_Iter>::value,
1609 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>>
1610 __uninitialized_copy_a(_Iter __first, _Iter __last,
1611 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result,
1613 {
1614 // In order to unwind all initialized elements, we just use the default
1615 // implementation if construction can throw.
1616 if constexpr (!__is_nothrow_constructible(_OTp, decltype(*__first)))
1617 return std::__do_uninit_copy(__first, __last, __result);
1618 else
1619 while (__first != __last)
1620 {
1621 auto __n = std::min<ptrdiff_t>(__last - __first,
1622 __result._M_last - __result._M_cur);
1623 std::uninitialized_copy(__first, __first + __n, __result._M_cur);
1624 __first += __n;
1625 __result += __n;
1626 }
1627 return __result;
1628 }
1629
1630 template<typename _ITp, typename _IRef, typename _IPtr, typename _OTp,
1631 typename _Tp>
1632 _GLIBCXX26_CONSTEXPR
1633 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>
1634 __uninitialized_move_a(
1635 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first,
1636 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last,
1637 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result,
1639 {
1640 // In order to unwind all initialized elements, we just use the default
1641 // implementation if construction can throw.
1642 if constexpr (!__is_nothrow_constructible(_OTp,
1643 decltype(std::move(*__first))))
1644 return std::uninitialized_copy(std::make_move_iterator(__first),
1645 std::make_move_iterator(__last),
1646 __result);
1647 else
1648 while (__first != __last)
1649 {
1650 auto __from = __first._M_cur;
1651 ptrdiff_t __n;
1652 if (__first._M_node == __last._M_node)
1653 __n = __last._M_cur - __from;
1654 else
1655 __n = __first._M_last - __from;
1656 __n = std::min<ptrdiff_t>(__n, __result._M_last - __result._M_cur);
1657 std::uninitialized_copy(std::make_move_iterator(__from),
1658 std::make_move_iterator(__from + __n),
1659 __result._M_cur);
1660 __first += __n;
1661 __result += __n;
1662 }
1663 return __result;
1664 }
1665#pragma GCC diagnostic pop
1666#endif // C++11
1667
1668_GLIBCXX_END_NAMESPACE_VERSION
1669} // namespace std
1670
1671#endif
constexpr _ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Copies the range [first,last) into result.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
constexpr insert_iterator< _Container > inserter(_Container &__x, std::__detail::__range_iter_t< _Container > __i)
ISO C++ entities toplevel namespace is std.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
constexpr auto cend(const _Container &__cont) noexcept(noexcept(std::end(__cont))) -> decltype(std::end(__cont))
Return an iterator pointing to one past the last element of the const container.
constexpr auto end(_Container &__cont) noexcept(noexcept(__cont.end())) -> decltype(__cont.end())
Return an iterator pointing to one past the last element of the container.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
constexpr auto cbegin(const _Container &__cont) noexcept(noexcept(std::begin(__cont))) -> decltype(std::begin(__cont))
Return an iterator pointing to the first element of the const container.
constexpr void _Destroy(_ForwardIterator __first, _ForwardIterator __last)
constexpr auto begin(_Container &__cont) noexcept(noexcept(__cont.begin())) -> decltype(__cont.begin())
Return an iterator pointing to the first element of the container.
The standard allocator, as per C++03 [20.4.1].
Definition allocator.h:134
Basis for explicit traits specializations.
Provides input iterator semantics for streambufs.
A standard container using fixed-size memory allocation and constant-time manipulation of elements at...
Definition stl_deque.h:854
constexpr void push_front(const value_type &__x)
Add data to the front of the deque.
Definition stl_deque.h:1642
constexpr void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
Memory-handling helpers for the major map.
Definition deque.tcc:1121
constexpr void _M_reserve_map_at_front(size_type __nodes_to_add=1)
Memory-handling helpers for the major map.
Definition stl_deque.h:2396
constexpr void _M_new_elements_at_back(size_type __new_elements)
Memory-handling helpers for the previous internal insert functions.
Definition deque.tcc:1096
constexpr size_type max_size() const noexcept
Definition stl_deque.h:1414
constexpr void _M_reserve_map_at_back(size_type __nodes_to_add=1)
Memory-handling helpers for the major map.
Definition stl_deque.h:2388
constexpr void _M_pop_front_aux()
Helper functions for push_* and pop_*.
Definition deque.tcc:586
constexpr void _M_fill_initialize(const value_type &__value)
Fills the deque with copies of value.
Definition deque.tcc:401
constexpr size_type size() const noexcept
Definition stl_deque.h:1403
constexpr void _M_range_initialize(_InputIterator __first, _InputIterator __last, std::input_iterator_tag)
Fills the deque with whatever is in [first,last).
Definition deque.tcc:427
constexpr void _M_new_elements_at_front(size_type __new_elements)
Memory-handling helpers for the previous internal insert functions.
Definition deque.tcc:1071
constexpr deque & operator=(const deque &__x)
Deque assignment operator.
Definition deque.tcc:97
deque()=default
Creates a deque with no elements.
constexpr void push_back(const value_type &__x)
Add data to the end of the deque.
Definition stl_deque.h:1679
constexpr iterator end() noexcept
Definition stl_deque.h:1305
constexpr void _M_pop_back_aux()
Helper functions for push_* and pop_*.
Definition deque.tcc:569
constexpr void clear() noexcept
Definition stl_deque.h:2008
constexpr allocator_type get_allocator() const noexcept
Get a copy of the memory allocation object.
Definition stl_deque.h:1276
constexpr iterator begin() noexcept
Definition stl_deque.h:1286
constexpr void _M_push_front_aux(_Args &&... __args)
Helper functions for push_* and pop_*.
Definition deque.tcc:531
constexpr iterator insert(const_iterator __position, const value_type &__x)
Inserts given value into deque before specified iterator.
Definition deque.tcc:217
constexpr iterator emplace(const_iterator __position, _Args &&... __args)
Inserts an object in deque before specified iterator.
Definition deque.tcc:192
constexpr void _M_push_back_aux(_Args &&... __args)
Helper functions for push_* and pop_*.
Definition deque.tcc:492
Marking input iterators.
Forward iterators support a superset of input iterator operations.
Random-access iterators support a superset of bidirectional iterator operations.
Common iterator class.
[range.sized] The sized_range concept.
A range for which ranges::begin returns a forward iterator.
A range for which ranges::begin returns a random access iterator.
A range for which ranges::begin and ranges::end return the same type.