1 // Deque implementation (out of line) -*- C++ -*- 2 3 // Copyright (C) 2001-2024 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /* 26 * 27 * Copyright (c) 1994 28 * Hewlett-Packard Company 29 * 30 * Permission to use, copy, modify, distribute and sell this software 31 * and its documentation for any purpose is hereby granted without fee, 32 * provided that the above copyright notice appear in all copies and 33 * that both that copyright notice and this permission notice appear 34 * in supporting documentation. Hewlett-Packard Company makes no 35 * representations about the suitability of this software for any 36 * purpose. It is provided "as is" without express or implied warranty. 37 * 38 * 39 * Copyright (c) 1997 40 * Silicon Graphics Computer Systems, Inc. 41 * 42 * Permission to use, copy, modify, distribute and sell this software 43 * and its documentation for any purpose is hereby granted without fee, 44 * provided that the above copyright notice appear in all copies and 45 * that both that copyright notice and this permission notice appear 46 * in supporting documentation. Silicon Graphics makes no 47 * representations about the suitability of this software for any 48 * purpose. It is provided "as is" without express or implied warranty. 49 */ 50 51 /** @file bits/deque.tcc 52 * This is an internal header file, included by other library headers. 53 * Do not attempt to use it directly. @headername{deque} 54 */ 55 56 #ifndef _DEQUE_TCC 57 #define _DEQUE_TCC 1 58 59 #include <bits/stl_algobase.h> 60 61 namespace std _GLIBCXX_VISIBILITY(default) 62 { 63 _GLIBCXX_BEGIN_NAMESPACE_VERSION 64 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 65 66 #if __cplusplus >= 201103L 67 template <typename _Tp, typename _Alloc> 68 void 69 deque<_Tp, _Alloc>:: 70 _M_default_initialize() 71 { 72 _Map_pointer __cur; 73 __try 74 { 75 for (__cur = this->_M_impl._M_start._M_node; 76 __cur < this->_M_impl._M_finish._M_node; 77 ++__cur) 78 std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(), 79 _M_get_Tp_allocator()); 80 std::__uninitialized_default_a(this->_M_impl._M_finish._M_first, 81 this->_M_impl._M_finish._M_cur, 82 _M_get_Tp_allocator()); 83 } 84 __catch(...) 85 { 86 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), 87 _M_get_Tp_allocator()); 88 __throw_exception_again; 89 } 90 } 91 #endif 92 93 template <typename _Tp, typename _Alloc> 94 deque<_Tp, _Alloc>& 95 deque<_Tp, _Alloc>:: 96 operator=(const deque& __x) 97 { 98 if (std::__addressof(__x) != this) 99 { 100 #if __cplusplus >= 201103L 101 if (_Alloc_traits::_S_propagate_on_copy_assign()) 102 { 103 if (!_Alloc_traits::_S_always_equal() 104 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator()) 105 { 106 // Replacement allocator cannot free existing storage, 107 // so deallocate everything and take copy of __x's data. 108 _M_replace_map(__x, __x.get_allocator()); 109 std::__alloc_on_copy(_M_get_Tp_allocator(), 110 __x._M_get_Tp_allocator()); 111 return *this; 112 } 113 std::__alloc_on_copy(_M_get_Tp_allocator(), 114 __x._M_get_Tp_allocator()); 115 } 116 #endif 117 const size_type __len = size(); 118 if (__len >= __x.size()) 119 _M_erase_at_end(std::copy(__x.begin(), __x.end(), 120 this->_M_impl._M_start)); 121 else 122 { 123 const_iterator __mid = __x.begin() + difference_type(__len); 124 std::copy(__x.begin(), __mid, this->_M_impl._M_start); 125 _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(), 126 std::random_access_iterator_tag()); 127 } 128 } 129 return *this; 130 } 131 132 #if __cplusplus >= 201103L 133 template<typename _Tp, typename _Alloc> 134 template<typename... _Args> 135 #if __cplusplus > 201402L 136 typename deque<_Tp, _Alloc>::reference 137 #else 138 void 139 #endif 140 deque<_Tp, _Alloc>:: 141 emplace_front(_Args&&... __args) 142 { 143 if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) 144 { 145 _Alloc_traits::construct(this->_M_impl, 146 this->_M_impl._M_start._M_cur - 1, 147 std::forward<_Args>(__args)...); 148 --this->_M_impl._M_start._M_cur; 149 } 150 else 151 _M_push_front_aux(std::forward<_Args>(__args)...); 152 #if __cplusplus > 201402L 153 return front(); 154 #endif 155 } 156 157 template<typename _Tp, typename _Alloc> 158 template<typename... _Args> 159 #if __cplusplus > 201402L 160 typename deque<_Tp, _Alloc>::reference 161 #else 162 void 163 #endif 164 deque<_Tp, _Alloc>:: 165 emplace_back(_Args&&... __args) 166 { 167 if (this->_M_impl._M_finish._M_cur 168 != this->_M_impl._M_finish._M_last - 1) 169 { 170 _Alloc_traits::construct(this->_M_impl, 171 this->_M_impl._M_finish._M_cur, 172 std::forward<_Args>(__args)...); 173 ++this->_M_impl._M_finish._M_cur; 174 } 175 else 176 _M_push_back_aux(std::forward<_Args>(__args)...); 177 #if __cplusplus > 201402L 178 return back(); 179 #endif 180 } 181 #endif 182 183 #if __cplusplus >= 201103L 184 template<typename _Tp, typename _Alloc> 185 template<typename... _Args> 186 typename deque<_Tp, _Alloc>::iterator 187 deque<_Tp, _Alloc>:: 188 emplace(const_iterator __position, _Args&&... __args) 189 { 190 if (__position._M_cur == this->_M_impl._M_start._M_cur) 191 { 192 emplace_front(std::forward<_Args>(__args)...); 193 return this->_M_impl._M_start; 194 } 195 else if (__position._M_cur == this->_M_impl._M_finish._M_cur) 196 { 197 emplace_back(std::forward<_Args>(__args)...); 198 iterator __tmp = this->_M_impl._M_finish; 199 --__tmp; 200 return __tmp; 201 } 202 else 203 return _M_emplace_aux(__position._M_const_cast(), 204 std::forward<_Args>(__args)...); 205 } 206 #endif 207 208 template <typename _Tp, typename _Alloc> 209 typename deque<_Tp, _Alloc>::iterator 210 deque<_Tp, _Alloc>:: 211 #if __cplusplus >= 201103L 212 insert(const_iterator __position, const value_type& __x) 213 #else 214 insert(iterator __position, const value_type& __x) 215 #endif 216 { 217 if (__position._M_cur == this->_M_impl._M_start._M_cur) 218 { 219 push_front(__x); 220 return this->_M_impl._M_start; 221 } 222 else if (__position._M_cur == this->_M_impl._M_finish._M_cur) 223 { 224 push_back(__x); 225 iterator __tmp = this->_M_impl._M_finish; 226 --__tmp; 227 return __tmp; 228 } 229 else 230 return _M_insert_aux(__position._M_const_cast(), __x); 231 } 232 233 template <typename _Tp, typename _Alloc> 234 typename deque<_Tp, _Alloc>::iterator 235 deque<_Tp, _Alloc>:: 236 _M_erase(iterator __position) 237 { 238 iterator __next = __position; 239 ++__next; 240 const difference_type __index = __position - begin(); 241 if (static_cast<size_type>(__index) < (size() >> 1)) 242 { 243 if (__position != begin()) 244 _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next); 245 pop_front(); 246 } 247 else 248 { 249 if (__next != end()) 250 _GLIBCXX_MOVE3(__next, end(), __position); 251 pop_back(); 252 } 253 return begin() + __index; 254 } 255 256 template <typename _Tp, typename _Alloc> 257 typename deque<_Tp, _Alloc>::iterator 258 deque<_Tp, _Alloc>:: 259 _M_erase(iterator __first, iterator __last) 260 { 261 if (__first == __last) 262 return __first; 263 else if (__first == begin() && __last == end()) 264 { 265 clear(); 266 return end(); 267 } 268 else 269 { 270 const difference_type __n = __last - __first; 271 const difference_type __elems_before = __first - begin(); 272 if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2) 273 { 274 if (__first != begin()) 275 _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last); 276 _M_erase_at_begin(begin() + __n); 277 } 278 else 279 { 280 if (__last != end()) 281 _GLIBCXX_MOVE3(__last, end(), __first); 282 _M_erase_at_end(end() - __n); 283 } 284 return begin() + __elems_before; 285 } 286 } 287 288 template <typename _Tp, class _Alloc> 289 template <typename _InputIterator> 290 void 291 deque<_Tp, _Alloc>:: 292 _M_assign_aux(_InputIterator __first, _InputIterator __last, 293 std::input_iterator_tag) 294 { 295 iterator __cur = begin(); 296 for (; __first != __last && __cur != end(); ++__cur, (void)++__first) 297 *__cur = *__first; 298 if (__first == __last) 299 _M_erase_at_end(__cur); 300 else 301 _M_range_insert_aux(end(), __first, __last, 302 std::__iterator_category(__first)); 303 } 304 305 template <typename _Tp, typename _Alloc> 306 void 307 deque<_Tp, _Alloc>:: 308 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) 309 { 310 if (__pos._M_cur == this->_M_impl._M_start._M_cur) 311 { 312 iterator __new_start = _M_reserve_elements_at_front(__n); 313 __try 314 { 315 std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, 316 __x, _M_get_Tp_allocator()); 317 this->_M_impl._M_start = __new_start; 318 } 319 __catch(...) 320 { 321 _M_destroy_nodes(__new_start._M_node, 322 this->_M_impl._M_start._M_node); 323 __throw_exception_again; 324 } 325 } 326 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) 327 { 328 iterator __new_finish = _M_reserve_elements_at_back(__n); 329 __try 330 { 331 std::__uninitialized_fill_a(this->_M_impl._M_finish, 332 __new_finish, __x, 333 _M_get_Tp_allocator()); 334 this->_M_impl._M_finish = __new_finish; 335 } 336 __catch(...) 337 { 338 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 339 __new_finish._M_node + 1); 340 __throw_exception_again; 341 } 342 } 343 else 344 _M_insert_aux(__pos, __n, __x); 345 } 346 347 #if __cplusplus >= 201103L 348 template <typename _Tp, typename _Alloc> 349 void 350 deque<_Tp, _Alloc>:: 351 _M_default_append(size_type __n) 352 { 353 if (__n) 354 { 355 iterator __new_finish = _M_reserve_elements_at_back(__n); 356 __try 357 { 358 std::__uninitialized_default_a(this->_M_impl._M_finish, 359 __new_finish, 360 _M_get_Tp_allocator()); 361 this->_M_impl._M_finish = __new_finish; 362 } 363 __catch(...) 364 { 365 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 366 __new_finish._M_node + 1); 367 __throw_exception_again; 368 } 369 } 370 } 371 372 template <typename _Tp, typename _Alloc> 373 bool 374 deque<_Tp, _Alloc>:: 375 _M_shrink_to_fit() 376 { 377 const difference_type __front_capacity 378 = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first); 379 if (__front_capacity == 0) 380 return false; 381 382 const difference_type __back_capacity 383 = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur); 384 if (__front_capacity + __back_capacity < _S_buffer_size()) 385 return false; 386 387 return std::__shrink_to_fit_aux<deque>::_S_do_it(*this); 388 } 389 #endif 390 391 template <typename _Tp, typename _Alloc> 392 void 393 deque<_Tp, _Alloc>:: 394 _M_fill_initialize(const value_type& __value) 395 { 396 _Map_pointer __cur; 397 __try 398 { 399 for (__cur = this->_M_impl._M_start._M_node; 400 __cur < this->_M_impl._M_finish._M_node; 401 ++__cur) 402 std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(), 403 __value, _M_get_Tp_allocator()); 404 std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first, 405 this->_M_impl._M_finish._M_cur, 406 __value, _M_get_Tp_allocator()); 407 } 408 __catch(...) 409 { 410 std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), 411 _M_get_Tp_allocator()); 412 __throw_exception_again; 413 } 414 } 415 416 template <typename _Tp, typename _Alloc> 417 template <typename _InputIterator> 418 void 419 deque<_Tp, _Alloc>:: 420 _M_range_initialize(_InputIterator __first, _InputIterator __last, 421 std::input_iterator_tag) 422 { 423 this->_M_initialize_map(0); 424 __try 425 { 426 for (; __first != __last; ++__first) 427 #if __cplusplus >= 201103L 428 emplace_back(*__first); 429 #else 430 push_back(*__first); 431 #endif 432 } 433 __catch(...) 434 { 435 clear(); 436 __throw_exception_again; 437 } 438 } 439 440 template <typename _Tp, typename _Alloc> 441 template <typename _ForwardIterator> 442 void 443 deque<_Tp, _Alloc>:: 444 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, 445 std::forward_iterator_tag) 446 { 447 const size_type __n = std::distance(__first, __last); 448 this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator())); 449 450 _Map_pointer __cur_node; 451 __try 452 { 453 for (__cur_node = this->_M_impl._M_start._M_node; 454 __cur_node < this->_M_impl._M_finish._M_node; 455 ++__cur_node) 456 { 457 if (__n < _S_buffer_size()) 458 __builtin_unreachable(); // See PR 100516 459 460 _ForwardIterator __mid = __first; 461 std::advance(__mid, _S_buffer_size()); 462 std::__uninitialized_copy_a(__first, __mid, *__cur_node, 463 _M_get_Tp_allocator()); 464 __first = __mid; 465 } 466 std::__uninitialized_copy_a(__first, __last, 467 this->_M_impl._M_finish._M_first, 468 _M_get_Tp_allocator()); 469 } 470 __catch(...) 471 { 472 std::_Destroy(this->_M_impl._M_start, 473 iterator(*__cur_node, __cur_node), 474 _M_get_Tp_allocator()); 475 __throw_exception_again; 476 } 477 } 478 479 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. 480 template<typename _Tp, typename _Alloc> 481 #if __cplusplus >= 201103L 482 template<typename... _Args> 483 void 484 deque<_Tp, _Alloc>:: 485 _M_push_back_aux(_Args&&... __args) 486 #else 487 void 488 deque<_Tp, _Alloc>:: 489 _M_push_back_aux(const value_type& __t) 490 #endif 491 { 492 if (size() == max_size()) 493 __throw_length_error( 494 __N("cannot create std::deque larger than max_size()")); 495 496 _M_reserve_map_at_back(); 497 *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); 498 __try 499 { 500 #if __cplusplus >= 201103L 501 _Alloc_traits::construct(this->_M_impl, 502 this->_M_impl._M_finish._M_cur, 503 std::forward<_Args>(__args)...); 504 #else 505 this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t); 506 #endif 507 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node 508 + 1); 509 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; 510 } 511 __catch(...) 512 { 513 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); 514 __throw_exception_again; 515 } 516 } 517 518 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. 519 template<typename _Tp, typename _Alloc> 520 #if __cplusplus >= 201103L 521 template<typename... _Args> 522 void 523 deque<_Tp, _Alloc>:: 524 _M_push_front_aux(_Args&&... __args) 525 #else 526 void 527 deque<_Tp, _Alloc>:: 528 _M_push_front_aux(const value_type& __t) 529 #endif 530 { 531 if (size() == max_size()) 532 __throw_length_error( 533 __N("cannot create std::deque larger than max_size()")); 534 535 _M_reserve_map_at_front(); 536 *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); 537 __try 538 { 539 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node 540 - 1); 541 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; 542 #if __cplusplus >= 201103L 543 _Alloc_traits::construct(this->_M_impl, 544 this->_M_impl._M_start._M_cur, 545 std::forward<_Args>(__args)...); 546 #else 547 this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t); 548 #endif 549 } 550 __catch(...) 551 { 552 ++this->_M_impl._M_start; 553 _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); 554 __throw_exception_again; 555 } 556 } 557 558 // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. 559 template <typename _Tp, typename _Alloc> 560 void deque<_Tp, _Alloc>:: 561 _M_pop_back_aux() 562 { 563 _M_deallocate_node(this->_M_impl._M_finish._M_first); 564 this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); 565 this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; 566 _Alloc_traits::destroy(_M_get_Tp_allocator(), 567 this->_M_impl._M_finish._M_cur); 568 } 569 570 // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. 571 // Note that if the deque has at least one element (a precondition for this 572 // member function), and if 573 // _M_impl._M_start._M_cur == _M_impl._M_start._M_last, 574 // then the deque must have at least two nodes. 575 template <typename _Tp, typename _Alloc> 576 void deque<_Tp, _Alloc>:: 577 _M_pop_front_aux() 578 { 579 _Alloc_traits::destroy(_M_get_Tp_allocator(), 580 this->_M_impl._M_start._M_cur); 581 _M_deallocate_node(this->_M_impl._M_start._M_first); 582 this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); 583 this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; 584 } 585 586 template <typename _Tp, typename _Alloc> 587 template <typename _InputIterator> 588 void 589 deque<_Tp, _Alloc>:: 590 _M_range_insert_aux(iterator __pos, 591 _InputIterator __first, _InputIterator __last, 592 std::input_iterator_tag) 593 { std::copy(__first, __last, std::inserter(*this, __pos)); } 594 595 template <typename _Tp, typename _Alloc> 596 template <typename _ForwardIterator> 597 void 598 deque<_Tp, _Alloc>:: 599 _M_range_insert_aux(iterator __pos, 600 _ForwardIterator __first, _ForwardIterator __last, 601 std::forward_iterator_tag) 602 { 603 const size_type __n = std::distance(__first, __last); 604 if (__builtin_expect(__n == 0, 0)) 605 return; 606 607 if (__pos._M_cur == this->_M_impl._M_start._M_cur) 608 { 609 iterator __new_start = _M_reserve_elements_at_front(__n); 610 __try 611 { 612 std::__uninitialized_copy_a(__first, __last, __new_start, 613 _M_get_Tp_allocator()); 614 this->_M_impl._M_start = __new_start; 615 } 616 __catch(...) 617 { 618 _M_destroy_nodes(__new_start._M_node, 619 this->_M_impl._M_start._M_node); 620 __throw_exception_again; 621 } 622 } 623 else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) 624 { 625 iterator __new_finish = _M_reserve_elements_at_back(__n); 626 __try 627 { 628 std::__uninitialized_copy_a(__first, __last, 629 this->_M_impl._M_finish, 630 _M_get_Tp_allocator()); 631 this->_M_impl._M_finish = __new_finish; 632 } 633 __catch(...) 634 { 635 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 636 __new_finish._M_node + 1); 637 __throw_exception_again; 638 } 639 } 640 else 641 _M_insert_aux(__pos, __first, __last, __n); 642 } 643 644 template<typename _Tp, typename _Alloc> 645 #if __cplusplus >= 201103L 646 template<typename... _Args> 647 typename deque<_Tp, _Alloc>::iterator 648 deque<_Tp, _Alloc>:: 649 _M_emplace_aux(iterator __pos, _Args&&... __args) 650 { 651 value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy 652 #else 653 typename deque<_Tp, _Alloc>::iterator 654 deque<_Tp, _Alloc>:: 655 _M_insert_aux(iterator __pos, const value_type& __x) 656 { 657 value_type __x_copy = __x; // XXX copy 658 #endif 659 difference_type __index = __pos - this->_M_impl._M_start; 660 if (static_cast<size_type>(__index) < size() / 2) 661 { 662 push_front(_GLIBCXX_MOVE(front())); 663 iterator __front1 = this->_M_impl._M_start; 664 ++__front1; 665 iterator __front2 = __front1; 666 ++__front2; 667 __pos = this->_M_impl._M_start + __index; 668 iterator __pos1 = __pos; 669 ++__pos1; 670 _GLIBCXX_MOVE3(__front2, __pos1, __front1); 671 } 672 else 673 { 674 push_back(_GLIBCXX_MOVE(back())); 675 iterator __back1 = this->_M_impl._M_finish; 676 --__back1; 677 iterator __back2 = __back1; 678 --__back2; 679 __pos = this->_M_impl._M_start + __index; 680 _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1); 681 } 682 *__pos = _GLIBCXX_MOVE(__x_copy); 683 return __pos; 684 } 685 686 template <typename _Tp, typename _Alloc> 687 void 688 deque<_Tp, _Alloc>:: 689 _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) 690 { 691 const difference_type __elems_before = __pos - this->_M_impl._M_start; 692 const size_type __length = this->size(); 693 value_type __x_copy = __x; 694 if (__elems_before < difference_type(__length / 2)) 695 { 696 iterator __new_start = _M_reserve_elements_at_front(__n); 697 iterator __old_start = this->_M_impl._M_start; 698 __pos = this->_M_impl._M_start + __elems_before; 699 __try 700 { 701 if (__elems_before >= difference_type(__n)) 702 { 703 iterator __start_n = (this->_M_impl._M_start 704 + difference_type(__n)); 705 std::__uninitialized_move_a(this->_M_impl._M_start, 706 __start_n, __new_start, 707 _M_get_Tp_allocator()); 708 this->_M_impl._M_start = __new_start; 709 _GLIBCXX_MOVE3(__start_n, __pos, __old_start); 710 std::fill(__pos - difference_type(__n), __pos, __x_copy); 711 } 712 else 713 { 714 std::__uninitialized_move_fill(this->_M_impl._M_start, 715 __pos, __new_start, 716 this->_M_impl._M_start, 717 __x_copy, 718 _M_get_Tp_allocator()); 719 this->_M_impl._M_start = __new_start; 720 std::fill(__old_start, __pos, __x_copy); 721 } 722 } 723 __catch(...) 724 { 725 _M_destroy_nodes(__new_start._M_node, 726 this->_M_impl._M_start._M_node); 727 __throw_exception_again; 728 } 729 } 730 else 731 { 732 iterator __new_finish = _M_reserve_elements_at_back(__n); 733 iterator __old_finish = this->_M_impl._M_finish; 734 const difference_type __elems_after = 735 difference_type(__length) - __elems_before; 736 __pos = this->_M_impl._M_finish - __elems_after; 737 __try 738 { 739 if (__elems_after > difference_type(__n)) 740 { 741 iterator __finish_n = (this->_M_impl._M_finish 742 - difference_type(__n)); 743 std::__uninitialized_move_a(__finish_n, 744 this->_M_impl._M_finish, 745 this->_M_impl._M_finish, 746 _M_get_Tp_allocator()); 747 this->_M_impl._M_finish = __new_finish; 748 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); 749 std::fill(__pos, __pos + difference_type(__n), __x_copy); 750 } 751 else 752 { 753 std::__uninitialized_fill_move(this->_M_impl._M_finish, 754 __pos + difference_type(__n), 755 __x_copy, __pos, 756 this->_M_impl._M_finish, 757 _M_get_Tp_allocator()); 758 this->_M_impl._M_finish = __new_finish; 759 std::fill(__pos, __old_finish, __x_copy); 760 } 761 } 762 __catch(...) 763 { 764 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 765 __new_finish._M_node + 1); 766 __throw_exception_again; 767 } 768 } 769 } 770 771 template <typename _Tp, typename _Alloc> 772 template <typename _ForwardIterator> 773 void 774 deque<_Tp, _Alloc>:: 775 _M_insert_aux(iterator __pos, 776 _ForwardIterator __first, _ForwardIterator __last, 777 size_type __n) 778 { 779 const difference_type __elemsbefore = __pos - this->_M_impl._M_start; 780 const size_type __length = size(); 781 if (static_cast<size_type>(__elemsbefore) < __length / 2) 782 { 783 iterator __new_start = _M_reserve_elements_at_front(__n); 784 iterator __old_start = this->_M_impl._M_start; 785 __pos = this->_M_impl._M_start + __elemsbefore; 786 __try 787 { 788 if (__elemsbefore >= difference_type(__n)) 789 { 790 iterator __start_n = (this->_M_impl._M_start 791 + difference_type(__n)); 792 std::__uninitialized_move_a(this->_M_impl._M_start, 793 __start_n, __new_start, 794 _M_get_Tp_allocator()); 795 this->_M_impl._M_start = __new_start; 796 _GLIBCXX_MOVE3(__start_n, __pos, __old_start); 797 std::copy(__first, __last, __pos - difference_type(__n)); 798 } 799 else 800 { 801 _ForwardIterator __mid = __first; 802 std::advance(__mid, difference_type(__n) - __elemsbefore); 803 std::__uninitialized_move_copy(this->_M_impl._M_start, 804 __pos, __first, __mid, 805 __new_start, 806 _M_get_Tp_allocator()); 807 this->_M_impl._M_start = __new_start; 808 std::copy(__mid, __last, __old_start); 809 } 810 } 811 __catch(...) 812 { 813 _M_destroy_nodes(__new_start._M_node, 814 this->_M_impl._M_start._M_node); 815 __throw_exception_again; 816 } 817 } 818 else 819 { 820 iterator __new_finish = _M_reserve_elements_at_back(__n); 821 iterator __old_finish = this->_M_impl._M_finish; 822 const difference_type __elemsafter = 823 difference_type(__length) - __elemsbefore; 824 __pos = this->_M_impl._M_finish - __elemsafter; 825 __try 826 { 827 if (__elemsafter > difference_type(__n)) 828 { 829 iterator __finish_n = (this->_M_impl._M_finish 830 - difference_type(__n)); 831 std::__uninitialized_move_a(__finish_n, 832 this->_M_impl._M_finish, 833 this->_M_impl._M_finish, 834 _M_get_Tp_allocator()); 835 this->_M_impl._M_finish = __new_finish; 836 _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); 837 std::copy(__first, __last, __pos); 838 } 839 else 840 { 841 _ForwardIterator __mid = __first; 842 std::advance(__mid, __elemsafter); 843 std::__uninitialized_copy_move(__mid, __last, __pos, 844 this->_M_impl._M_finish, 845 this->_M_impl._M_finish, 846 _M_get_Tp_allocator()); 847 this->_M_impl._M_finish = __new_finish; 848 std::copy(__first, __mid, __pos); 849 } 850 } 851 __catch(...) 852 { 853 _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, 854 __new_finish._M_node + 1); 855 __throw_exception_again; 856 } 857 } 858 } 859 860 template<typename _Tp, typename _Alloc> 861 void 862 deque<_Tp, _Alloc>:: 863 _M_destroy_data_aux(iterator __first, iterator __last) 864 { 865 for (_Map_pointer __node = __first._M_node + 1; 866 __node < __last._M_node; ++__node) 867 std::_Destroy(*__node, *__node + _S_buffer_size(), 868 _M_get_Tp_allocator()); 869 870 if (__first._M_node != __last._M_node) 871 { 872 std::_Destroy(__first._M_cur, __first._M_last, 873 _M_get_Tp_allocator()); 874 std::_Destroy(__last._M_first, __last._M_cur, 875 _M_get_Tp_allocator()); 876 } 877 else 878 std::_Destroy(__first._M_cur, __last._M_cur, 879 _M_get_Tp_allocator()); 880 } 881 882 template <typename _Tp, typename _Alloc> 883 void 884 deque<_Tp, _Alloc>:: 885 _M_new_elements_at_front(size_type __new_elems) 886 { 887 if (this->max_size() - this->size() < __new_elems) 888 __throw_length_error(__N("deque::_M_new_elements_at_front")); 889 890 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) 891 / _S_buffer_size()); 892 _M_reserve_map_at_front(__new_nodes); 893 size_type __i; 894 __try 895 { 896 for (__i = 1; __i <= __new_nodes; ++__i) 897 *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); 898 } 899 __catch(...) 900 { 901 for (size_type __j = 1; __j < __i; ++__j) 902 _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); 903 __throw_exception_again; 904 } 905 } 906 907 template <typename _Tp, typename _Alloc> 908 void 909 deque<_Tp, _Alloc>:: 910 _M_new_elements_at_back(size_type __new_elems) 911 { 912 if (this->max_size() - this->size() < __new_elems) 913 __throw_length_error(__N("deque::_M_new_elements_at_back")); 914 915 const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) 916 / _S_buffer_size()); 917 _M_reserve_map_at_back(__new_nodes); 918 size_type __i; 919 __try 920 { 921 for (__i = 1; __i <= __new_nodes; ++__i) 922 *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); 923 } 924 __catch(...) 925 { 926 for (size_type __j = 1; __j < __i; ++__j) 927 _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); 928 __throw_exception_again; 929 } 930 } 931 932 template <typename _Tp, typename _Alloc> 933 void 934 deque<_Tp, _Alloc>:: 935 _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) 936 { 937 const size_type __old_num_nodes 938 = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; 939 const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; 940 941 _Map_pointer __new_nstart; 942 if (this->_M_impl._M_map_size > 2 * __new_num_nodes) 943 { 944 __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size 945 - __new_num_nodes) / 2 946 + (__add_at_front ? __nodes_to_add : 0); 947 if (__new_nstart < this->_M_impl._M_start._M_node) 948 std::copy(this->_M_impl._M_start._M_node, 949 this->_M_impl._M_finish._M_node + 1, 950 __new_nstart); 951 else 952 std::copy_backward(this->_M_impl._M_start._M_node, 953 this->_M_impl._M_finish._M_node + 1, 954 __new_nstart + __old_num_nodes); 955 } 956 else 957 { 958 size_type __new_map_size = this->_M_impl._M_map_size 959 + std::max(this->_M_impl._M_map_size, 960 __nodes_to_add) + 2; 961 962 _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); 963 __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 964 + (__add_at_front ? __nodes_to_add : 0); 965 std::copy(this->_M_impl._M_start._M_node, 966 this->_M_impl._M_finish._M_node + 1, 967 __new_nstart); 968 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); 969 970 this->_M_impl._M_map = __new_map; 971 this->_M_impl._M_map_size = __new_map_size; 972 } 973 974 this->_M_impl._M_start._M_set_node(__new_nstart); 975 this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); 976 } 977 978 _GLIBCXX_END_NAMESPACE_CONTAINER 979 980 // Overload for deque::iterators, exploiting the "segmented-iterator 981 // optimization". 982 template<typename _Tp, typename _VTp> 983 void 984 __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __first, 985 const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __last, 986 const _VTp& __value) 987 { 988 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter; 989 if (__first._M_node != __last._M_node) 990 { 991 std::__fill_a1(__first._M_cur, __first._M_last, __value); 992 993 for (typename _Iter::_Map_pointer __node = __first._M_node + 1; 994 __node < __last._M_node; ++__node) 995 std::__fill_a1(*__node, *__node + _Iter::_S_buffer_size(), __value); 996 997 std::__fill_a1(__last._M_first, __last._M_cur, __value); 998 } 999 else 1000 std::__fill_a1(__first._M_cur, __last._M_cur, __value); 1001 } 1002 1003 template<bool _IsMove, 1004 typename _Tp, typename _Ref, typename _Ptr, typename _OI> 1005 _OI 1006 __copy_move_dit(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, 1007 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, 1008 _OI __result) 1009 { 1010 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; 1011 if (__first._M_node != __last._M_node) 1012 { 1013 __result 1014 = std::__copy_move_a1<_IsMove>(__first._M_cur, __first._M_last, 1015 __result); 1016 1017 for (typename _Iter::_Map_pointer __node = __first._M_node + 1; 1018 __node != __last._M_node; ++__node) 1019 __result 1020 = std::__copy_move_a1<_IsMove>(*__node, 1021 *__node + _Iter::_S_buffer_size(), 1022 __result); 1023 1024 return std::__copy_move_a1<_IsMove>(__last._M_first, __last._M_cur, 1025 __result); 1026 } 1027 1028 return std::__copy_move_a1<_IsMove>(__first._M_cur, __last._M_cur, 1029 __result); 1030 } 1031 1032 template<bool _IsMove, 1033 typename _Tp, typename _Ref, typename _Ptr, typename _OI> 1034 _OI 1035 __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, 1036 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, 1037 _OI __result) 1038 { return __copy_move_dit<_IsMove>(__first, __last, __result); } 1039 1040 template<bool _IsMove, 1041 typename _ITp, typename _IRef, typename _IPtr, typename _OTp> 1042 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> 1043 __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first, 1044 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last, 1045 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result) 1046 { return __copy_move_dit<_IsMove>(__first, __last, __result); } 1047 1048 template<bool _IsMove, typename _II, typename _Tp> 1049 typename __gnu_cxx::__enable_if< 1050 __is_random_access_iter<_II>::__value, 1051 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type 1052 __copy_move_a1(_II __first, _II __last, 1053 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result) 1054 { 1055 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter; 1056 typedef typename _Iter::difference_type difference_type; 1057 1058 difference_type __len = __last - __first; 1059 while (__len > 0) 1060 { 1061 const difference_type __clen 1062 = std::min(__len, __result._M_last - __result._M_cur); 1063 std::__copy_move_a1<_IsMove>(__first, __first + __clen, 1064 __result._M_cur); 1065 1066 __first += __clen; 1067 __result += __clen; 1068 __len -= __clen; 1069 } 1070 1071 return __result; 1072 } 1073 1074 template<bool _IsMove, typename _CharT> 1075 typename __gnu_cxx::__enable_if< 1076 __is_char<_CharT>::__value, 1077 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> >::__type 1078 __copy_move_a2( 1079 istreambuf_iterator<_CharT, char_traits<_CharT> > __first, 1080 istreambuf_iterator<_CharT, char_traits<_CharT> > __last, 1081 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> __result) 1082 { 1083 if (__first == __last) 1084 return __result; 1085 1086 for (;;) 1087 { 1088 const std::ptrdiff_t __len = __result._M_last - __result._M_cur; 1089 const std::ptrdiff_t __nb 1090 = std::__copy_n_a(__first, __len, __result._M_cur, false) 1091 - __result._M_cur; 1092 __result += __nb; 1093 1094 if (__nb != __len) 1095 break; 1096 } 1097 1098 return __result; 1099 } 1100 1101 template<typename _CharT, typename _Size> 1102 typename __gnu_cxx::__enable_if< 1103 __is_char<_CharT>::__value, 1104 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> >::__type 1105 __copy_n_a( 1106 istreambuf_iterator<_CharT, char_traits<_CharT> > __it, _Size __size, 1107 _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*> __result, 1108 bool __strict) 1109 { 1110 if (__size == 0) 1111 return __result; 1112 1113 do 1114 { 1115 const _Size __len 1116 = std::min<_Size>(__result._M_last - __result._M_cur, __size); 1117 std::__copy_n_a(__it, __len, __result._M_cur, __strict); 1118 __result += __len; 1119 __size -= __len; 1120 } 1121 while (__size != 0); 1122 return __result; 1123 } 1124 1125 template<bool _IsMove, 1126 typename _Tp, typename _Ref, typename _Ptr, typename _OI> 1127 _OI 1128 __copy_move_backward_dit( 1129 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, 1130 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, 1131 _OI __result) 1132 { 1133 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; 1134 if (__first._M_node != __last._M_node) 1135 { 1136 __result = std::__copy_move_backward_a1<_IsMove>( 1137 __last._M_first, __last._M_cur, __result); 1138 1139 for (typename _Iter::_Map_pointer __node = __last._M_node - 1; 1140 __node != __first._M_node; --__node) 1141 __result = std::__copy_move_backward_a1<_IsMove>( 1142 *__node, *__node + _Iter::_S_buffer_size(), __result); 1143 1144 return std::__copy_move_backward_a1<_IsMove>( 1145 __first._M_cur, __first._M_last, __result); 1146 } 1147 1148 return std::__copy_move_backward_a1<_IsMove>( 1149 __first._M_cur, __last._M_cur, __result); 1150 } 1151 1152 template<bool _IsMove, 1153 typename _Tp, typename _Ref, typename _Ptr, typename _OI> 1154 _OI 1155 __copy_move_backward_a1( 1156 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, 1157 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, 1158 _OI __result) 1159 { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); } 1160 1161 template<bool _IsMove, 1162 typename _ITp, typename _IRef, typename _IPtr, typename _OTp> 1163 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> 1164 __copy_move_backward_a1( 1165 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first, 1166 _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last, 1167 _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result) 1168 { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); } 1169 1170 template<bool _IsMove, typename _II, typename _Tp> 1171 typename __gnu_cxx::__enable_if< 1172 __is_random_access_iter<_II>::__value, 1173 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type 1174 __copy_move_backward_a1(_II __first, _II __last, 1175 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result) 1176 { 1177 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter; 1178 typedef typename _Iter::difference_type difference_type; 1179 1180 difference_type __len = __last - __first; 1181 while (__len > 0) 1182 { 1183 difference_type __rlen = __result._M_cur - __result._M_first; 1184 _Tp* __rend = __result._M_cur; 1185 if (!__rlen) 1186 { 1187 __rlen = _Iter::_S_buffer_size(); 1188 __rend = *(__result._M_node - 1) + __rlen; 1189 } 1190 1191 const difference_type __clen = std::min(__len, __rlen); 1192 std::__copy_move_backward_a1<_IsMove>(__last - __clen, __last, __rend); 1193 1194 __last -= __clen; 1195 __result -= __clen; 1196 __len -= __clen; 1197 } 1198 1199 return __result; 1200 } 1201 1202 template<typename _Tp, typename _Ref, typename _Ptr, typename _II> 1203 bool 1204 __equal_dit( 1205 const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __first1, 1206 const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __last1, 1207 _II __first2) 1208 { 1209 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; 1210 if (__first1._M_node != __last1._M_node) 1211 { 1212 if (!std::__equal_aux1(__first1._M_cur, __first1._M_last, __first2)) 1213 return false; 1214 1215 __first2 += __first1._M_last - __first1._M_cur; 1216 for (typename _Iter::_Map_pointer __node = __first1._M_node + 1; 1217 __node != __last1._M_node; 1218 __first2 += _Iter::_S_buffer_size(), ++__node) 1219 if (!std::__equal_aux1(*__node, *__node + _Iter::_S_buffer_size(), 1220 __first2)) 1221 return false; 1222 1223 return std::__equal_aux1(__last1._M_first, __last1._M_cur, __first2); 1224 } 1225 1226 return std::__equal_aux1(__first1._M_cur, __last1._M_cur, __first2); 1227 } 1228 1229 template<typename _Tp, typename _Ref, typename _Ptr, typename _II> 1230 typename __gnu_cxx::__enable_if< 1231 __is_random_access_iter<_II>::__value, bool>::__type 1232 __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first1, 1233 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last1, 1234 _II __first2) 1235 { return std::__equal_dit(__first1, __last1, __first2); } 1236 1237 template<typename _Tp1, typename _Ref1, typename _Ptr1, 1238 typename _Tp2, typename _Ref2, typename _Ptr2> 1239 bool 1240 __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1, 1241 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1, 1242 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2) 1243 { return std::__equal_dit(__first1, __last1, __first2); } 1244 1245 template<typename _II, typename _Tp, typename _Ref, typename _Ptr> 1246 typename __gnu_cxx::__enable_if< 1247 __is_random_access_iter<_II>::__value, bool>::__type 1248 __equal_aux1(_II __first1, _II __last1, 1249 _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first2) 1250 { 1251 typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; 1252 typedef typename _Iter::difference_type difference_type; 1253 1254 difference_type __len = __last1 - __first1; 1255 while (__len > 0) 1256 { 1257 const difference_type __clen 1258 = std::min(__len, __first2._M_last - __first2._M_cur); 1259 if (!std::__equal_aux1(__first1, __first1 + __clen, __first2._M_cur)) 1260 return false; 1261 1262 __first1 += __clen; 1263 __len -= __clen; 1264 __first2 += __clen; 1265 } 1266 1267 return true; 1268 } 1269 1270 template<typename _Tp1, typename _Ref, typename _Ptr, typename _Tp2> 1271 int 1272 __lex_cmp_dit( 1273 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref, _Ptr> __first1, 1274 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref, _Ptr> __last1, 1275 const _Tp2* __first2, const _Tp2* __last2) 1276 { 1277 const bool __simple = 1278 (__is_memcmp_ordered_with<_Tp1, _Tp2>::__value 1279 && __is_pointer<_Ptr>::__value 1280 #if __cplusplus > 201703L && __cpp_lib_concepts 1281 // For C++20 iterator_traits<volatile T*>::value_type is non-volatile 1282 // so __is_byte<T> could be true, but we can't use memcmp with 1283 // volatile data. 1284 && !is_volatile_v<_Tp1> 1285 && !is_volatile_v<_Tp2> 1286 #endif 1287 ); 1288 typedef std::__lexicographical_compare<__simple> _Lc; 1289 1290 while (__first1._M_node != __last1._M_node) 1291 { 1292 const ptrdiff_t __len1 = __first1._M_last - __first1._M_cur; 1293 const ptrdiff_t __len2 = __last2 - __first2; 1294 const ptrdiff_t __len = std::min(__len1, __len2); 1295 // if __len1 > __len2 this will return a positive value: 1296 if (int __ret = _Lc::__3way(__first1._M_cur, __first1._M_last, 1297 __first2, __first2 + __len)) 1298 return __ret; 1299 1300 __first1 += __len; 1301 __first2 += __len; 1302 } 1303 return _Lc::__3way(__first1._M_cur, __last1._M_cur, 1304 __first2, __last2); 1305 } 1306 1307 template<typename _Tp1, typename _Ref1, typename _Ptr1, 1308 typename _Tp2> 1309 inline bool 1310 __lexicographical_compare_aux1( 1311 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1, 1312 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1, 1313 _Tp2* __first2, _Tp2* __last2) 1314 { return std::__lex_cmp_dit(__first1, __last1, __first2, __last2) < 0; } 1315 1316 template<typename _Tp1, 1317 typename _Tp2, typename _Ref2, typename _Ptr2> 1318 inline bool 1319 __lexicographical_compare_aux1(_Tp1* __first1, _Tp1* __last1, 1320 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2, 1321 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __last2) 1322 { return std::__lex_cmp_dit(__first2, __last2, __first1, __last1) > 0; } 1323 1324 template<typename _Tp1, typename _Ref1, typename _Ptr1, 1325 typename _Tp2, typename _Ref2, typename _Ptr2> 1326 inline bool 1327 __lexicographical_compare_aux1( 1328 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1, 1329 _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1, 1330 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2, 1331 _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __last2) 1332 { 1333 const bool __simple = 1334 (__is_memcmp_ordered_with<_Tp1, _Tp2>::__value 1335 && __is_pointer<_Ptr1>::__value 1336 && __is_pointer<_Ptr2>::__value 1337 #if __cplusplus > 201703L && __cpp_lib_concepts 1338 // For C++20 iterator_traits<volatile T*>::value_type is non-volatile 1339 // so __is_byte<T> could be true, but we can't use memcmp with 1340 // volatile data. 1341 && !is_volatile_v<_Tp1> 1342 && !is_volatile_v<_Tp2> 1343 #endif 1344 ); 1345 typedef std::__lexicographical_compare<__simple> _Lc; 1346 1347 while (__first1 != __last1) 1348 { 1349 const ptrdiff_t __len2 = __first2._M_node == __last2._M_node 1350 ? __last2._M_cur - __first2._M_cur 1351 : __first2._M_last - __first2._M_cur; 1352 if (__len2 == 0) 1353 return false; 1354 const ptrdiff_t __len1 = __first1._M_node == __last1._M_node 1355 ? __last1._M_cur - __first1._M_cur 1356 : __first1._M_last - __first1._M_cur; 1357 const ptrdiff_t __len = std::min(__len1, __len2); 1358 if (int __ret = _Lc::__3way(__first1._M_cur, __first1._M_cur + __len, 1359 __first2._M_cur, __first2._M_cur + __len)) 1360 return __ret < 0; 1361 1362 __first1 += __len; 1363 __first2 += __len; 1364 } 1365 1366 return __last2 != __first2; 1367 } 1368 1369 _GLIBCXX_END_NAMESPACE_VERSION 1370 } // namespace std 1371 1372 #endif 1373