1 // Deque implementation (out of line) -*- C++ -*- 2 3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 2, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // You should have received a copy of the GNU General Public License along 18 // with this library; see the file COPYING. If not, write to the Free 19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 // USA. 21 22 // As a special exception, you may use this file as part of a free software 23 // library without restriction. Specifically, if other files instantiate 24 // templates or use macros or inline functions from this file, or you compile 25 // this file and link it with other files to produce an executable, this 26 // file does not by itself cause the resulting executable to be covered by 27 // the GNU General Public License. This exception does not however 28 // invalidate any other reasons why the executable file might be covered by 29 // the GNU General Public License. 30 31 /* 32 * 33 * Copyright (c) 1994 34 * Hewlett-Packard Company 35 * 36 * Permission to use, copy, modify, distribute and sell this software 37 * and its documentation for any purpose is hereby granted without fee, 38 * provided that the above copyright notice appear in all copies and 39 * that both that copyright notice and this permission notice appear 40 * in supporting documentation. Hewlett-Packard Company makes no 41 * representations about the suitability of this software for any 42 * purpose. It is provided "as is" without express or implied warranty. 43 * 44 * 45 * Copyright (c) 1997 46 * Silicon Graphics Computer Systems, Inc. 47 * 48 * Permission to use, copy, modify, distribute and sell this software 49 * and its documentation for any purpose is hereby granted without fee, 50 * provided that the above copyright notice appear in all copies and 51 * that both that copyright notice and this permission notice appear 52 * in supporting documentation. Silicon Graphics makes no 53 * representations about the suitability of this software for any 54 * purpose. It is provided "as is" without express or implied warranty. 55 */ 56 57 /** @file deque.tcc 58 * This is an internal header file, included by other library headers. 59 * You should not attempt to use it directly. 60 */ 61 62 #ifndef _DEQUE_TCC 63 #define _DEQUE_TCC 1 64 65 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) 66 67 template <typename _Tp, typename _Alloc> 68 deque<_Tp, _Alloc>& 69 deque<_Tp, _Alloc>:: 70 operator=(const deque& __x) 71 { 72 const size_type __len = size(); 73 if (&__x != this) 74 { 75 if (__len >= __x.size()) 76 _M_erase_at_end(std::copy(__x.begin(), __x.end(), 77 this->_M_impl._M_start)); 78 else 79 { 80 const_iterator __mid = __x.begin() + difference_type(__len); 81 std::copy(__x.begin(), __mid, this->_M_impl._M_start); 82 insert(this->_M_impl._M_finish, __mid, __x.end()); 83 } 84 } 85 return *this; 86 } 87 88 template <typename _Tp, typename _Alloc> 89 typename deque<_Tp, _Alloc>::iterator 90 deque<_Tp, _Alloc>:: 91 insert(iterator __position, const value_type& __x) 92 { 93 if (__position._M_cur == this->_M_impl._M_start._M_cur) 94 { 95 push_front(__x); 96 return this->_M_impl._M_start; 97 } 98 else if (__position._M_cur == this->_M_impl._M_finish._M_cur) 99 { 100 push_back(__x); 101 iterator __tmp = this->_M_impl._M_finish; 102 --__tmp; 103 return __tmp; 104 } 105 else 106 return _M_insert_aux(__position, __x); 107 } 108 109 template <typename _Tp, typename _Alloc> 110 typename deque<_Tp, _Alloc>::iterator 111 deque<_Tp, _Alloc>:: 112 erase(iterator __position) 113 { 114 iterator __next = __position; 115 ++__next; 116 const difference_type __index = __position - begin(); 117 if (static_cast<size_type>(__index) < (size() >> 1)) 118 { 119 if (__position != begin()) 120 std::copy_backward(begin(), __position, __next); 121 pop_front(); 122 } 123 else 124 { 125 if (__next != end()) 126 std::copy(__next, end(), __position); 127 pop_back(); 128 } 129 return begin() + __index; 130 } 131 132 template <typename _Tp, typename _Alloc> 133 typename deque<_Tp, _Alloc>::iterator 134 deque<_Tp, _Alloc>:: 135 erase(iterator __first, iterator __last) 136 { 137 if (__first == begin() && __last == end()) 138 { 139 clear(); 140 return end(); 141 } 142 else 143 { 144 const difference_type __n = __last - __first; 145 const difference_type __elems_before = __first - begin(); 146 if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2) 147 { 148 if (__first != begin()) 149 std::copy_backward(begin(), __first, __last); 150 _M_erase_at_begin(begin() + __n); 151 } 152 else 153 { 154 if (__last != end()) 155 std::copy(__last, end(), __first); 156 _M_erase_at_end(end() - __n); 157 } 158 return begin() + __elems_before; 159 } 160 } 161 162 template <typename _Tp, class _Alloc> 163 template <typename _InputIterator> 164 void 165 deque<_Tp, _Alloc>:: 166 _M_assign_aux(_InputIterator __first, _InputIterator __last, 167 std::input_iterator_tag) 168 { 169 iterator __cur = begin(); 170 for (; __first != __last && __cur != end(); ++__cur, ++__first) 171 *__cur = *__first; 172 if (__first == __last) 173 _M_erase_at_end(__cur); 174 else 175 insert(end(), __first, __last); 176 } 177 178 template <typename _Tp, typename _Alloc> 179 void 180 deque<_Tp, _Alloc>:: 181 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) 182 { 183 if (__pos._M_cur == this->_M_impl._M_start._M_cur) 184 { 185 iterator __new_start = _M_reserve_elements_at_front(__n); 186 try 187 { 188 std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, 189 __x, _M_get_Tp_allocator()); 190 this->_M_impl._M_start = __new_start; 191 } 192 catch(...) 193 { 194 _M_destroy_nodes(__new_start._M_node, 195 this->_M_impl._M_start._M_node); 196 __throw_exception_again; 197 } 198 } 199 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) 200 { 201 iterator __new_finish = _M_reserve_elements_at_back(__n); 202 try 203 { 204 std::__uninitialized_fill_a(this->_M_impl._M_finish, 205 __new_finish, __x, 206 _M_get_Tp_allocator()); 207 this->_M_impl._M_finish = __new_finish; 208 } 209 catch(...) 210 { 211 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 212 __new_finish._M_node + 1); 213 __throw_exception_again; 214 } 215 } 216 else 217 _M_insert_aux(__pos, __n, __x); 218 } 219 220 template <typename _Tp, typename _Alloc> 221 void 222 deque<_Tp, _Alloc>:: 223 _M_fill_initialize(const value_type& __value) 224 { 225 _Map_pointer __cur; 226 try 227 { 228 for (__cur = this->_M_impl._M_start._M_node; 229 __cur < this->_M_impl._M_finish._M_node; 230 ++__cur) 231 std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(), 232 __value, _M_get_Tp_allocator()); 233 std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first, 234 this->_M_impl._M_finish._M_cur, 235 __value, _M_get_Tp_allocator()); 236 } 237 catch(...) 238 { 239 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), 240 _M_get_Tp_allocator()); 241 __throw_exception_again; 242 } 243 } 244 245 template <typename _Tp, typename _Alloc> 246 template <typename _InputIterator> 247 void 248 deque<_Tp, _Alloc>:: 249 _M_range_initialize(_InputIterator __first, _InputIterator __last, 250 std::input_iterator_tag) 251 { 252 this->_M_initialize_map(0); 253 try 254 { 255 for (; __first != __last; ++__first) 256 push_back(*__first); 257 } 258 catch(...) 259 { 260 clear(); 261 __throw_exception_again; 262 } 263 } 264 265 template <typename _Tp, typename _Alloc> 266 template <typename _ForwardIterator> 267 void 268 deque<_Tp, _Alloc>:: 269 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, 270 std::forward_iterator_tag) 271 { 272 const size_type __n = std::distance(__first, __last); 273 this->_M_initialize_map(__n); 274 275 _Map_pointer __cur_node; 276 try 277 { 278 for (__cur_node = this->_M_impl._M_start._M_node; 279 __cur_node < this->_M_impl._M_finish._M_node; 280 ++__cur_node) 281 { 282 _ForwardIterator __mid = __first; 283 std::advance(__mid, _S_buffer_size()); 284 std::__uninitialized_copy_a(__first, __mid, *__cur_node, 285 _M_get_Tp_allocator()); 286 __first = __mid; 287 } 288 std::__uninitialized_copy_a(__first, __last, 289 this->_M_impl._M_finish._M_first, 290 _M_get_Tp_allocator()); 291 } 292 catch(...) 293 { 294 std::_Destroy(this->_M_impl._M_start, 295 iterator(*__cur_node, __cur_node), 296 _M_get_Tp_allocator()); 297 __throw_exception_again; 298 } 299 } 300 301 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. 302 template <typename _Tp, typename _Alloc> 303 void 304 deque<_Tp, _Alloc>:: 305 _M_push_back_aux(const value_type& __t) 306 { 307 value_type __t_copy = __t; 308 _M_reserve_map_at_back(); 309 *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); 310 try 311 { 312 this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t_copy); 313 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node 314 + 1); 315 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; 316 } 317 catch(...) 318 { 319 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); 320 __throw_exception_again; 321 } 322 } 323 324 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. 325 template <typename _Tp, typename _Alloc> 326 void 327 deque<_Tp, _Alloc>:: 328 _M_push_front_aux(const value_type& __t) 329 { 330 value_type __t_copy = __t; 331 _M_reserve_map_at_front(); 332 *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); 333 try 334 { 335 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node 336 - 1); 337 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; 338 this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t_copy); 339 } 340 catch(...) 341 { 342 ++this->_M_impl._M_start; 343 _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); 344 __throw_exception_again; 345 } 346 } 347 348 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. 349 template <typename _Tp, typename _Alloc> 350 void deque<_Tp, _Alloc>:: 351 _M_pop_back_aux() 352 { 353 _M_deallocate_node(this->_M_impl._M_finish._M_first); 354 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); 355 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; 356 this->_M_impl.destroy(this->_M_impl._M_finish._M_cur); 357 } 358 359 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. 360 // Note that if the deque has at least one element (a precondition for this 361 // member function), and if 362 // _M_impl._M_start._M_cur == _M_impl._M_start._M_last, 363 // then the deque must have at least two nodes. 364 template <typename _Tp, typename _Alloc> 365 void deque<_Tp, _Alloc>:: 366 _M_pop_front_aux() 367 { 368 this->_M_impl.destroy(this->_M_impl._M_start._M_cur); 369 _M_deallocate_node(this->_M_impl._M_start._M_first); 370 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); 371 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; 372 } 373 374 template <typename _Tp, typename _Alloc> 375 template <typename _InputIterator> 376 void 377 deque<_Tp, _Alloc>:: 378 _M_range_insert_aux(iterator __pos, 379 _InputIterator __first, _InputIterator __last, 380 std::input_iterator_tag) 381 { std::copy(__first, __last, std::inserter(*this, __pos)); } 382 383 template <typename _Tp, typename _Alloc> 384 template <typename _ForwardIterator> 385 void 386 deque<_Tp, _Alloc>:: 387 _M_range_insert_aux(iterator __pos, 388 _ForwardIterator __first, _ForwardIterator __last, 389 std::forward_iterator_tag) 390 { 391 const size_type __n = std::distance(__first, __last); 392 if (__pos._M_cur == this->_M_impl._M_start._M_cur) 393 { 394 iterator __new_start = _M_reserve_elements_at_front(__n); 395 try 396 { 397 std::__uninitialized_copy_a(__first, __last, __new_start, 398 _M_get_Tp_allocator()); 399 this->_M_impl._M_start = __new_start; 400 } 401 catch(...) 402 { 403 _M_destroy_nodes(__new_start._M_node, 404 this->_M_impl._M_start._M_node); 405 __throw_exception_again; 406 } 407 } 408 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) 409 { 410 iterator __new_finish = _M_reserve_elements_at_back(__n); 411 try 412 { 413 std::__uninitialized_copy_a(__first, __last, 414 this->_M_impl._M_finish, 415 _M_get_Tp_allocator()); 416 this->_M_impl._M_finish = __new_finish; 417 } 418 catch(...) 419 { 420 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 421 __new_finish._M_node + 1); 422 __throw_exception_again; 423 } 424 } 425 else 426 _M_insert_aux(__pos, __first, __last, __n); 427 } 428 429 template <typename _Tp, typename _Alloc> 430 typename deque<_Tp, _Alloc>::iterator 431 deque<_Tp, _Alloc>:: 432 _M_insert_aux(iterator __pos, const value_type& __x) 433 { 434 difference_type __index = __pos - this->_M_impl._M_start; 435 value_type __x_copy = __x; // XXX copy 436 if (static_cast<size_type>(__index) < size() / 2) 437 { 438 push_front(front()); 439 iterator __front1 = this->_M_impl._M_start; 440 ++__front1; 441 iterator __front2 = __front1; 442 ++__front2; 443 __pos = this->_M_impl._M_start + __index; 444 iterator __pos1 = __pos; 445 ++__pos1; 446 std::copy(__front2, __pos1, __front1); 447 } 448 else 449 { 450 push_back(back()); 451 iterator __back1 = this->_M_impl._M_finish; 452 --__back1; 453 iterator __back2 = __back1; 454 --__back2; 455 __pos = this->_M_impl._M_start + __index; 456 std::copy_backward(__pos, __back2, __back1); 457 } 458 *__pos = __x_copy; 459 return __pos; 460 } 461 462 template <typename _Tp, typename _Alloc> 463 void 464 deque<_Tp, _Alloc>:: 465 _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) 466 { 467 const difference_type __elems_before = __pos - this->_M_impl._M_start; 468 const size_type __length = this->size(); 469 value_type __x_copy = __x; 470 if (__elems_before < difference_type(__length / 2)) 471 { 472 iterator __new_start = _M_reserve_elements_at_front(__n); 473 iterator __old_start = this->_M_impl._M_start; 474 __pos = this->_M_impl._M_start + __elems_before; 475 try 476 { 477 if (__elems_before >= difference_type(__n)) 478 { 479 iterator __start_n = (this->_M_impl._M_start 480 + difference_type(__n)); 481 std::__uninitialized_copy_a(this->_M_impl._M_start, 482 __start_n, __new_start, 483 _M_get_Tp_allocator()); 484 this->_M_impl._M_start = __new_start; 485 std::copy(__start_n, __pos, __old_start); 486 std::fill(__pos - difference_type(__n), __pos, __x_copy); 487 } 488 else 489 { 490 std::__uninitialized_copy_fill(this->_M_impl._M_start, 491 __pos, __new_start, 492 this->_M_impl._M_start, 493 __x_copy, 494 _M_get_Tp_allocator()); 495 this->_M_impl._M_start = __new_start; 496 std::fill(__old_start, __pos, __x_copy); 497 } 498 } 499 catch(...) 500 { 501 _M_destroy_nodes(__new_start._M_node, 502 this->_M_impl._M_start._M_node); 503 __throw_exception_again; 504 } 505 } 506 else 507 { 508 iterator __new_finish = _M_reserve_elements_at_back(__n); 509 iterator __old_finish = this->_M_impl._M_finish; 510 const difference_type __elems_after = 511 difference_type(__length) - __elems_before; 512 __pos = this->_M_impl._M_finish - __elems_after; 513 try 514 { 515 if (__elems_after > difference_type(__n)) 516 { 517 iterator __finish_n = (this->_M_impl._M_finish 518 - difference_type(__n)); 519 std::__uninitialized_copy_a(__finish_n, 520 this->_M_impl._M_finish, 521 this->_M_impl._M_finish, 522 _M_get_Tp_allocator()); 523 this->_M_impl._M_finish = __new_finish; 524 std::copy_backward(__pos, __finish_n, __old_finish); 525 std::fill(__pos, __pos + difference_type(__n), __x_copy); 526 } 527 else 528 { 529 std::__uninitialized_fill_copy(this->_M_impl._M_finish, 530 __pos + difference_type(__n), 531 __x_copy, __pos, 532 this->_M_impl._M_finish, 533 _M_get_Tp_allocator()); 534 this->_M_impl._M_finish = __new_finish; 535 std::fill(__pos, __old_finish, __x_copy); 536 } 537 } 538 catch(...) 539 { 540 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 541 __new_finish._M_node + 1); 542 __throw_exception_again; 543 } 544 } 545 } 546 547 template <typename _Tp, typename _Alloc> 548 template <typename _ForwardIterator> 549 void 550 deque<_Tp, _Alloc>:: 551 _M_insert_aux(iterator __pos, 552 _ForwardIterator __first, _ForwardIterator __last, 553 size_type __n) 554 { 555 const difference_type __elemsbefore = __pos - this->_M_impl._M_start; 556 const size_type __length = size(); 557 if (static_cast<size_type>(__elemsbefore) < __length / 2) 558 { 559 iterator __new_start = _M_reserve_elements_at_front(__n); 560 iterator __old_start = this->_M_impl._M_start; 561 __pos = this->_M_impl._M_start + __elemsbefore; 562 try 563 { 564 if (__elemsbefore >= difference_type(__n)) 565 { 566 iterator __start_n = (this->_M_impl._M_start 567 + difference_type(__n)); 568 std::__uninitialized_copy_a(this->_M_impl._M_start, 569 __start_n, __new_start, 570 _M_get_Tp_allocator()); 571 this->_M_impl._M_start = __new_start; 572 std::copy(__start_n, __pos, __old_start); 573 std::copy(__first, __last, __pos - difference_type(__n)); 574 } 575 else 576 { 577 _ForwardIterator __mid = __first; 578 std::advance(__mid, difference_type(__n) - __elemsbefore); 579 std::__uninitialized_copy_copy(this->_M_impl._M_start, 580 __pos, __first, __mid, 581 __new_start, 582 _M_get_Tp_allocator()); 583 this->_M_impl._M_start = __new_start; 584 std::copy(__mid, __last, __old_start); 585 } 586 } 587 catch(...) 588 { 589 _M_destroy_nodes(__new_start._M_node, 590 this->_M_impl._M_start._M_node); 591 __throw_exception_again; 592 } 593 } 594 else 595 { 596 iterator __new_finish = _M_reserve_elements_at_back(__n); 597 iterator __old_finish = this->_M_impl._M_finish; 598 const difference_type __elemsafter = 599 difference_type(__length) - __elemsbefore; 600 __pos = this->_M_impl._M_finish - __elemsafter; 601 try 602 { 603 if (__elemsafter > difference_type(__n)) 604 { 605 iterator __finish_n = (this->_M_impl._M_finish 606 - difference_type(__n)); 607 std::__uninitialized_copy_a(__finish_n, 608 this->_M_impl._M_finish, 609 this->_M_impl._M_finish, 610 _M_get_Tp_allocator()); 611 this->_M_impl._M_finish = __new_finish; 612 std::copy_backward(__pos, __finish_n, __old_finish); 613 std::copy(__first, __last, __pos); 614 } 615 else 616 { 617 _ForwardIterator __mid = __first; 618 std::advance(__mid, __elemsafter); 619 std::__uninitialized_copy_copy(__mid, __last, __pos, 620 this->_M_impl._M_finish, 621 this->_M_impl._M_finish, 622 _M_get_Tp_allocator()); 623 this->_M_impl._M_finish = __new_finish; 624 std::copy(__first, __mid, __pos); 625 } 626 } 627 catch(...) 628 { 629 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 630 __new_finish._M_node + 1); 631 __throw_exception_again; 632 } 633 } 634 } 635 636 template<typename _Tp, typename _Alloc> 637 void 638 deque<_Tp, _Alloc>:: 639 _M_destroy_data_aux(iterator __first, iterator __last) 640 { 641 for (_Map_pointer __node = __first._M_node + 1; 642 __node < __last._M_node; ++__node) 643 std::_Destroy(*__node, *__node + _S_buffer_size(), 644 _M_get_Tp_allocator()); 645 646 if (__first._M_node != __last._M_node) 647 { 648 std::_Destroy(__first._M_cur, __first._M_last, 649 _M_get_Tp_allocator()); 650 std::_Destroy(__last._M_first, __last._M_cur, 651 _M_get_Tp_allocator()); 652 } 653 else 654 std::_Destroy(__first._M_cur, __last._M_cur, 655 _M_get_Tp_allocator()); 656 } 657 658 template <typename _Tp, typename _Alloc> 659 void 660 deque<_Tp, _Alloc>:: 661 _M_new_elements_at_front(size_type __new_elems) 662 { 663 if (this->max_size() - this->size() < __new_elems) 664 __throw_length_error(__N("deque::_M_new_elements_at_front")); 665 666 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) 667 / _S_buffer_size()); 668 _M_reserve_map_at_front(__new_nodes); 669 size_type __i; 670 try 671 { 672 for (__i = 1; __i <= __new_nodes; ++__i) 673 *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); 674 } 675 catch(...) 676 { 677 for (size_type __j = 1; __j < __i; ++__j) 678 _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); 679 __throw_exception_again; 680 } 681 } 682 683 template <typename _Tp, typename _Alloc> 684 void 685 deque<_Tp, _Alloc>:: 686 _M_new_elements_at_back(size_type __new_elems) 687 { 688 if (this->max_size() - this->size() < __new_elems) 689 __throw_length_error(__N("deque::_M_new_elements_at_back")); 690 691 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) 692 / _S_buffer_size()); 693 _M_reserve_map_at_back(__new_nodes); 694 size_type __i; 695 try 696 { 697 for (__i = 1; __i <= __new_nodes; ++__i) 698 *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); 699 } 700 catch(...) 701 { 702 for (size_type __j = 1; __j < __i; ++__j) 703 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); 704 __throw_exception_again; 705 } 706 } 707 708 template <typename _Tp, typename _Alloc> 709 void 710 deque<_Tp, _Alloc>:: 711 _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) 712 { 713 const size_type __old_num_nodes 714 = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; 715 const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; 716 717 _Map_pointer __new_nstart; 718 if (this->_M_impl._M_map_size > 2 * __new_num_nodes) 719 { 720 __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size 721 - __new_num_nodes) / 2 722 + (__add_at_front ? __nodes_to_add : 0); 723 if (__new_nstart < this->_M_impl._M_start._M_node) 724 std::copy(this->_M_impl._M_start._M_node, 725 this->_M_impl._M_finish._M_node + 1, 726 __new_nstart); 727 else 728 std::copy_backward(this->_M_impl._M_start._M_node, 729 this->_M_impl._M_finish._M_node + 1, 730 __new_nstart + __old_num_nodes); 731 } 732 else 733 { 734 size_type __new_map_size = this->_M_impl._M_map_size 735 + std::max(this->_M_impl._M_map_size, 736 __nodes_to_add) + 2; 737 738 _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); 739 __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 740 + (__add_at_front ? __nodes_to_add : 0); 741 std::copy(this->_M_impl._M_start._M_node, 742 this->_M_impl._M_finish._M_node + 1, 743 __new_nstart); 744 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); 745 746 this->_M_impl._M_map = __new_map; 747 this->_M_impl._M_map_size = __new_map_size; 748 } 749 750 this->_M_impl._M_start._M_set_node(__new_nstart); 751 this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); 752 } 753 754 // Overload for deque::iterators, exploiting the "segmented-iterator 755 // optimization". NB: leave const_iterators alone! 756 template<typename _Tp> 757 void 758 fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, 759 const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value) 760 { 761 typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; 762 763 for (typename _Self::_Map_pointer __node = __first._M_node + 1; 764 __node < __last._M_node; ++__node) 765 std::fill(*__node, *__node + _Self::_S_buffer_size(), __value); 766 767 if (__first._M_node != __last._M_node) 768 { 769 std::fill(__first._M_cur, __first._M_last, __value); 770 std::fill(__last._M_first, __last._M_cur, __value); 771 } 772 else 773 std::fill(__first._M_cur, __last._M_cur, __value); 774 } 775 776 _GLIBCXX_END_NESTED_NAMESPACE 777 778 #endif 779