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