1 // Debugging vector implementation -*- C++ -*- 2 3 // Copyright (C) 2003-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 /** @file debug/vector 26 * This file is a GNU debug extension to the Standard C++ Library. 27 */ 28 29 #ifndef _GLIBCXX_DEBUG_VECTOR 30 #define _GLIBCXX_DEBUG_VECTOR 1 31 32 #pragma GCC system_header 33 34 #include <bits/c++config.h> 35 namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug { 36 template<typename _Tp, typename _Allocator> class vector; 37 } } // namespace std::__debug 38 39 #include <vector> 40 #include <debug/safe_sequence.h> 41 #include <debug/safe_container.h> 42 #include <debug/safe_iterator.h> 43 44 namespace __gnu_debug 45 { 46 /** @brief Base class for Debug Mode vector. 47 * 48 * Adds information about the guaranteed capacity, which is useful for 49 * detecting code which relies on non-portable implementation details of 50 * the libstdc++ reallocation policy. 51 */ 52 template<typename _SafeSequence, 53 typename _BaseSequence> 54 class _Safe_vector 55 { 56 typedef typename _BaseSequence::size_type size_type; 57 58 _GLIBCXX20_CONSTEXPR 59 const _SafeSequence& 60 _M_seq() const { return *static_cast<const _SafeSequence*>(this); } 61 62 protected: 63 _GLIBCXX20_CONSTEXPR 64 _Safe_vector() _GLIBCXX_NOEXCEPT 65 : _M_guaranteed_capacity(0) 66 { _M_update_guaranteed_capacity(); } 67 68 _GLIBCXX20_CONSTEXPR 69 _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT 70 : _M_guaranteed_capacity(0) 71 { _M_update_guaranteed_capacity(); } 72 73 _GLIBCXX20_CONSTEXPR 74 _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT 75 : _M_guaranteed_capacity(__n) 76 { } 77 78 _GLIBCXX20_CONSTEXPR 79 _Safe_vector& 80 operator=(const _Safe_vector&) _GLIBCXX_NOEXCEPT 81 { 82 _M_update_guaranteed_capacity(); 83 return *this; 84 } 85 86 #if __cplusplus >= 201103L 87 _GLIBCXX20_CONSTEXPR 88 _Safe_vector(_Safe_vector&& __x) noexcept 89 : _Safe_vector() 90 { __x._M_guaranteed_capacity = 0; } 91 92 _GLIBCXX20_CONSTEXPR 93 _Safe_vector& 94 operator=(_Safe_vector&& __x) noexcept 95 { 96 _M_update_guaranteed_capacity(); 97 __x._M_guaranteed_capacity = 0; 98 return *this; 99 } 100 #endif 101 102 size_type _M_guaranteed_capacity; 103 104 bool 105 _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT 106 { return __elements > _M_seq().capacity(); } 107 108 _GLIBCXX20_CONSTEXPR 109 void 110 _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT 111 { 112 if (_M_seq().size() > _M_guaranteed_capacity) 113 _M_guaranteed_capacity = _M_seq().size(); 114 } 115 }; 116 } 117 118 namespace std _GLIBCXX_VISIBILITY(default) 119 { 120 namespace __debug 121 { 122 /// Class std::vector with safety/checking/debug instrumentation. 123 template<typename _Tp, 124 typename _Allocator = std::allocator<_Tp> > 125 class vector 126 : public __gnu_debug::_Safe_container< 127 vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>, 128 public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, 129 public __gnu_debug::_Safe_vector< 130 vector<_Tp, _Allocator>, 131 _GLIBCXX_STD_C::vector<_Tp, _Allocator> > 132 { 133 typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; 134 typedef __gnu_debug::_Safe_container< 135 vector, _Allocator, __gnu_debug::_Safe_sequence> _Safe; 136 typedef __gnu_debug::_Safe_vector<vector, _Base> _Safe_vector; 137 138 typedef typename _Base::iterator _Base_iterator; 139 typedef typename _Base::const_iterator _Base_const_iterator; 140 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; 141 142 template<typename _ItT, typename _SeqT, typename _CatT> 143 friend class ::__gnu_debug::_Safe_iterator; 144 145 // Reference wrapper for base class. Disambiguates vector(const _Base&) 146 // from copy constructor by requiring a user-defined conversion. 147 // See PR libstdc++/90102. 148 struct _Base_ref 149 { 150 _Base_ref(const _Base& __r) : _M_ref(__r) { } 151 152 const _Base& _M_ref; 153 }; 154 155 public: 156 typedef typename _Base::reference reference; 157 typedef typename _Base::const_reference const_reference; 158 159 typedef __gnu_debug::_Safe_iterator< 160 _Base_iterator, vector> iterator; 161 typedef __gnu_debug::_Safe_iterator< 162 _Base_const_iterator, vector> const_iterator; 163 164 typedef typename _Base::size_type size_type; 165 typedef typename _Base::difference_type difference_type; 166 167 typedef _Tp value_type; 168 typedef _Allocator allocator_type; 169 typedef typename _Base::pointer pointer; 170 typedef typename _Base::const_pointer const_pointer; 171 typedef std::reverse_iterator<iterator> reverse_iterator; 172 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 173 174 // 23.2.4.1 construct/copy/destroy: 175 176 #if __cplusplus < 201103L 177 vector() _GLIBCXX_NOEXCEPT 178 : _Base() { } 179 #else 180 vector() = default; 181 #endif 182 183 _GLIBCXX20_CONSTEXPR 184 explicit 185 vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT 186 : _Base(__a) { } 187 188 #if __cplusplus >= 201103L 189 _GLIBCXX20_CONSTEXPR 190 explicit 191 vector(size_type __n, const _Allocator& __a = _Allocator()) 192 : _Base(__n, __a), _Safe_vector(__n) { } 193 194 _GLIBCXX20_CONSTEXPR 195 vector(size_type __n, const __type_identity_t<_Tp>& __value, 196 const _Allocator& __a = _Allocator()) 197 : _Base(__n, __value, __a) { } 198 #else 199 explicit 200 vector(size_type __n, const _Tp& __value = _Tp(), 201 const _Allocator& __a = _Allocator()) 202 : _Base(__n, __value, __a) { } 203 #endif 204 205 #if __cplusplus >= 201103L 206 template<class _InputIterator, 207 typename = std::_RequireInputIter<_InputIterator>> 208 #else 209 template<class _InputIterator> 210 #endif 211 _GLIBCXX20_CONSTEXPR 212 vector(_InputIterator __first, _InputIterator __last, 213 const _Allocator& __a = _Allocator()) 214 : _Base(__gnu_debug::__base(std::__is_constant_evaluated() ? __first 215 : __glibcxx_check_valid_constructor_range(__first, __last)), 216 __gnu_debug::__base(__last), __a) { } 217 218 #if __cplusplus < 201103L 219 vector(const vector& __x) 220 : _Base(__x) { } 221 222 ~vector() _GLIBCXX_NOEXCEPT { } 223 #else 224 vector(const vector&) = default; 225 vector(vector&&) = default; 226 227 _GLIBCXX20_CONSTEXPR 228 vector(const vector& __x, const __type_identity_t<allocator_type>& __a) 229 : _Base(__x, __a) { } 230 231 _GLIBCXX20_CONSTEXPR 232 vector(vector&& __x, const __type_identity_t<allocator_type>& __a) 233 noexcept( 234 std::is_nothrow_constructible<_Base, 235 _Base, const allocator_type&>::value ) 236 : _Safe(std::move(__x), __a), 237 _Base(std::move(__x), __a), 238 _Safe_vector(std::move(__x)) { } 239 240 _GLIBCXX20_CONSTEXPR 241 vector(initializer_list<value_type> __l, 242 const allocator_type& __a = allocator_type()) 243 : _Base(__l, __a) { } 244 245 ~vector() = default; 246 #endif 247 248 /// Construction from a normal-mode vector 249 _GLIBCXX20_CONSTEXPR 250 vector(_Base_ref __x) 251 : _Base(__x._M_ref) { } 252 253 #if __cplusplus >= 201103L 254 vector& 255 operator=(const vector&) = default; 256 257 vector& 258 operator=(vector&&) = default; 259 260 _GLIBCXX20_CONSTEXPR 261 vector& 262 operator=(initializer_list<value_type> __l) 263 { 264 _Base::operator=(__l); 265 if (!std::__is_constant_evaluated()) 266 { 267 this->_M_invalidate_all(); 268 this->_M_update_guaranteed_capacity(); 269 } 270 return *this; 271 } 272 #endif 273 274 #if __cplusplus >= 201103L 275 template<typename _InputIterator, 276 typename = std::_RequireInputIter<_InputIterator>> 277 #else 278 template<typename _InputIterator> 279 #endif 280 _GLIBCXX20_CONSTEXPR 281 void 282 assign(_InputIterator __first, _InputIterator __last) 283 { 284 if (std::__is_constant_evaluated()) 285 return _Base::assign(__gnu_debug::__unsafe(__first), 286 __gnu_debug::__unsafe(__last)); 287 288 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 289 __glibcxx_check_valid_range2(__first, __last, __dist); 290 291 if (__dist.second >= __gnu_debug::__dp_sign) 292 _Base::assign(__gnu_debug::__unsafe(__first), 293 __gnu_debug::__unsafe(__last)); 294 else 295 _Base::assign(__first, __last); 296 297 this->_M_invalidate_all(); 298 this->_M_update_guaranteed_capacity(); 299 } 300 301 _GLIBCXX20_CONSTEXPR 302 void 303 assign(size_type __n, const _Tp& __u) 304 { 305 _Base::assign(__n, __u); 306 if (!std::__is_constant_evaluated()) 307 { 308 this->_M_invalidate_all(); 309 this->_M_update_guaranteed_capacity(); 310 } 311 } 312 313 #if __cplusplus >= 201103L 314 _GLIBCXX20_CONSTEXPR 315 void 316 assign(initializer_list<value_type> __l) 317 { 318 _Base::assign(__l); 319 if (!std::__is_constant_evaluated()) 320 { 321 this->_M_invalidate_all(); 322 this->_M_update_guaranteed_capacity(); 323 } 324 } 325 #endif 326 327 using _Base::get_allocator; 328 329 // iterators: 330 _GLIBCXX_NODISCARD 331 _GLIBCXX20_CONSTEXPR 332 iterator 333 begin() _GLIBCXX_NOEXCEPT 334 { return iterator(_Base::begin(), this); } 335 336 _GLIBCXX_NODISCARD 337 _GLIBCXX20_CONSTEXPR 338 const_iterator 339 begin() const _GLIBCXX_NOEXCEPT 340 { return const_iterator(_Base::begin(), this); } 341 342 _GLIBCXX_NODISCARD 343 _GLIBCXX20_CONSTEXPR 344 iterator 345 end() _GLIBCXX_NOEXCEPT 346 { return iterator(_Base::end(), this); } 347 348 _GLIBCXX_NODISCARD 349 _GLIBCXX20_CONSTEXPR 350 const_iterator 351 end() const _GLIBCXX_NOEXCEPT 352 { return const_iterator(_Base::end(), this); } 353 354 _GLIBCXX_NODISCARD 355 _GLIBCXX20_CONSTEXPR 356 reverse_iterator 357 rbegin() _GLIBCXX_NOEXCEPT 358 { return reverse_iterator(end()); } 359 360 _GLIBCXX_NODISCARD 361 _GLIBCXX20_CONSTEXPR 362 const_reverse_iterator 363 rbegin() const _GLIBCXX_NOEXCEPT 364 { return const_reverse_iterator(end()); } 365 366 _GLIBCXX_NODISCARD 367 _GLIBCXX20_CONSTEXPR 368 reverse_iterator 369 rend() _GLIBCXX_NOEXCEPT 370 { return reverse_iterator(begin()); } 371 372 _GLIBCXX_NODISCARD 373 _GLIBCXX20_CONSTEXPR 374 const_reverse_iterator 375 rend() const _GLIBCXX_NOEXCEPT 376 { return const_reverse_iterator(begin()); } 377 378 #if __cplusplus >= 201103L 379 [[__nodiscard__]] 380 _GLIBCXX20_CONSTEXPR 381 const_iterator 382 cbegin() const noexcept 383 { return const_iterator(_Base::begin(), this); } 384 385 [[__nodiscard__]] 386 _GLIBCXX20_CONSTEXPR 387 const_iterator 388 cend() const noexcept 389 { return const_iterator(_Base::end(), this); } 390 391 [[__nodiscard__]] 392 _GLIBCXX20_CONSTEXPR 393 const_reverse_iterator 394 crbegin() const noexcept 395 { return const_reverse_iterator(end()); } 396 397 [[__nodiscard__]] 398 _GLIBCXX20_CONSTEXPR 399 const_reverse_iterator 400 crend() const noexcept 401 { return const_reverse_iterator(begin()); } 402 #endif 403 404 // 23.2.4.2 capacity: 405 using _Base::size; 406 using _Base::max_size; 407 408 #if __cplusplus >= 201103L 409 _GLIBCXX20_CONSTEXPR 410 void 411 resize(size_type __sz) 412 { 413 if (std::__is_constant_evaluated()) 414 return _Base::resize(__sz); 415 416 bool __realloc = this->_M_requires_reallocation(__sz); 417 if (__sz < this->size()) 418 this->_M_invalidate_after_nth(__sz); 419 _Base::resize(__sz); 420 if (__realloc) 421 this->_M_invalidate_all(); 422 this->_M_update_guaranteed_capacity(); 423 } 424 425 _GLIBCXX20_CONSTEXPR 426 void 427 resize(size_type __sz, const _Tp& __c) 428 { 429 if (std::__is_constant_evaluated()) 430 return _Base::resize(__sz, __c); 431 432 bool __realloc = this->_M_requires_reallocation(__sz); 433 if (__sz < this->size()) 434 this->_M_invalidate_after_nth(__sz); 435 _Base::resize(__sz, __c); 436 if (__realloc) 437 this->_M_invalidate_all(); 438 this->_M_update_guaranteed_capacity(); 439 } 440 #else 441 void 442 resize(size_type __sz, _Tp __c = _Tp()) 443 { 444 bool __realloc = this->_M_requires_reallocation(__sz); 445 if (__sz < this->size()) 446 this->_M_invalidate_after_nth(__sz); 447 _Base::resize(__sz, __c); 448 if (__realloc) 449 this->_M_invalidate_all(); 450 this->_M_update_guaranteed_capacity(); 451 } 452 #endif 453 454 #if __cplusplus >= 201103L 455 _GLIBCXX20_CONSTEXPR 456 void 457 shrink_to_fit() 458 { 459 if (std::__is_constant_evaluated()) 460 return _Base::shrink_to_fit(); 461 462 if (_Base::_M_shrink_to_fit()) 463 { 464 this->_M_guaranteed_capacity = _Base::capacity(); 465 this->_M_invalidate_all(); 466 } 467 } 468 #endif 469 470 _GLIBCXX_NODISCARD 471 _GLIBCXX20_CONSTEXPR 472 size_type 473 capacity() const _GLIBCXX_NOEXCEPT 474 { 475 if (std::__is_constant_evaluated()) 476 return _Base::capacity(); 477 478 #ifdef _GLIBCXX_DEBUG_PEDANTIC 479 return this->_M_guaranteed_capacity; 480 #else 481 return _Base::capacity(); 482 #endif 483 } 484 485 using _Base::empty; 486 487 _GLIBCXX20_CONSTEXPR 488 void 489 reserve(size_type __n) 490 { 491 if (std::__is_constant_evaluated()) 492 return _Base::reserve(__n); 493 494 bool __realloc = this->_M_requires_reallocation(__n); 495 _Base::reserve(__n); 496 if (__n > this->_M_guaranteed_capacity) 497 this->_M_guaranteed_capacity = __n; 498 if (__realloc) 499 this->_M_invalidate_all(); 500 } 501 502 // element access: 503 _GLIBCXX_NODISCARD 504 _GLIBCXX20_CONSTEXPR 505 reference 506 operator[](size_type __n) _GLIBCXX_NOEXCEPT 507 { 508 __glibcxx_check_subscript(__n); 509 return _Base::operator[](__n); 510 } 511 512 _GLIBCXX_NODISCARD 513 _GLIBCXX20_CONSTEXPR 514 const_reference 515 operator[](size_type __n) const _GLIBCXX_NOEXCEPT 516 { 517 __glibcxx_check_subscript(__n); 518 return _Base::operator[](__n); 519 } 520 521 using _Base::at; 522 523 _GLIBCXX_NODISCARD 524 _GLIBCXX20_CONSTEXPR 525 reference 526 front() _GLIBCXX_NOEXCEPT 527 { 528 __glibcxx_check_nonempty(); 529 return _Base::front(); 530 } 531 532 _GLIBCXX_NODISCARD 533 _GLIBCXX20_CONSTEXPR 534 const_reference 535 front() const _GLIBCXX_NOEXCEPT 536 { 537 __glibcxx_check_nonempty(); 538 return _Base::front(); 539 } 540 541 _GLIBCXX_NODISCARD 542 _GLIBCXX20_CONSTEXPR 543 reference 544 back() _GLIBCXX_NOEXCEPT 545 { 546 __glibcxx_check_nonempty(); 547 return _Base::back(); 548 } 549 550 _GLIBCXX_NODISCARD 551 _GLIBCXX20_CONSTEXPR 552 const_reference 553 back() const _GLIBCXX_NOEXCEPT 554 { 555 __glibcxx_check_nonempty(); 556 return _Base::back(); 557 } 558 559 // _GLIBCXX_RESOLVE_LIB_DEFECTS 560 // DR 464. Suggestion for new member functions in standard containers. 561 using _Base::data; 562 563 // 23.2.4.3 modifiers: 564 _GLIBCXX20_CONSTEXPR 565 void 566 push_back(const _Tp& __x) 567 { 568 if (std::__is_constant_evaluated()) 569 return _Base::push_back(__x); 570 571 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 572 _Base::push_back(__x); 573 if (__realloc) 574 this->_M_invalidate_all(); 575 this->_M_update_guaranteed_capacity(); 576 } 577 578 #if __cplusplus >= 201103L 579 template<typename _Up = _Tp> 580 _GLIBCXX20_CONSTEXPR 581 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 582 void>::__type 583 push_back(_Tp&& __x) 584 { emplace_back(std::move(__x)); } 585 586 template<typename... _Args> 587 _GLIBCXX20_CONSTEXPR 588 #if __cplusplus > 201402L 589 reference 590 #else 591 void 592 #endif 593 emplace_back(_Args&&... __args) 594 { 595 if (std::__is_constant_evaluated()) 596 return _Base::emplace_back(std::forward<_Args>(__args)...); 597 598 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 599 _Base::emplace_back(std::forward<_Args>(__args)...); 600 if (__realloc) 601 this->_M_invalidate_all(); 602 this->_M_update_guaranteed_capacity(); 603 #if __cplusplus > 201402L 604 return back(); 605 #endif 606 } 607 #endif 608 609 _GLIBCXX20_CONSTEXPR 610 void 611 pop_back() _GLIBCXX_NOEXCEPT 612 { 613 if (!std::__is_constant_evaluated()) 614 { 615 __glibcxx_check_nonempty(); 616 this->_M_invalidate_if(_Equal(--_Base::end())); 617 } 618 _Base::pop_back(); 619 } 620 621 #if __cplusplus >= 201103L 622 template<typename... _Args> 623 _GLIBCXX20_CONSTEXPR 624 iterator 625 emplace(const_iterator __position, _Args&&... __args) 626 { 627 if (std::__is_constant_evaluated()) 628 return iterator(_Base::emplace(__position.base(), 629 std::forward<_Args>(__args)...), 630 this); 631 632 __glibcxx_check_insert(__position); 633 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 634 difference_type __offset = __position.base() - _Base::cbegin(); 635 _Base_iterator __res = _Base::emplace(__position.base(), 636 std::forward<_Args>(__args)...); 637 if (__realloc) 638 this->_M_invalidate_all(); 639 else 640 this->_M_invalidate_after_nth(__offset); 641 this->_M_update_guaranteed_capacity(); 642 return { __res, this }; 643 } 644 #endif 645 646 _GLIBCXX20_CONSTEXPR 647 iterator 648 #if __cplusplus >= 201103L 649 insert(const_iterator __position, const _Tp& __x) 650 #else 651 insert(iterator __position, const _Tp& __x) 652 #endif 653 { 654 if (std::__is_constant_evaluated()) 655 return iterator(_Base::insert(__position.base(), __x), this); 656 657 __glibcxx_check_insert(__position); 658 bool __realloc = this->_M_requires_reallocation(this->size() + 1); 659 difference_type __offset = __position.base() - _Base::begin(); 660 _Base_iterator __res = _Base::insert(__position.base(), __x); 661 if (__realloc) 662 this->_M_invalidate_all(); 663 else 664 this->_M_invalidate_after_nth(__offset); 665 this->_M_update_guaranteed_capacity(); 666 return iterator(__res, this); 667 } 668 669 #if __cplusplus >= 201103L 670 template<typename _Up = _Tp> 671 _GLIBCXX20_CONSTEXPR 672 typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value, 673 iterator>::__type 674 insert(const_iterator __position, _Tp&& __x) 675 { return emplace(__position, std::move(__x)); } 676 677 _GLIBCXX20_CONSTEXPR 678 iterator 679 insert(const_iterator __position, initializer_list<value_type> __l) 680 { return this->insert(__position, __l.begin(), __l.end()); } 681 #endif 682 683 #if __cplusplus >= 201103L 684 _GLIBCXX20_CONSTEXPR 685 iterator 686 insert(const_iterator __position, size_type __n, const _Tp& __x) 687 { 688 if (std::__is_constant_evaluated()) 689 return iterator(_Base::insert(__position.base(), __n, __x), this); 690 691 __glibcxx_check_insert(__position); 692 bool __realloc = this->_M_requires_reallocation(this->size() + __n); 693 difference_type __offset = __position.base() - _Base::cbegin(); 694 _Base_iterator __res = _Base::insert(__position.base(), __n, __x); 695 if (__realloc) 696 this->_M_invalidate_all(); 697 else 698 this->_M_invalidate_after_nth(__offset); 699 this->_M_update_guaranteed_capacity(); 700 return { __res, this }; 701 } 702 #else 703 void 704 insert(iterator __position, size_type __n, const _Tp& __x) 705 { 706 __glibcxx_check_insert(__position); 707 bool __realloc = this->_M_requires_reallocation(this->size() + __n); 708 difference_type __offset = __position.base() - _Base::begin(); 709 _Base::insert(__position.base(), __n, __x); 710 if (__realloc) 711 this->_M_invalidate_all(); 712 else 713 this->_M_invalidate_after_nth(__offset); 714 this->_M_update_guaranteed_capacity(); 715 } 716 #endif 717 718 #if __cplusplus >= 201103L 719 template<class _InputIterator, 720 typename = std::_RequireInputIter<_InputIterator>> 721 _GLIBCXX20_CONSTEXPR 722 iterator 723 insert(const_iterator __position, 724 _InputIterator __first, _InputIterator __last) 725 { 726 if (std::__is_constant_evaluated()) 727 return iterator(_Base::insert(__position.base(), 728 __gnu_debug::__unsafe(__first), 729 __gnu_debug::__unsafe(__last)), this); 730 731 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 732 __glibcxx_check_insert_range(__position, __first, __last, __dist); 733 734 /* Hard to guess if invalidation will occur, because __last 735 - __first can't be calculated in all cases, so we just 736 punt here by checking if it did occur. */ 737 _Base_iterator __old_begin = _M_base().begin(); 738 difference_type __offset = __position.base() - _Base::cbegin(); 739 _Base_iterator __res; 740 if (__dist.second >= __gnu_debug::__dp_sign) 741 __res = _Base::insert(__position.base(), 742 __gnu_debug::__unsafe(__first), 743 __gnu_debug::__unsafe(__last)); 744 else 745 __res = _Base::insert(__position.base(), __first, __last); 746 747 if (_M_base().begin() != __old_begin) 748 this->_M_invalidate_all(); 749 else 750 this->_M_invalidate_after_nth(__offset); 751 this->_M_update_guaranteed_capacity(); 752 return { __res, this }; 753 } 754 #else 755 template<class _InputIterator> 756 void 757 insert(iterator __position, 758 _InputIterator __first, _InputIterator __last) 759 { 760 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 761 __glibcxx_check_insert_range(__position, __first, __last, __dist); 762 763 /* Hard to guess if invalidation will occur, because __last 764 - __first can't be calculated in all cases, so we just 765 punt here by checking if it did occur. */ 766 _Base_iterator __old_begin = _M_base().begin(); 767 difference_type __offset = __position.base() - _Base::begin(); 768 if (__dist.second >= __gnu_debug::__dp_sign) 769 _Base::insert(__position.base(), __gnu_debug::__unsafe(__first), 770 __gnu_debug::__unsafe(__last)); 771 else 772 _Base::insert(__position.base(), __first, __last); 773 774 if (_M_base().begin() != __old_begin) 775 this->_M_invalidate_all(); 776 else 777 this->_M_invalidate_after_nth(__offset); 778 this->_M_update_guaranteed_capacity(); 779 } 780 #endif 781 782 _GLIBCXX20_CONSTEXPR 783 iterator 784 #if __cplusplus >= 201103L 785 erase(const_iterator __position) 786 #else 787 erase(iterator __position) 788 #endif 789 { 790 if (std::__is_constant_evaluated()) 791 return iterator(_Base::erase(__position.base()), this); 792 793 __glibcxx_check_erase(__position); 794 difference_type __offset = __position.base() - _Base::begin(); 795 _Base_iterator __res = _Base::erase(__position.base()); 796 this->_M_invalidate_after_nth(__offset); 797 return iterator(__res, this); 798 } 799 800 _GLIBCXX20_CONSTEXPR 801 iterator 802 #if __cplusplus >= 201103L 803 erase(const_iterator __first, const_iterator __last) 804 #else 805 erase(iterator __first, iterator __last) 806 #endif 807 { 808 if (std::__is_constant_evaluated()) 809 return iterator(_Base::erase(__first.base(), __last.base()), this); 810 811 // _GLIBCXX_RESOLVE_LIB_DEFECTS 812 // 151. can't currently clear() empty container 813 __glibcxx_check_erase_range(__first, __last); 814 815 if (__first.base() != __last.base()) 816 { 817 difference_type __offset = __first.base() - _Base::begin(); 818 _Base_iterator __res = _Base::erase(__first.base(), 819 __last.base()); 820 this->_M_invalidate_after_nth(__offset); 821 return iterator(__res, this); 822 } 823 else 824 #if __cplusplus >= 201103L 825 return { _Base::begin() + (__first.base() - _Base::cbegin()), this }; 826 #else 827 return __first; 828 #endif 829 } 830 831 _GLIBCXX20_CONSTEXPR 832 void 833 swap(vector& __x) 834 _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) 835 { 836 if (!std::__is_constant_evaluated()) 837 _Safe::_M_swap(__x); 838 _Base::swap(__x); 839 std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity); 840 } 841 842 _GLIBCXX20_CONSTEXPR 843 void 844 clear() _GLIBCXX_NOEXCEPT 845 { 846 _Base::clear(); 847 if (!std::__is_constant_evaluated()) 848 this->_M_invalidate_all(); 849 } 850 851 _GLIBCXX20_CONSTEXPR 852 _Base& 853 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 854 855 _GLIBCXX20_CONSTEXPR 856 const _Base& 857 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 858 859 private: 860 void 861 _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT 862 { 863 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; 864 this->_M_invalidate_if(_After_nth(__n, _Base::begin())); 865 } 866 }; 867 868 template<typename _Tp, typename _Alloc> 869 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR 870 inline bool 871 operator==(const vector<_Tp, _Alloc>& __lhs, 872 const vector<_Tp, _Alloc>& __rhs) 873 { return __lhs._M_base() == __rhs._M_base(); } 874 875 #if __cpp_lib_three_way_comparison 876 template<typename _Tp, typename _Alloc> 877 [[nodiscard]] 878 constexpr __detail::__synth3way_t<_Tp> 879 operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 880 { return __x._M_base() <=> __y._M_base(); } 881 #else 882 template<typename _Tp, typename _Alloc> 883 _GLIBCXX_NODISCARD 884 inline bool 885 operator!=(const vector<_Tp, _Alloc>& __lhs, 886 const vector<_Tp, _Alloc>& __rhs) 887 { return __lhs._M_base() != __rhs._M_base(); } 888 889 template<typename _Tp, typename _Alloc> 890 _GLIBCXX_NODISCARD 891 inline bool 892 operator<(const vector<_Tp, _Alloc>& __lhs, 893 const vector<_Tp, _Alloc>& __rhs) 894 { return __lhs._M_base() < __rhs._M_base(); } 895 896 template<typename _Tp, typename _Alloc> 897 _GLIBCXX_NODISCARD 898 inline bool 899 operator<=(const vector<_Tp, _Alloc>& __lhs, 900 const vector<_Tp, _Alloc>& __rhs) 901 { return __lhs._M_base() <= __rhs._M_base(); } 902 903 template<typename _Tp, typename _Alloc> 904 _GLIBCXX_NODISCARD 905 inline bool 906 operator>=(const vector<_Tp, _Alloc>& __lhs, 907 const vector<_Tp, _Alloc>& __rhs) 908 { return __lhs._M_base() >= __rhs._M_base(); } 909 910 template<typename _Tp, typename _Alloc> 911 _GLIBCXX_NODISCARD 912 inline bool 913 operator>(const vector<_Tp, _Alloc>& __lhs, 914 const vector<_Tp, _Alloc>& __rhs) 915 { return __lhs._M_base() > __rhs._M_base(); } 916 #endif // three-way comparison 917 918 template<typename _Tp, typename _Alloc> 919 _GLIBCXX20_CONSTEXPR 920 inline void 921 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) 922 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) 923 { __lhs.swap(__rhs); } 924 925 #if __cpp_deduction_guides >= 201606 926 template<typename _InputIterator, typename _ValT 927 = typename iterator_traits<_InputIterator>::value_type, 928 typename _Allocator = allocator<_ValT>, 929 typename = _RequireInputIter<_InputIterator>, 930 typename = _RequireAllocator<_Allocator>> 931 vector(_InputIterator, _InputIterator, _Allocator = _Allocator()) 932 -> vector<_ValT, _Allocator>; 933 934 template<typename _Tp, typename _Allocator = allocator<_Tp>, 935 typename = _RequireAllocator<_Allocator>> 936 vector(size_t, _Tp, _Allocator = _Allocator()) 937 -> vector<_Tp, _Allocator>; 938 #endif 939 940 } // namespace __debug 941 942 _GLIBCXX_BEGIN_NAMESPACE_VERSION 943 944 #if __cplusplus >= 201103L 945 // DR 1182. 946 /// std::hash specialization for vector<bool>. 947 template<typename _Alloc> 948 struct hash<__debug::vector<bool, _Alloc>> 949 : public __hash_base<size_t, __debug::vector<bool, _Alloc>> 950 { 951 size_t 952 operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept 953 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); } 954 }; 955 #endif 956 957 #if __cplusplus >= 201703L 958 namespace __detail::__variant 959 { 960 template<typename> struct _Never_valueless_alt; // see <variant> 961 962 // Provide the strong exception-safety guarantee when emplacing a 963 // vector into a variant, but only if move assignment cannot throw. 964 template<typename _Tp, typename _Alloc> 965 struct _Never_valueless_alt<__debug::vector<_Tp, _Alloc>> 966 : std::is_nothrow_move_assignable<__debug::vector<_Tp, _Alloc>> 967 { }; 968 } // namespace __detail::__variant 969 #endif // C++17 970 971 _GLIBCXX_END_NAMESPACE_VERSION 972 } // namespace std 973 974 namespace __gnu_debug 975 { 976 template<typename _Tp, typename _Alloc> 977 struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> > 978 : std::__true_type 979 { }; 980 981 template<typename _Alloc> 982 struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> > 983 : std::__false_type 984 { }; 985 } 986 987 #endif 988