Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/debug/safe_iterator.h
$ cat -n /usr/include/c++/13/debug/safe_iterator.h 1 // Safe iterator implementation -*- C++ -*- 2 3 // Copyright (C) 2003-2023 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 //
. 24 25 /** @file debug/safe_iterator.h 26 * This file is a GNU debug extension to the Standard C++ Library. 27 */ 28 29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 31 32 #include
33 #include
34 #include
35 #include
36 #include
37 #include
38 #if __cplusplus > 201703L 39 # include
40 #endif 41 42 #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \ 43 _GLIBCXX_DEBUG_VERIFY((!_Lhs._M_singular() && !_Rhs._M_singular()) \ 44 || (_Lhs._M_value_initialized() \ 45 && _Rhs._M_value_initialized()), \ 46 _M_message(_BadMsgId) \ 47 ._M_iterator(_Lhs, #_Lhs) \ 48 ._M_iterator(_Rhs, #_Rhs)); \ 49 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \ 50 _M_message(_DiffMsgId) \ 51 ._M_iterator(_Lhs, #_Lhs) \ 52 ._M_iterator(_Rhs, #_Rhs)) 53 54 #define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \ 55 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \ 56 __msg_compare_different) 57 58 #define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \ 59 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \ 60 __msg_order_different) 61 62 #define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \ 63 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \ 64 __msg_distance_different) 65 66 namespace __gnu_debug 67 { 68 /** Helper struct to deal with sequence offering a before_begin 69 * iterator. 70 **/ 71 template
72 struct _BeforeBeginHelper 73 { 74 template
75 static bool 76 _S_Is(const _Safe_iterator<_Iterator, _Sequence, _Category>&) 77 { return false; } 78 79 template
80 static bool 81 _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it) 82 { return __it.base() == __it._M_get_sequence()->_M_base().begin(); } 83 }; 84 85 /** Sequence traits giving the size of a container if possible. */ 86 template
87 struct _Sequence_traits 88 { 89 typedef _Distance_traits
_DistTraits; 90 91 static typename _DistTraits::__type 92 _S_size(const _Sequence& __seq) 93 { return std::make_pair(__seq.size(), __dp_exact); } 94 }; 95 96 /** \brief Safe iterator wrapper. 97 * 98 * The class template %_Safe_iterator is a wrapper around an 99 * iterator that tracks the iterator's movement among sequences and 100 * checks that operations performed on the "safe" iterator are 101 * legal. In additional to the basic iterator operations (which are 102 * validated, and then passed to the underlying iterator), 103 * %_Safe_iterator has member functions for iterator invalidation, 104 * attaching/detaching the iterator from sequences, and querying 105 * the iterator's state. 106 * 107 * Note that _Iterator must be the first base class so that it gets 108 * initialized before the iterator is being attached to the container's list 109 * of iterators and it is being detached before _Iterator get 110 * destroyed. Otherwise it would result in a data race. 111 */ 112 template
::iterator_category> 114 class _Safe_iterator 115 : private _Iterator, 116 public _Safe_iterator_base 117 { 118 typedef _Iterator _Iter_base; 119 typedef _Safe_iterator_base _Safe_base; 120 121 typedef std::iterator_traits<_Iterator> _Traits; 122 123 protected: 124 typedef std::__are_same
_IsConstant; 126 127 typedef typename __gnu_cxx::__conditional_type< 128 _IsConstant::__value, 129 typename _Sequence::_Base::iterator, 130 typename _Sequence::_Base::const_iterator>::__type _OtherIterator; 131 132 struct _Unchecked { }; 133 134 _Safe_iterator(const _Safe_iterator& __x, _Unchecked) _GLIBCXX_NOEXCEPT 135 : _Iter_base(__x.base()), _Safe_base() 136 { _M_attach(__x._M_sequence); } 137 138 public: 139 typedef _Iterator iterator_type; 140 typedef typename _Traits::iterator_category iterator_category; 141 typedef typename _Traits::value_type value_type; 142 typedef typename _Traits::difference_type difference_type; 143 typedef typename _Traits::reference reference; 144 typedef typename _Traits::pointer pointer; 145 146 #if __cplusplus > 201703L && __cpp_lib_concepts 147 using iterator_concept = std::__detail::__iter_concept<_Iterator>; 148 #endif 149 150 /// @post the iterator is singular and unattached 151 _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { } 152 153 /** 154 * @brief Safe iterator construction from an unsafe iterator and 155 * its sequence. 156 * 157 * @pre @p seq is not NULL 158 * @post this is not singular 159 */ 160 _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq) 161 _GLIBCXX_NOEXCEPT 162 : _Iter_base(__i), _Safe_base(__seq, _S_constant()) 163 { } 164 165 /** 166 * @brief Copy construction. 167 */ 168 _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 169 : _Iter_base(__x.base()), _Safe_base() 170 { 171 // _GLIBCXX_RESOLVE_LIB_DEFECTS 172 // DR 408. Is vector
> forbidden? 173 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 174 || __x._M_value_initialized(), 175 _M_message(__msg_init_copy_singular) 176 ._M_iterator(*this, "this") 177 ._M_iterator(__x, "other")); 178 _M_attach(__x._M_sequence); 179 } 180 181 #if __cplusplus >= 201103L 182 /** 183 * @brief Move construction. 184 * @post __x is singular and unattached 185 */ 186 _Safe_iterator(_Safe_iterator&& __x) noexcept 187 : _Iter_base() 188 { 189 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 190 || __x._M_value_initialized(), 191 _M_message(__msg_init_copy_singular) 192 ._M_iterator(*this, "this") 193 ._M_iterator(__x, "other")); 194 _Safe_sequence_base* __seq = __x._M_sequence; 195 __x._M_detach(); 196 std::swap(base(), __x.base()); 197 _M_attach(__seq); 198 } 199 #endif 200 201 /** 202 * @brief Converting constructor from a mutable iterator to a 203 * constant iterator. 204 */ 205 template
206 _Safe_iterator( 207 const _Safe_iterator<_MutableIterator, _Sequence, 208 typename __gnu_cxx::__enable_if<_IsConstant::__value && 209 std::__are_same<_MutableIterator, _OtherIterator>::__value, 210 _Category>::__type>& __x) 211 _GLIBCXX_NOEXCEPT 212 : _Iter_base(__x.base()) 213 { 214 // _GLIBCXX_RESOLVE_LIB_DEFECTS 215 // DR 408. Is vector
> forbidden? 216 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 217 || __x._M_value_initialized(), 218 _M_message(__msg_init_const_singular) 219 ._M_iterator(*this, "this") 220 ._M_iterator(__x, "other")); 221 _M_attach(__x._M_sequence); 222 } 223 224 /** 225 * @brief Copy assignment. 226 */ 227 _Safe_iterator& 228 operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 229 { 230 // _GLIBCXX_RESOLVE_LIB_DEFECTS 231 // DR 408. Is vector
> forbidden? 232 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 233 || __x._M_value_initialized(), 234 _M_message(__msg_copy_singular) 235 ._M_iterator(*this, "this") 236 ._M_iterator(__x, "other")); 237 238 if (this->_M_sequence && this->_M_sequence == __x._M_sequence) 239 { 240 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 241 base() = __x.base(); 242 _M_version = __x._M_sequence->_M_version; 243 } 244 else 245 { 246 _M_detach(); 247 base() = __x.base(); 248 _M_attach(__x._M_sequence); 249 } 250 251 return *this; 252 } 253 254 #if __cplusplus >= 201103L 255 /** 256 * @brief Move assignment. 257 * @post __x is singular and unattached 258 */ 259 _Safe_iterator& 260 operator=(_Safe_iterator&& __x) noexcept 261 { 262 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 263 || __x._M_value_initialized(), 264 _M_message(__msg_copy_singular) 265 ._M_iterator(*this, "this") 266 ._M_iterator(__x, "other")); 267 268 if (std::__addressof(__x) == this) 269 return *this; 270 271 if (this->_M_sequence && this->_M_sequence == __x._M_sequence) 272 { 273 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 274 base() = __x.base(); 275 _M_version = __x._M_sequence->_M_version; 276 } 277 else 278 { 279 _M_detach(); 280 base() = __x.base(); 281 _M_attach(__x._M_sequence); 282 } 283 284 __x._M_detach(); 285 __x.base() = _Iterator(); 286 return *this; 287 } 288 #endif 289 290 /** 291 * @brief Iterator dereference. 292 * @pre iterator is dereferenceable 293 */ 294 _GLIBCXX_NODISCARD 295 reference 296 operator*() const _GLIBCXX_NOEXCEPT 297 { 298 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 299 _M_message(__msg_bad_deref) 300 ._M_iterator(*this, "this")); 301 return *base(); 302 } 303 304 /** 305 * @brief Iterator dereference. 306 * @pre iterator is dereferenceable 307 */ 308 _GLIBCXX_NODISCARD 309 pointer 310 operator->() const _GLIBCXX_NOEXCEPT 311 { 312 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 313 _M_message(__msg_bad_deref) 314 ._M_iterator(*this, "this")); 315 return base().operator->(); 316 } 317 318 // ------ Input iterator requirements ------ 319 /** 320 * @brief Iterator preincrement 321 * @pre iterator is incrementable 322 */ 323 _Safe_iterator& 324 operator++() _GLIBCXX_NOEXCEPT 325 { 326 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 327 _M_message(__msg_bad_inc) 328 ._M_iterator(*this, "this")); 329 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 330 ++base(); 331 return *this; 332 } 333 334 /** 335 * @brief Iterator postincrement 336 * @pre iterator is incrementable 337 */ 338 _Safe_iterator 339 operator++(int) _GLIBCXX_NOEXCEPT 340 { 341 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 342 _M_message(__msg_bad_inc) 343 ._M_iterator(*this, "this")); 344 _Safe_iterator __ret(*this, _Unchecked()); 345 ++*this; 346 return __ret; 347 } 348 349 // ------ Utilities ------ 350 351 /// Determine if this is a constant iterator. 352 static _GLIBCXX_CONSTEXPR bool 353 _S_constant() 354 { return _IsConstant::__value; } 355 356 /** 357 * @brief Return the underlying iterator 358 */ 359 _Iterator& 360 base() _GLIBCXX_NOEXCEPT { return *this; } 361 362 const _Iterator& 363 base() const _GLIBCXX_NOEXCEPT { return *this; } 364 365 /** 366 * @brief Conversion to underlying non-debug iterator to allow 367 * better interaction with non-debug containers. 368 */ 369 operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; } 370 371 /** Attach iterator to the given sequence. */ 372 void 373 _M_attach(_Safe_sequence_base* __seq) 374 { _Safe_base::_M_attach(__seq, _S_constant()); } 375 376 /** Likewise, but not thread-safe. */ 377 void 378 _M_attach_single(_Safe_sequence_base* __seq) 379 { _Safe_base::_M_attach_single(__seq, _S_constant()); } 380 381 /// Is the iterator dereferenceable? 382 bool 383 _M_dereferenceable() const 384 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); } 385 386 /// Is the iterator before a dereferenceable one? 387 bool 388 _M_before_dereferenceable() const 389 { 390 if (this->_M_incrementable()) 391 { 392 _Iterator __base = base(); 393 return ++__base != _M_get_sequence()->_M_base().end(); 394 } 395 return false; 396 } 397 398 /// Is the iterator incrementable? 399 bool 400 _M_incrementable() const 401 { return !this->_M_singular() && !_M_is_end(); } 402 403 /// Is the iterator value-initialized? 404 bool 405 _M_value_initialized() const 406 { return _M_version == 0 && base() == _Iter_base(); } 407 408 // Can we advance the iterator @p __n steps (@p __n may be negative) 409 bool 410 _M_can_advance(difference_type __n, bool __strict = false) const; 411 412 // Can we advance the iterator using @p __dist in @p __way direction. 413 template
414 bool 415 _M_can_advance(const std::pair<_Diff, _Distance_precision>& __dist, 416 int __way) const; 417 418 // Is the iterator range [*this, __rhs) valid? 419 bool 420 _M_valid_range(const _Safe_iterator& __rhs, 421 std::pair
& __dist, 422 bool __check_dereferenceable = true) const; 423 424 // The sequence this iterator references. 425 typename __gnu_cxx::__conditional_type< 426 _IsConstant::__value, const _Sequence*, _Sequence*>::__type 427 _M_get_sequence() const 428 { return static_cast<_Sequence*>(_M_sequence); } 429 430 // Get distance to __rhs. 431 typename _Distance_traits<_Iterator>::__type 432 _M_get_distance_to(const _Safe_iterator& __rhs) const; 433 434 // Get distance from sequence begin up to *this. 435 typename _Distance_traits<_Iterator>::__type 436 _M_get_distance_from_begin() const; 437 438 // Get distance from *this to sequence end. 439 typename _Distance_traits<_Iterator>::__type 440 _M_get_distance_to_end() const; 441 442 /// Is this iterator equal to the sequence's begin() iterator? 443 bool 444 _M_is_begin() const 445 { return base() == _M_get_sequence()->_M_base().begin(); } 446 447 /// Is this iterator equal to the sequence's end() iterator? 448 bool 449 _M_is_end() const 450 { return base() == _M_get_sequence()->_M_base().end(); } 451 452 /// Is this iterator equal to the sequence's before_begin() iterator if 453 /// any? 454 bool 455 _M_is_before_begin() const 456 { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); } 457 458 /// Is this iterator equal to the sequence's before_begin() iterator if 459 /// any or begin() otherwise? 460 bool 461 _M_is_beginnest() const 462 { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); } 463 464 // ------ Operators ------ 465 466 typedef _Safe_iterator<_Iterator, _Sequence, iterator_category> _Self; 467 468 _GLIBCXX_NODISCARD 469 friend bool 470 operator==(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 471 { 472 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs); 473 return __lhs.base() == __rhs.base(); 474 } 475 476 template
477 _GLIBCXX_NODISCARD 478 friend bool 479 operator==(const _Self& __lhs, 480 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs) 481 _GLIBCXX_NOEXCEPT 482 { 483 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs); 484 return __lhs.base() == __rhs.base(); 485 } 486 487 #if ! __cpp_lib_three_way_comparison 488 _GLIBCXX_NODISCARD 489 friend bool 490 operator!=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 491 { 492 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs); 493 return __lhs.base() != __rhs.base(); 494 } 495 496 template
497 _GLIBCXX_NODISCARD 498 friend bool 499 operator!=(const _Self& __lhs, 500 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs) 501 _GLIBCXX_NOEXCEPT 502 { 503 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs); 504 return __lhs.base() != __rhs.base(); 505 } 506 #endif // three-way comparison 507 }; 508 509 template
510 class _Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag> 511 : public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag> 512 { 513 typedef _Safe_iterator<_Iterator, _Sequence, 514 std::forward_iterator_tag> _Safe_base; 515 516 protected: 517 typedef typename _Safe_base::_OtherIterator _OtherIterator; 518 519 typedef typename _Safe_base::_Unchecked _Unchecked; 520 521 _Safe_iterator(const _Safe_iterator& __x, 522 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT 523 : _Safe_base(__x, __unchecked) 524 { } 525 526 public: 527 /// @post the iterator is singular and unattached 528 _Safe_iterator() _GLIBCXX_NOEXCEPT { } 529 530 /** 531 * @brief Safe iterator construction from an unsafe iterator and 532 * its sequence. 533 * 534 * @pre @p seq is not NULL 535 * @post this is not singular 536 */ 537 _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq) 538 _GLIBCXX_NOEXCEPT 539 : _Safe_base(__i, __seq) 540 { } 541 542 /** 543 * @brief Copy construction. 544 */ 545 _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 546 : _Safe_base(__x) 547 { } 548 549 #if __cplusplus >= 201103L 550 /** @brief Move construction. */ 551 _Safe_iterator(_Safe_iterator&&) = default; 552 #endif 553 554 /** 555 * @brief Converting constructor from a mutable iterator to a 556 * constant iterator. 557 */ 558 template
559 _Safe_iterator( 560 const _Safe_iterator<_MutableIterator, _Sequence, 561 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value && 562 std::__are_same<_MutableIterator, _OtherIterator>::__value, 563 std::bidirectional_iterator_tag>::__type>& __x) 564 _GLIBCXX_NOEXCEPT 565 : _Safe_base(__x) 566 { } 567 568 #if __cplusplus >= 201103L 569 /** @brief Copy assignment. */ 570 _Safe_iterator& 571 operator=(const _Safe_iterator&) = default; 572 573 /** @brief Move assignment. */ 574 _Safe_iterator& 575 operator=(_Safe_iterator&&) = default; 576 #else 577 /** @brief Copy assignment. */ 578 _Safe_iterator& 579 operator=(const _Safe_iterator& __x) 580 { 581 _Safe_base::operator=(__x); 582 return *this; 583 } 584 #endif 585 586 // ------ Input iterator requirements ------ 587 /** 588 * @brief Iterator preincrement 589 * @pre iterator is incrementable 590 */ 591 _Safe_iterator& 592 operator++() _GLIBCXX_NOEXCEPT 593 { 594 _Safe_base::operator++(); 595 return *this; 596 } 597 598 /** 599 * @brief Iterator postincrement 600 * @pre iterator is incrementable 601 */ 602 _Safe_iterator 603 operator++(int) _GLIBCXX_NOEXCEPT 604 { 605 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 606 _M_message(__msg_bad_inc) 607 ._M_iterator(*this, "this")); 608 _Safe_iterator __ret(*this, _Unchecked()); 609 ++*this; 610 return __ret; 611 } 612 613 // ------ Bidirectional iterator requirements ------ 614 /** 615 * @brief Iterator predecrement 616 * @pre iterator is decrementable 617 */ 618 _Safe_iterator& 619 operator--() _GLIBCXX_NOEXCEPT 620 { 621 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 622 _M_message(__msg_bad_dec) 623 ._M_iterator(*this, "this")); 624 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 625 --this->base(); 626 return *this; 627 } 628 629 /** 630 * @brief Iterator postdecrement 631 * @pre iterator is decrementable 632 */ 633 _Safe_iterator 634 operator--(int) _GLIBCXX_NOEXCEPT 635 { 636 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 637 _M_message(__msg_bad_dec) 638 ._M_iterator(*this, "this")); 639 _Safe_iterator __ret(*this, _Unchecked()); 640 --*this; 641 return __ret; 642 } 643 644 // ------ Utilities ------ 645 646 // Is the iterator decrementable? 647 bool 648 _M_decrementable() const 649 { return !this->_M_singular() && !this->_M_is_begin(); } 650 }; 651 652 template
653 class _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag> 654 : public _Safe_iterator<_Iterator, _Sequence, 655 std::bidirectional_iterator_tag> 656 { 657 typedef _Safe_iterator<_Iterator, _Sequence, 658 std::bidirectional_iterator_tag> _Safe_base; 659 typedef typename _Safe_base::_OtherIterator _OtherIterator; 660 661 typedef typename _Safe_base::_Self _Self; 662 typedef _Safe_iterator<_OtherIterator, _Sequence, 663 std::random_access_iterator_tag> _OtherSelf; 664 665 typedef typename _Safe_base::_Unchecked _Unchecked; 666 _Safe_iterator(const _Safe_iterator& __x, 667 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT 668 : _Safe_base(__x, __unchecked) 669 { } 670 671 public: 672 typedef typename _Safe_base::difference_type difference_type; 673 typedef typename _Safe_base::reference reference; 674 675 /// @post the iterator is singular and unattached 676 _Safe_iterator() _GLIBCXX_NOEXCEPT { } 677 678 /** 679 * @brief Safe iterator construction from an unsafe iterator and 680 * its sequence. 681 * 682 * @pre @p seq is not NULL 683 * @post this is not singular 684 */ 685 _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq) 686 _GLIBCXX_NOEXCEPT 687 : _Safe_base(__i, __seq) 688 { } 689 690 /** 691 * @brief Copy construction. 692 */ 693 _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 694 : _Safe_base(__x) 695 { } 696 697 #if __cplusplus >= 201103L 698 /** @brief Move construction. */ 699 _Safe_iterator(_Safe_iterator&&) = default; 700 #endif 701 702 /** 703 * @brief Converting constructor from a mutable iterator to a 704 * constant iterator. 705 */ 706 template
707 _Safe_iterator( 708 const _Safe_iterator<_MutableIterator, _Sequence, 709 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value && 710 std::__are_same<_MutableIterator, _OtherIterator>::__value, 711 std::random_access_iterator_tag>::__type>& __x) 712 _GLIBCXX_NOEXCEPT 713 : _Safe_base(__x) 714 { } 715 716 #if __cplusplus >= 201103L 717 /** @brief Copy assignment. */ 718 _Safe_iterator& 719 operator=(const _Safe_iterator&) = default; 720 721 /** @brief Move assignment. */ 722 _Safe_iterator& 723 operator=(_Safe_iterator&&) = default; 724 #else 725 /** @brief Copy assignment. */ 726 _Safe_iterator& 727 operator=(const _Safe_iterator& __x) 728 { 729 _Safe_base::operator=(__x); 730 return *this; 731 } 732 #endif 733 734 // Is the iterator range [*this, __rhs) valid? 735 bool 736 _M_valid_range(const _Safe_iterator& __rhs, 737 std::pair
& __dist) const; 739 740 // ------ Input iterator requirements ------ 741 /** 742 * @brief Iterator preincrement 743 * @pre iterator is incrementable 744 */ 745 _Safe_iterator& 746 operator++() _GLIBCXX_NOEXCEPT 747 { 748 _Safe_base::operator++(); 749 return *this; 750 } 751 752 /** 753 * @brief Iterator postincrement 754 * @pre iterator is incrementable 755 */ 756 _Safe_iterator 757 operator++(int) _GLIBCXX_NOEXCEPT 758 { 759 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 760 _M_message(__msg_bad_inc) 761 ._M_iterator(*this, "this")); 762 _Safe_iterator __ret(*this, _Unchecked()); 763 ++*this; 764 return __ret; 765 } 766 767 // ------ Bidirectional iterator requirements ------ 768 /** 769 * @brief Iterator predecrement 770 * @pre iterator is decrementable 771 */ 772 _Safe_iterator& 773 operator--() _GLIBCXX_NOEXCEPT 774 { 775 _Safe_base::operator--(); 776 return *this; 777 } 778 779 /** 780 * @brief Iterator postdecrement 781 * @pre iterator is decrementable 782 */ 783 _Safe_iterator 784 operator--(int) _GLIBCXX_NOEXCEPT 785 { 786 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 787 _M_message(__msg_bad_dec) 788 ._M_iterator(*this, "this")); 789 _Safe_iterator __ret(*this, _Unchecked()); 790 --*this; 791 return __ret; 792 } 793 794 // ------ Random access iterator requirements ------ 795 _GLIBCXX_NODISCARD 796 reference 797 operator[](difference_type __n) const _GLIBCXX_NOEXCEPT 798 { 799 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 800 && this->_M_can_advance(__n + 1), 801 _M_message(__msg_iter_subscript_oob) 802 ._M_iterator(*this)._M_integer(__n)); 803 return this->base()[__n]; 804 } 805 806 _Safe_iterator& 807 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT 808 { 809 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 810 _M_message(__msg_advance_oob) 811 ._M_iterator(*this)._M_integer(__n)); 812 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 813 this->base() += __n; 814 return *this; 815 } 816 817 _Safe_iterator& 818 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT 819 { 820 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 821 _M_message(__msg_retreat_oob) 822 ._M_iterator(*this)._M_integer(__n)); 823 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 824 this->base() -= __n; 825 return *this; 826 } 827 828 #if __cpp_lib_three_way_comparison 829 [[nodiscard]] 830 friend auto 831 operator<=>(const _Self& __lhs, const _Self& __rhs) noexcept 832 { 833 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 834 return __lhs.base() <=> __rhs.base(); 835 } 836 837 [[nodiscard]] 838 friend auto 839 operator<=>(const _Self& __lhs, const _OtherSelf& __rhs) noexcept 840 { 841 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 842 return __lhs.base() <=> __rhs.base(); 843 } 844 #else 845 _GLIBCXX_NODISCARD 846 friend bool 847 operator<(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 848 { 849 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 850 return __lhs.base() < __rhs.base(); 851 } 852 853 _GLIBCXX_NODISCARD 854 friend bool 855 operator<(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT 856 { 857 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 858 return __lhs.base() < __rhs.base(); 859 } 860 861 _GLIBCXX_NODISCARD 862 friend bool 863 operator<=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 864 { 865 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 866 return __lhs.base() <= __rhs.base(); 867 } 868 869 _GLIBCXX_NODISCARD 870 friend bool 871 operator<=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT 872 { 873 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 874 return __lhs.base() <= __rhs.base(); 875 } 876 877 _GLIBCXX_NODISCARD 878 friend bool 879 operator>(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 880 { 881 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 882 return __lhs.base() > __rhs.base(); 883 } 884 885 _GLIBCXX_NODISCARD 886 friend bool 887 operator>(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT 888 { 889 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 890 return __lhs.base() > __rhs.base(); 891 } 892 893 _GLIBCXX_NODISCARD 894 friend bool 895 operator>=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 896 { 897 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 898 return __lhs.base() >= __rhs.base(); 899 } 900 901 _GLIBCXX_NODISCARD 902 friend bool 903 operator>=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT 904 { 905 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs); 906 return __lhs.base() >= __rhs.base(); 907 } 908 #endif // three-way comparison 909 910 // _GLIBCXX_RESOLVE_LIB_DEFECTS 911 // According to the resolution of DR179 not only the various comparison 912 // operators but also operator- must accept mixed iterator/const_iterator 913 // parameters. 914 _GLIBCXX_NODISCARD 915 friend difference_type 916 operator-(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT 917 { 918 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs); 919 return __lhs.base() - __rhs.base(); 920 } 921 922 _GLIBCXX_NODISCARD 923 friend difference_type 924 operator-(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT 925 { 926 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs); 927 return __lhs.base() - __rhs.base(); 928 } 929 930 _GLIBCXX_NODISCARD 931 friend _Self 932 operator+(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT 933 { 934 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n), 935 _M_message(__msg_advance_oob) 936 ._M_iterator(__x)._M_integer(__n)); 937 return _Safe_iterator(__x.base() + __n, __x._M_sequence); 938 } 939 940 _GLIBCXX_NODISCARD 941 friend _Self 942 operator+(difference_type __n, const _Self& __x) _GLIBCXX_NOEXCEPT 943 { 944 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n), 945 _M_message(__msg_advance_oob) 946 ._M_iterator(__x)._M_integer(__n)); 947 return _Safe_iterator(__n + __x.base(), __x._M_sequence); 948 } 949 950 _GLIBCXX_NODISCARD 951 friend _Self 952 operator-(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT 953 { 954 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n), 955 _M_message(__msg_retreat_oob) 956 ._M_iterator(__x)._M_integer(__n)); 957 return _Safe_iterator(__x.base() - __n, __x._M_sequence); 958 } 959 }; 960 961 /** Safe iterators know how to check if they form a valid range. */ 962 template
963 inline bool 964 __valid_range(const _Safe_iterator<_Iterator, _Sequence, 965 _Category>& __first, 966 const _Safe_iterator<_Iterator, _Sequence, 967 _Category>& __last, 968 typename _Distance_traits<_Iterator>::__type& __dist) 969 { return __first._M_valid_range(__last, __dist); } 970 971 template
972 inline bool 973 __valid_range(const _Safe_iterator<_Iterator, _Sequence, 974 _Category>& __first, 975 const _Safe_iterator<_Iterator, _Sequence, 976 _Category>& __last) 977 { 978 typename _Distance_traits<_Iterator>::__type __dist; 979 return __first._M_valid_range(__last, __dist); 980 } 981 982 template
984 inline bool 985 __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, 986 _Size __n) 987 { return __it._M_can_advance(__n); } 988 989 template
991 inline bool 992 __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, 993 const std::pair<_Diff, _Distance_precision>& __dist, 994 int __way) 995 { return __it._M_can_advance(__dist, __way); } 996 997 template
998 _Iterator 999 __base(const _Safe_iterator<_Iterator, _Sequence, 1000 std::random_access_iterator_tag>& __it) 1001 { return __it.base(); } 1002 1003 #if __cplusplus < 201103L 1004 template
1005 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> > 1006 { typedef _Iterator _Type; }; 1007 #endif 1008 1009 template
1010 inline _Iterator 1011 __unsafe(const _Safe_iterator<_Iterator, _Sequence>& __it) 1012 { return __it.base(); } 1013 1014 } // namespace __gnu_debug 1015 1016 #if __cplusplus >= 201103L && __cplusplus <= 201703L 1017 namespace std _GLIBCXX_VISIBILITY(default) 1018 { 1019 _GLIBCXX_BEGIN_NAMESPACE_VERSION 1020 1021 template
1022 constexpr auto 1023 __to_address(const __gnu_debug::_Safe_iterator< 1024 __gnu_cxx::__normal_iterator<_Iterator, _Container>, 1025 _Sequence>& __it) noexcept 1026 -> decltype(std::__to_address(__it.base().base())) 1027 { return std::__to_address(__it.base().base()); } 1028 1029 _GLIBCXX_END_NAMESPACE_VERSION 1030 } 1031 #endif 1032 1033 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS 1034 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS 1035 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS 1036 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS 1037 1038 #include
1039 1040 #endif
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™