]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/deque.tcc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / deque.tcc
CommitLineData
c4f49014 1// Deque implementation (out of line) -*- C++ -*-
2
fbd26352 3// Copyright (C) 2001-2019 Free Software Foundation, Inc.
c4f49014 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
6bc9506f 8// Free Software Foundation; either version 3, or (at your option)
c4f49014 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
6bc9506f 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.
c4f49014 19
6bc9506f 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/>.
c4f49014 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
5846aeac 51/** @file bits/deque.tcc
c4f49014 52 * This is an internal header file, included by other library headers.
5846aeac 53 * Do not attempt to use it directly. @headername{deque}
c4f49014 54 */
55
5a64d8cf 56#ifndef _DEQUE_TCC
57#define _DEQUE_TCC 1
c4f49014 58
2948dd21 59namespace std _GLIBCXX_VISIBILITY(default)
60{
ae6a4ce9 61_GLIBCXX_BEGIN_NAMESPACE_VERSION
2948dd21 62_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
1069247d 63
0c8766b1 64#if __cplusplus >= 201103L
6b5322d5 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
32bb2cd7 91 template <typename _Tp, typename _Alloc>
aab88dda 92 deque<_Tp, _Alloc>&
93 deque<_Tp, _Alloc>::
32bb2cd7 94 operator=(const deque& __x)
c4f49014 95 {
32bb2cd7 96 if (&__x != this)
b9156b5c 97 {
65d8ffc2 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();
b9156b5c 116 if (__len >= __x.size())
a67a968a 117 _M_erase_at_end(std::copy(__x.begin(), __x.end(),
118 this->_M_impl._M_start));
b9156b5c 119 else
120 {
121 const_iterator __mid = __x.begin() + difference_type(__len);
43f65741 122 std::copy(__x.begin(), __mid, this->_M_impl._M_start);
caa5d563 123 _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(),
124 std::random_access_iterator_tag());
b9156b5c 125 }
126 }
32bb2cd7 127 return *this;
bae9b8af 128 }
129
0c8766b1 130#if __cplusplus >= 201103L
31efd5aa 131 template<typename _Tp, typename _Alloc>
132 template<typename... _Args>
72b02400 133#if __cplusplus > 201402L
134 typename deque<_Tp, _Alloc>::reference
135#else
31efd5aa 136 void
72b02400 137#endif
31efd5aa 138 deque<_Tp, _Alloc>::
139 emplace_front(_Args&&... __args)
140 {
141 if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
142 {
65d8ffc2 143 _Alloc_traits::construct(this->_M_impl,
144 this->_M_impl._M_start._M_cur - 1,
145 std::forward<_Args>(__args)...);
31efd5aa 146 --this->_M_impl._M_start._M_cur;
147 }
148 else
149 _M_push_front_aux(std::forward<_Args>(__args)...);
72b02400 150#if __cplusplus > 201402L
151 return front();
152#endif
31efd5aa 153 }
154
155 template<typename _Tp, typename _Alloc>
156 template<typename... _Args>
72b02400 157#if __cplusplus > 201402L
158 typename deque<_Tp, _Alloc>::reference
159#else
31efd5aa 160 void
72b02400 161#endif
31efd5aa 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 {
65d8ffc2 168 _Alloc_traits::construct(this->_M_impl,
169 this->_M_impl._M_finish._M_cur,
170 std::forward<_Args>(__args)...);
31efd5aa 171 ++this->_M_impl._M_finish._M_cur;
172 }
173 else
174 _M_push_back_aux(std::forward<_Args>(__args)...);
72b02400 175#if __cplusplus > 201402L
176 return back();
177#endif
31efd5aa 178 }
179#endif
180
0c8766b1 181#if __cplusplus >= 201103L
d1fd9d50 182 template<typename _Tp, typename _Alloc>
183 template<typename... _Args>
184 typename deque<_Tp, _Alloc>::iterator
185 deque<_Tp, _Alloc>::
3d2b2f49 186 emplace(const_iterator __position, _Args&&... __args)
d1fd9d50 187 {
188 if (__position._M_cur == this->_M_impl._M_start._M_cur)
189 {
b6b2334e 190 emplace_front(std::forward<_Args>(__args)...);
d1fd9d50 191 return this->_M_impl._M_start;
192 }
193 else if (__position._M_cur == this->_M_impl._M_finish._M_cur)
194 {
b6b2334e 195 emplace_back(std::forward<_Args>(__args)...);
d1fd9d50 196 iterator __tmp = this->_M_impl._M_finish;
197 --__tmp;
198 return __tmp;
199 }
200 else
3d2b2f49 201 return _M_insert_aux(__position._M_const_cast(),
202 std::forward<_Args>(__args)...);
d1fd9d50 203 }
204#endif
205
3d2b2f49 206 template <typename _Tp, typename _Alloc>
207 typename deque<_Tp, _Alloc>::iterator
208 deque<_Tp, _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
32bb2cd7 231 template <typename _Tp, typename _Alloc>
aab88dda 232 typename deque<_Tp, _Alloc>::iterator
9380d281 233 deque<_Tp, _Alloc>::
6b0e18ca 234 _M_erase(iterator __position)
c4f49014 235 {
32bb2cd7 236 iterator __next = __position;
237 ++__next;
93304f99 238 const difference_type __index = __position - begin();
239 if (static_cast<size_type>(__index) < (size() >> 1))
b9156b5c 240 {
a67a968a 241 if (__position != begin())
2adb675d 242 _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next);
b9156b5c 243 pop_front();
244 }
32bb2cd7 245 else
b9156b5c 246 {
a67a968a 247 if (__next != end())
2adb675d 248 _GLIBCXX_MOVE3(__next, end(), __position);
b9156b5c 249 pop_back();
250 }
a67a968a 251 return begin() + __index;
32bb2cd7 252 }
bae9b8af 253
32bb2cd7 254 template <typename _Tp, typename _Alloc>
aab88dda 255 typename deque<_Tp, _Alloc>::iterator
9380d281 256 deque<_Tp, _Alloc>::
6b0e18ca 257 _M_erase(iterator __first, iterator __last)
c4f49014 258 {
b07725b5 259 if (__first == __last)
260 return __first;
261 else if (__first == begin() && __last == end())
b9156b5c 262 {
263 clear();
a67a968a 264 return end();
b9156b5c 265 }
32bb2cd7 266 else
b9156b5c 267 {
268 const difference_type __n = __last - __first;
a67a968a 269 const difference_type __elems_before = __first - begin();
c04e7aaf 270 if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2)
b9156b5c 271 {
a67a968a 272 if (__first != begin())
2adb675d 273 _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last);
a67a968a 274 _M_erase_at_begin(begin() + __n);
b9156b5c 275 }
276 else
277 {
a67a968a 278 if (__last != end())
2adb675d 279 _GLIBCXX_MOVE3(__last, end(), __first);
a67a968a 280 _M_erase_at_end(end() - __n);
b9156b5c 281 }
a67a968a 282 return begin() + __elems_before;
b9156b5c 283 }
32bb2cd7 284 }
bae9b8af 285
32bb2cd7 286 template <typename _Tp, class _Alloc>
c03ec9b9 287 template <typename _InputIterator>
32bb2cd7 288 void
56c33711 289 deque<_Tp, _Alloc>::
290 _M_assign_aux(_InputIterator __first, _InputIterator __last,
291 std::input_iterator_tag)
c4f49014 292 {
32bb2cd7 293 iterator __cur = begin();
b63a0dff 294 for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
32bb2cd7 295 *__cur = *__first;
296 if (__first == __last)
a67a968a 297 _M_erase_at_end(__cur);
32bb2cd7 298 else
caa5d563 299 _M_range_insert_aux(end(), __first, __last,
300 std::__iterator_category(__first));
c4f49014 301 }
bae9b8af 302
32bb2cd7 303 template <typename _Tp, typename _Alloc>
c4f49014 304 void
9380d281 305 deque<_Tp, _Alloc>::
32bb2cd7 306 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
c4f49014 307 {
43f65741 308 if (__pos._M_cur == this->_M_impl._M_start._M_cur)
b9156b5c 309 {
310 iterator __new_start = _M_reserve_elements_at_front(__n);
b1a09c64 311 __try
b9156b5c 312 {
e1d16db9 313 std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
93304f99 314 __x, _M_get_Tp_allocator());
43f65741 315 this->_M_impl._M_start = __new_start;
b9156b5c 316 }
b1a09c64 317 __catch(...)
b9156b5c 318 {
e58f24c0 319 _M_destroy_nodes(__new_start._M_node,
320 this->_M_impl._M_start._M_node);
b9156b5c 321 __throw_exception_again;
322 }
323 }
43f65741 324 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
b9156b5c 325 {
326 iterator __new_finish = _M_reserve_elements_at_back(__n);
b1a09c64 327 __try
b9156b5c 328 {
e1d16db9 329 std::__uninitialized_fill_a(this->_M_impl._M_finish,
330 __new_finish, __x,
171a395a 331 _M_get_Tp_allocator());
43f65741 332 this->_M_impl._M_finish = __new_finish;
b9156b5c 333 }
b1a09c64 334 __catch(...)
b9156b5c 335 {
43f65741 336 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
bae9b8af 337 __new_finish._M_node + 1);
b9156b5c 338 __throw_exception_again;
339 }
340 }
bae9b8af 341 else
32bb2cd7 342 _M_insert_aux(__pos, __n, __x);
c4f49014 343 }
bae9b8af 344
0c8766b1 345#if __cplusplus >= 201103L
6b5322d5 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 }
775d377d 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 }
6b5322d5 387#endif
388
32bb2cd7 389 template <typename _Tp, typename _Alloc>
390 void
9380d281 391 deque<_Tp, _Alloc>::
32bb2cd7 392 _M_fill_initialize(const value_type& __value)
c4f49014 393 {
32bb2cd7 394 _Map_pointer __cur;
b1a09c64 395 __try
32bb2cd7 396 {
43f65741 397 for (__cur = this->_M_impl._M_start._M_node;
398 __cur < this->_M_impl._M_finish._M_node;
954ad420 399 ++__cur)
40d1ee2b 400 std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
171a395a 401 __value, _M_get_Tp_allocator());
e1d16db9 402 std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
403 this->_M_impl._M_finish._M_cur,
171a395a 404 __value, _M_get_Tp_allocator());
32bb2cd7 405 }
b1a09c64 406 __catch(...)
32bb2cd7 407 {
e1d16db9 408 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
171a395a 409 _M_get_Tp_allocator());
32bb2cd7 410 __throw_exception_again;
411 }
c4f49014 412 }
bae9b8af 413
32bb2cd7 414 template <typename _Tp, typename _Alloc>
415 template <typename _InputIterator>
416 void
9380d281 417 deque<_Tp, _Alloc>::
32bb2cd7 418 _M_range_initialize(_InputIterator __first, _InputIterator __last,
be7e699b 419 std::input_iterator_tag)
32bb2cd7 420 {
979a0450 421 this->_M_initialize_map(0);
b1a09c64 422 __try
32bb2cd7 423 {
9380d281 424 for (; __first != __last; ++__first)
8ddeb59a 425#if __cplusplus >= 201103L
426 emplace_back(*__first);
427#else
32bb2cd7 428 push_back(*__first);
8ddeb59a 429#endif
32bb2cd7 430 }
b1a09c64 431 __catch(...)
32bb2cd7 432 {
433 clear();
434 __throw_exception_again;
435 }
436 }
bae9b8af 437
32bb2cd7 438 template <typename _Tp, typename _Alloc>
439 template <typename _ForwardIterator>
440 void
9380d281 441 deque<_Tp, _Alloc>::
32bb2cd7 442 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
be7e699b 443 std::forward_iterator_tag)
32bb2cd7 444 {
b9156b5c 445 const size_type __n = std::distance(__first, __last);
2e0303d6 446 this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator()));
bae9b8af 447
32bb2cd7 448 _Map_pointer __cur_node;
b1a09c64 449 __try
32bb2cd7 450 {
43f65741 451 for (__cur_node = this->_M_impl._M_start._M_node;
452 __cur_node < this->_M_impl._M_finish._M_node;
32bb2cd7 453 ++__cur_node)
ab0da029 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 }
e1d16db9 461 std::__uninitialized_copy_a(__first, __last,
462 this->_M_impl._M_finish._M_first,
171a395a 463 _M_get_Tp_allocator());
32bb2cd7 464 }
b1a09c64 465 __catch(...)
32bb2cd7 466 {
e58f24c0 467 std::_Destroy(this->_M_impl._M_start,
e1d16db9 468 iterator(*__cur_node, __cur_node),
171a395a 469 _M_get_Tp_allocator());
32bb2cd7 470 __throw_exception_again;
471 }
472 }
bae9b8af 473
43f65741 474 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
d1fd9d50 475 template<typename _Tp, typename _Alloc>
0c8766b1 476#if __cplusplus >= 201103L
d1fd9d50 477 template<typename... _Args>
478 void
479 deque<_Tp, _Alloc>::
480 _M_push_back_aux(_Args&&... __args)
d1fd9d50 481#else
482 void
483 deque<_Tp, _Alloc>::
484 _M_push_back_aux(const value_type& __t)
d1fd9d50 485#endif
431d9495 486 {
2e0303d6 487 if (size() == max_size())
488 __throw_length_error(
489 __N("cannot create std::deque larger than max_size()"));
490
d1fd9d50 491 _M_reserve_map_at_back();
492 *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node();
b1a09c64 493 __try
d1fd9d50 494 {
0c8766b1 495#if __cplusplus >= 201103L
65d8ffc2 496 _Alloc_traits::construct(this->_M_impl,
497 this->_M_impl._M_finish._M_cur,
498 std::forward<_Args>(__args)...);
431d9495 499#else
500 this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
501#endif
d1fd9d50 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 }
b1a09c64 506 __catch(...)
d1fd9d50 507 {
508 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
509 __throw_exception_again;
510 }
511 }
bae9b8af 512
43f65741 513 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first.
d1fd9d50 514 template<typename _Tp, typename _Alloc>
0c8766b1 515#if __cplusplus >= 201103L
d1fd9d50 516 template<typename... _Args>
517 void
518 deque<_Tp, _Alloc>::
519 _M_push_front_aux(_Args&&... __args)
d1fd9d50 520#else
521 void
522 deque<_Tp, _Alloc>::
523 _M_push_front_aux(const value_type& __t)
d1fd9d50 524#endif
431d9495 525 {
2e0303d6 526 if (size() == max_size())
527 __throw_length_error(
528 __N("cannot create std::deque larger than max_size()"));
529
d1fd9d50 530 _M_reserve_map_at_front();
531 *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
b1a09c64 532 __try
d1fd9d50 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;
0c8766b1 537#if __cplusplus >= 201103L
65d8ffc2 538 _Alloc_traits::construct(this->_M_impl,
539 this->_M_impl._M_start._M_cur,
540 std::forward<_Args>(__args)...);
431d9495 541#else
542 this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
543#endif
d1fd9d50 544 }
b1a09c64 545 __catch(...)
d1fd9d50 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 }
bae9b8af 552
43f65741 553 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first.
32bb2cd7 554 template <typename _Tp, typename _Alloc>
9380d281 555 void deque<_Tp, _Alloc>::
32bb2cd7 556 _M_pop_back_aux()
557 {
43f65741 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;
65d8ffc2 561 _Alloc_traits::destroy(_M_get_Tp_allocator(),
562 this->_M_impl._M_finish._M_cur);
c4f49014 563 }
bae9b8af 564
e58f24c0 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.
32bb2cd7 570 template <typename _Tp, typename _Alloc>
9380d281 571 void deque<_Tp, _Alloc>::
32bb2cd7 572 _M_pop_front_aux()
573 {
65d8ffc2 574 _Alloc_traits::destroy(_M_get_Tp_allocator(),
575 this->_M_impl._M_start._M_cur);
43f65741 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;
bae9b8af 579 }
580
32bb2cd7 581 template <typename _Tp, typename _Alloc>
582 template <typename _InputIterator>
583 void
9380d281 584 deque<_Tp, _Alloc>::
32bb2cd7 585 _M_range_insert_aux(iterator __pos,
586 _InputIterator __first, _InputIterator __last,
be7e699b 587 std::input_iterator_tag)
b9156b5c 588 { std::copy(__first, __last, std::inserter(*this, __pos)); }
bae9b8af 589
32bb2cd7 590 template <typename _Tp, typename _Alloc>
591 template <typename _ForwardIterator>
592 void
9380d281 593 deque<_Tp, _Alloc>::
32bb2cd7 594 _M_range_insert_aux(iterator __pos,
595 _ForwardIterator __first, _ForwardIterator __last,
be7e699b 596 std::forward_iterator_tag)
32bb2cd7 597 {
9380d281 598 const size_type __n = std::distance(__first, __last);
43f65741 599 if (__pos._M_cur == this->_M_impl._M_start._M_cur)
b9156b5c 600 {
601 iterator __new_start = _M_reserve_elements_at_front(__n);
b1a09c64 602 __try
b9156b5c 603 {
e1d16db9 604 std::__uninitialized_copy_a(__first, __last, __new_start,
171a395a 605 _M_get_Tp_allocator());
43f65741 606 this->_M_impl._M_start = __new_start;
b9156b5c 607 }
b1a09c64 608 __catch(...)
b9156b5c 609 {
e58f24c0 610 _M_destroy_nodes(__new_start._M_node,
611 this->_M_impl._M_start._M_node);
b9156b5c 612 __throw_exception_again;
613 }
614 }
43f65741 615 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
b9156b5c 616 {
617 iterator __new_finish = _M_reserve_elements_at_back(__n);
b1a09c64 618 __try
b9156b5c 619 {
e1d16db9 620 std::__uninitialized_copy_a(__first, __last,
621 this->_M_impl._M_finish,
171a395a 622 _M_get_Tp_allocator());
43f65741 623 this->_M_impl._M_finish = __new_finish;
b9156b5c 624 }
b1a09c64 625 __catch(...)
b9156b5c 626 {
43f65741 627 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
b9156b5c 628 __new_finish._M_node + 1);
629 __throw_exception_again;
630 }
631 }
32bb2cd7 632 else
633 _M_insert_aux(__pos, __first, __last, __n);
634 }
bae9b8af 635
d1fd9d50 636 template<typename _Tp, typename _Alloc>
0c8766b1 637#if __cplusplus >= 201103L
d1fd9d50 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
32bb2cd7 645 typename deque<_Tp, _Alloc>::iterator
d1fd9d50 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 }
bae9b8af 677
32bb2cd7 678 template <typename _Tp, typename _Alloc>
c4f49014 679 void
9380d281 680 deque<_Tp, _Alloc>::
32bb2cd7 681 _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
c4f49014 682 {
43f65741 683 const difference_type __elems_before = __pos - this->_M_impl._M_start;
9380d281 684 const size_type __length = this->size();
32bb2cd7 685 value_type __x_copy = __x;
686 if (__elems_before < difference_type(__length / 2))
b9156b5c 687 {
688 iterator __new_start = _M_reserve_elements_at_front(__n);
43f65741 689 iterator __old_start = this->_M_impl._M_start;
690 __pos = this->_M_impl._M_start + __elems_before;
b1a09c64 691 __try
b9156b5c 692 {
693 if (__elems_before >= difference_type(__n))
694 {
e58f24c0 695 iterator __start_n = (this->_M_impl._M_start
696 + difference_type(__n));
d1fd9d50 697 std::__uninitialized_move_a(this->_M_impl._M_start,
40d1ee2b 698 __start_n, __new_start,
171a395a 699 _M_get_Tp_allocator());
43f65741 700 this->_M_impl._M_start = __new_start;
d1fd9d50 701 _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
93304f99 702 std::fill(__pos - difference_type(__n), __pos, __x_copy);
b9156b5c 703 }
704 else
705 {
d1fd9d50 706 std::__uninitialized_move_fill(this->_M_impl._M_start,
e58f24c0 707 __pos, __new_start,
708 this->_M_impl._M_start,
e1d16db9 709 __x_copy,
171a395a 710 _M_get_Tp_allocator());
43f65741 711 this->_M_impl._M_start = __new_start;
b9156b5c 712 std::fill(__old_start, __pos, __x_copy);
713 }
714 }
b1a09c64 715 __catch(...)
bae9b8af 716 {
e58f24c0 717 _M_destroy_nodes(__new_start._M_node,
718 this->_M_impl._M_start._M_node);
b9156b5c 719 __throw_exception_again;
720 }
721 }
c4f49014 722 else
b9156b5c 723 {
724 iterator __new_finish = _M_reserve_elements_at_back(__n);
43f65741 725 iterator __old_finish = this->_M_impl._M_finish;
bae9b8af 726 const difference_type __elems_after =
b9156b5c 727 difference_type(__length) - __elems_before;
43f65741 728 __pos = this->_M_impl._M_finish - __elems_after;
b1a09c64 729 __try
b9156b5c 730 {
731 if (__elems_after > difference_type(__n))
732 {
e58f24c0 733 iterator __finish_n = (this->_M_impl._M_finish
734 - difference_type(__n));
d1fd9d50 735 std::__uninitialized_move_a(__finish_n,
40d1ee2b 736 this->_M_impl._M_finish,
e1d16db9 737 this->_M_impl._M_finish,
171a395a 738 _M_get_Tp_allocator());
43f65741 739 this->_M_impl._M_finish = __new_finish;
d1fd9d50 740 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
b9156b5c 741 std::fill(__pos, __pos + difference_type(__n), __x_copy);
742 }
743 else
744 {
d1fd9d50 745 std::__uninitialized_fill_move(this->_M_impl._M_finish,
b9156b5c 746 __pos + difference_type(__n),
747 __x_copy, __pos,
e1d16db9 748 this->_M_impl._M_finish,
171a395a 749 _M_get_Tp_allocator());
43f65741 750 this->_M_impl._M_finish = __new_finish;
b9156b5c 751 std::fill(__pos, __old_finish, __x_copy);
752 }
753 }
b1a09c64 754 __catch(...)
bae9b8af 755 {
43f65741 756 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
b9156b5c 757 __new_finish._M_node + 1);
758 __throw_exception_again;
759 }
760 }
c4f49014 761 }
bae9b8af 762
32bb2cd7 763 template <typename _Tp, typename _Alloc>
764 template <typename _ForwardIterator>
765 void
9380d281 766 deque<_Tp, _Alloc>::
32bb2cd7 767 _M_insert_aux(iterator __pos,
768 _ForwardIterator __first, _ForwardIterator __last,
769 size_type __n)
c4f49014 770 {
43f65741 771 const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
9380d281 772 const size_type __length = size();
32bb2cd7 773 if (static_cast<size_type>(__elemsbefore) < __length / 2)
b9156b5c 774 {
775 iterator __new_start = _M_reserve_elements_at_front(__n);
43f65741 776 iterator __old_start = this->_M_impl._M_start;
777 __pos = this->_M_impl._M_start + __elemsbefore;
b1a09c64 778 __try
b9156b5c 779 {
780 if (__elemsbefore >= difference_type(__n))
781 {
e58f24c0 782 iterator __start_n = (this->_M_impl._M_start
783 + difference_type(__n));
d1fd9d50 784 std::__uninitialized_move_a(this->_M_impl._M_start,
40d1ee2b 785 __start_n, __new_start,
171a395a 786 _M_get_Tp_allocator());
43f65741 787 this->_M_impl._M_start = __new_start;
d1fd9d50 788 _GLIBCXX_MOVE3(__start_n, __pos, __old_start);
b9156b5c 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);
d1fd9d50 795 std::__uninitialized_move_copy(this->_M_impl._M_start,
e58f24c0 796 __pos, __first, __mid,
e1d16db9 797 __new_start,
171a395a 798 _M_get_Tp_allocator());
43f65741 799 this->_M_impl._M_start = __new_start;
b9156b5c 800 std::copy(__mid, __last, __old_start);
801 }
802 }
b1a09c64 803 __catch(...)
b9156b5c 804 {
e58f24c0 805 _M_destroy_nodes(__new_start._M_node,
806 this->_M_impl._M_start._M_node);
b9156b5c 807 __throw_exception_again;
808 }
809 }
32bb2cd7 810 else
811 {
812 iterator __new_finish = _M_reserve_elements_at_back(__n);
43f65741 813 iterator __old_finish = this->_M_impl._M_finish;
bae9b8af 814 const difference_type __elemsafter =
32bb2cd7 815 difference_type(__length) - __elemsbefore;
43f65741 816 __pos = this->_M_impl._M_finish - __elemsafter;
b1a09c64 817 __try
32bb2cd7 818 {
819 if (__elemsafter > difference_type(__n))
b9156b5c 820 {
e58f24c0 821 iterator __finish_n = (this->_M_impl._M_finish
822 - difference_type(__n));
d1fd9d50 823 std::__uninitialized_move_a(__finish_n,
e1d16db9 824 this->_M_impl._M_finish,
825 this->_M_impl._M_finish,
171a395a 826 _M_get_Tp_allocator());
43f65741 827 this->_M_impl._M_finish = __new_finish;
d1fd9d50 828 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
b9156b5c 829 std::copy(__first, __last, __pos);
830 }
32bb2cd7 831 else
b9156b5c 832 {
833 _ForwardIterator __mid = __first;
834 std::advance(__mid, __elemsafter);
d1fd9d50 835 std::__uninitialized_copy_move(__mid, __last, __pos,
43f65741 836 this->_M_impl._M_finish,
e1d16db9 837 this->_M_impl._M_finish,
171a395a 838 _M_get_Tp_allocator());
43f65741 839 this->_M_impl._M_finish = __new_finish;
b9156b5c 840 std::copy(__first, __mid, __pos);
841 }
32bb2cd7 842 }
b1a09c64 843 __catch(...)
32bb2cd7 844 {
43f65741 845 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
954ad420 846 __new_finish._M_node + 1);
32bb2cd7 847 __throw_exception_again;
848 }
849 }
c4f49014 850 }
bae9b8af 851
a67a968a 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
32bb2cd7 874 template <typename _Tp, typename _Alloc>
875 void
9380d281 876 deque<_Tp, _Alloc>::
32bb2cd7 877 _M_new_elements_at_front(size_type __new_elems)
878 {
ab0da029 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());
32bb2cd7 884 _M_reserve_map_at_front(__new_nodes);
885 size_type __i;
b1a09c64 886 __try
32bb2cd7 887 {
888 for (__i = 1; __i <= __new_nodes; ++__i)
43f65741 889 *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node();
32bb2cd7 890 }
b1a09c64 891 __catch(...)
32bb2cd7 892 {
893 for (size_type __j = 1; __j < __i; ++__j)
43f65741 894 _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
32bb2cd7 895 __throw_exception_again;
896 }
897 }
bae9b8af 898
32bb2cd7 899 template <typename _Tp, typename _Alloc>
900 void
9380d281 901 deque<_Tp, _Alloc>::
32bb2cd7 902 _M_new_elements_at_back(size_type __new_elems)
903 {
ab0da029 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());
32bb2cd7 909 _M_reserve_map_at_back(__new_nodes);
910 size_type __i;
b1a09c64 911 __try
32bb2cd7 912 {
913 for (__i = 1; __i <= __new_nodes; ++__i)
43f65741 914 *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node();
32bb2cd7 915 }
b1a09c64 916 __catch(...)
32bb2cd7 917 {
918 for (size_type __j = 1; __j < __i; ++__j)
43f65741 919 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
32bb2cd7 920 __throw_exception_again;
921 }
922 }
bae9b8af 923
32bb2cd7 924 template <typename _Tp, typename _Alloc>
925 void
9380d281 926 deque<_Tp, _Alloc>::
32bb2cd7 927 _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
928 {
9380d281 929 const size_type __old_num_nodes
43f65741 930 = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1;
9380d281 931 const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
bae9b8af 932
32bb2cd7 933 _Map_pointer __new_nstart;
43f65741 934 if (this->_M_impl._M_map_size > 2 * __new_num_nodes)
b9156b5c 935 {
43f65741 936 __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
bae9b8af 937 - __new_num_nodes) / 2
b9156b5c 938 + (__add_at_front ? __nodes_to_add : 0);
43f65741 939 if (__new_nstart < this->_M_impl._M_start._M_node)
940 std::copy(this->_M_impl._M_start._M_node,
ab0da029 941 this->_M_impl._M_finish._M_node + 1,
942 __new_nstart);
b9156b5c 943 else
43f65741 944 std::copy_backward(this->_M_impl._M_start._M_node,
945 this->_M_impl._M_finish._M_node + 1,
b9156b5c 946 __new_nstart + __old_num_nodes);
947 }
32bb2cd7 948 else
b9156b5c 949 {
43f65741 950 size_type __new_map_size = this->_M_impl._M_map_size
951 + std::max(this->_M_impl._M_map_size,
b9156b5c 952 __nodes_to_add) + 2;
bae9b8af 953
b9156b5c 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);
43f65741 957 std::copy(this->_M_impl._M_start._M_node,
958 this->_M_impl._M_finish._M_node + 1,
b9156b5c 959 __new_nstart);
43f65741 960 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
bae9b8af 961
43f65741 962 this->_M_impl._M_map = __new_map;
963 this->_M_impl._M_map_size = __new_map_size;
b9156b5c 964 }
bae9b8af 965
43f65741 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);
c4f49014 968 }
1069247d 969
8f471b51 970 // Overload for deque::iterators, exploiting the "segmented-iterator
c1c29a39 971 // optimization".
8f471b51 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
c1c29a39 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;
5e115052 999 typedef typename _Self::difference_type difference_type;
c1c29a39 1000
5e115052 1001 difference_type __len = __last - __first;
c1c29a39 1002 while (__len > 0)
1003 {
5e115052 1004 const difference_type __clen
c1c29a39 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
5e115052 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
0c8766b1 1054#if __cplusplus >= 201103L
c1c29a39 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;
5e115052 1062 typedef typename _Self::difference_type difference_type;
c1c29a39 1063
5e115052 1064 difference_type __len = __last - __first;
c1c29a39 1065 while (__len > 0)
1066 {
5e115052 1067 const difference_type __clen
c1c29a39 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 }
5e115052 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 }
c1c29a39 1116#endif
1117
2948dd21 1118_GLIBCXX_END_NAMESPACE_CONTAINER
ae6a4ce9 1119_GLIBCXX_END_NAMESPACE_VERSION
2948dd21 1120} // namespace std
b9156b5c 1121
5a64d8cf 1122#endif