1// Safe iterator implementation -*- C++ -*- 2 3// Copyright (C) 2003, 2004, 2005, 2006, 2009 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// Under Section 7 of GPL version 3, you are granted additional 18// permissions described in the GCC Runtime Library Exception, version 19// 3.1, as published by the Free Software Foundation. 20 21// You should have received a copy of the GNU General Public License and 22// a copy of the GCC Runtime Library Exception along with this program; 23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24// <http://www.gnu.org/licenses/>. 25 26/** @file debug/safe_iterator.h 27 * This file is a GNU debug extension to the Standard C++ Library. 28 */ 29 30#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 31#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 32 33#include <debug/debug.h> 34#include <debug/macros.h> 35#include <debug/functions.h> 36#include <debug/formatter.h> 37#include <debug/safe_base.h> 38#include <bits/stl_pair.h> 39#include <ext/type_traits.h> 40 41namespace __gnu_debug 42{ 43 /** Iterators that derive from _Safe_iterator_base but that aren't 44 * _Safe_iterators can be determined singular or non-singular via 45 * _Safe_iterator_base. 46 */ 47 inline bool 48 __check_singular_aux(const _Safe_iterator_base* __x) 49 { return __x->_M_singular(); } 50 51 /** \brief Safe iterator wrapper. 52 * 53 * The class template %_Safe_iterator is a wrapper around an 54 * iterator that tracks the iterator's movement among sequences and 55 * checks that operations performed on the "safe" iterator are 56 * legal. In additional to the basic iterator operations (which are 57 * validated, and then passed to the underlying iterator), 58 * %_Safe_iterator has member functions for iterator invalidation, 59 * attaching/detaching the iterator from sequences, and querying 60 * the iterator's state. 61 */ 62 template<typename _Iterator, typename _Sequence> 63 class _Safe_iterator : public _Safe_iterator_base 64 { 65 typedef _Safe_iterator _Self; 66 67 /** The precision to which we can calculate the distance between 68 * two iterators. 69 */ 70 enum _Distance_precision 71 { 72 __dp_equality, //< Can compare iterator equality, only 73 __dp_sign, //< Can determine equality and ordering 74 __dp_exact //< Can determine distance precisely 75 }; 76 77 /// The underlying iterator 78 _Iterator _M_current; 79 80 /// Determine if this is a constant iterator. 81 bool 82 _M_constant() const 83 { 84 typedef typename _Sequence::const_iterator const_iterator; 85 return __is_same<const_iterator, _Safe_iterator>::value; 86 } 87 88 typedef std::iterator_traits<_Iterator> _Traits; 89 90 public: 91 typedef _Iterator _Base_iterator; 92 typedef typename _Traits::iterator_category iterator_category; 93 typedef typename _Traits::value_type value_type; 94 typedef typename _Traits::difference_type difference_type; 95 typedef typename _Traits::reference reference; 96 typedef typename _Traits::pointer pointer; 97 98 /// @post the iterator is singular and unattached 99 _Safe_iterator() : _M_current() { } 100 101 /** 102 * @brief Safe iterator construction from an unsafe iterator and 103 * its sequence. 104 * 105 * @pre @p seq is not NULL 106 * @post this is not singular 107 */ 108 _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) 109 : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) 110 { 111 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 112 _M_message(__msg_init_singular) 113 ._M_iterator(*this, "this")); 114 } 115 116 /** 117 * @brief Copy construction. 118 * @pre @p x is not singular 119 */ 120 _Safe_iterator(const _Safe_iterator& __x) 121 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) 122 { 123 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 124 _M_message(__msg_init_copy_singular) 125 ._M_iterator(*this, "this") 126 ._M_iterator(__x, "other")); 127 } 128 129 /** 130 * @brief Converting constructor from a mutable iterator to a 131 * constant iterator. 132 * 133 * @pre @p x is not singular 134 */ 135 template<typename _MutableIterator> 136 _Safe_iterator( 137 const _Safe_iterator<_MutableIterator, 138 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, 139 typename _Sequence::iterator::_Base_iterator>::__value), 140 _Sequence>::__type>& __x) 141 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) 142 { 143 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 144 _M_message(__msg_init_const_singular) 145 ._M_iterator(*this, "this") 146 ._M_iterator(__x, "other")); 147 } 148 149 /** 150 * @brief Copy assignment. 151 * @pre @p x is not singular 152 */ 153 _Safe_iterator& 154 operator=(const _Safe_iterator& __x) 155 { 156 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 157 _M_message(__msg_copy_singular) 158 ._M_iterator(*this, "this") 159 ._M_iterator(__x, "other")); 160 _M_current = __x._M_current; 161 this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); 162 return *this; 163 } 164 165 /** 166 * @brief Iterator dereference. 167 * @pre iterator is dereferenceable 168 */ 169 reference 170 operator*() const 171 { 172 173 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 174 _M_message(__msg_bad_deref) 175 ._M_iterator(*this, "this")); 176 return *_M_current; 177 } 178 179 /** 180 * @brief Iterator dereference. 181 * @pre iterator is dereferenceable 182 * @todo Make this correct w.r.t. iterators that return proxies 183 * @todo Use addressof() instead of & operator 184 */ 185 pointer 186 operator->() const 187 { 188 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 189 _M_message(__msg_bad_deref) 190 ._M_iterator(*this, "this")); 191 return &*_M_current; 192 } 193 194 // ------ Input iterator requirements ------ 195 /** 196 * @brief Iterator preincrement 197 * @pre iterator is incrementable 198 */ 199 _Safe_iterator& 200 operator++() 201 { 202 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 203 _M_message(__msg_bad_inc) 204 ._M_iterator(*this, "this")); 205 ++_M_current; 206 return *this; 207 } 208 209 /** 210 * @brief Iterator postincrement 211 * @pre iterator is incrementable 212 */ 213 _Safe_iterator 214 operator++(int) 215 { 216 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 217 _M_message(__msg_bad_inc) 218 ._M_iterator(*this, "this")); 219 _Safe_iterator __tmp(*this); 220 ++_M_current; 221 return __tmp; 222 } 223 224 // ------ Bidirectional iterator requirements ------ 225 /** 226 * @brief Iterator predecrement 227 * @pre iterator is decrementable 228 */ 229 _Safe_iterator& 230 operator--() 231 { 232 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 233 _M_message(__msg_bad_dec) 234 ._M_iterator(*this, "this")); 235 --_M_current; 236 return *this; 237 } 238 239 /** 240 * @brief Iterator postdecrement 241 * @pre iterator is decrementable 242 */ 243 _Safe_iterator 244 operator--(int) 245 { 246 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 247 _M_message(__msg_bad_dec) 248 ._M_iterator(*this, "this")); 249 _Safe_iterator __tmp(*this); 250 --_M_current; 251 return __tmp; 252 } 253 254 // ------ Random access iterator requirements ------ 255 reference 256 operator[](const difference_type& __n) const 257 { 258 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 259 && this->_M_can_advance(__n+1), 260 _M_message(__msg_iter_subscript_oob) 261 ._M_iterator(*this)._M_integer(__n)); 262 263 return _M_current[__n]; 264 } 265 266 _Safe_iterator& 267 operator+=(const difference_type& __n) 268 { 269 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 270 _M_message(__msg_advance_oob) 271 ._M_iterator(*this)._M_integer(__n)); 272 _M_current += __n; 273 return *this; 274 } 275 276 _Safe_iterator 277 operator+(const difference_type& __n) const 278 { 279 _Safe_iterator __tmp(*this); 280 __tmp += __n; 281 return __tmp; 282 } 283 284 _Safe_iterator& 285 operator-=(const difference_type& __n) 286 { 287 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 288 _M_message(__msg_retreat_oob) 289 ._M_iterator(*this)._M_integer(__n)); 290 _M_current += -__n; 291 return *this; 292 } 293 294 _Safe_iterator 295 operator-(const difference_type& __n) const 296 { 297 _Safe_iterator __tmp(*this); 298 __tmp -= __n; 299 return __tmp; 300 } 301 302 // ------ Utilities ------ 303 /** 304 * @brief Return the underlying iterator 305 */ 306 _Iterator 307 base() const { return _M_current; } 308 309 /** 310 * @brief Conversion to underlying non-debug iterator to allow 311 * better interaction with non-debug containers. 312 */ 313 operator _Iterator() const { return _M_current; } 314 315 /** Attach iterator to the given sequence. */ 316 void 317 _M_attach(const _Sequence* __seq) 318 { 319 _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), 320 _M_constant()); 321 } 322 323 /** Likewise, but not thread-safe. */ 324 void 325 _M_attach_single(const _Sequence* __seq) 326 { 327 _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq), 328 _M_constant()); 329 } 330 331 /** Invalidate the iterator, making it singular. */ 332 void 333 _M_invalidate(); 334 335 /** Likewise, but not thread-safe. */ 336 void 337 _M_invalidate_single(); 338 339 /// Is the iterator dereferenceable? 340 bool 341 _M_dereferenceable() const 342 { return !this->_M_singular() && !_M_is_end(); } 343 344 /// Is the iterator incrementable? 345 bool 346 _M_incrementable() const { return this->_M_dereferenceable(); } 347 348 // Is the iterator decrementable? 349 bool 350 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } 351 352 // Can we advance the iterator @p __n steps (@p __n may be negative) 353 bool 354 _M_can_advance(const difference_type& __n) const; 355 356 // Is the iterator range [*this, __rhs) valid? 357 template<typename _Other> 358 bool 359 _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; 360 361 // The sequence this iterator references. 362 const _Sequence* 363 _M_get_sequence() const 364 { return static_cast<const _Sequence*>(_M_sequence); } 365 366 /** Determine the distance between two iterators with some known 367 * precision. 368 */ 369 template<typename _Iterator1, typename _Iterator2> 370 static std::pair<difference_type, _Distance_precision> 371 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) 372 { 373 typedef typename std::iterator_traits<_Iterator1>::iterator_category 374 _Category; 375 return _M_get_distance(__lhs, __rhs, _Category()); 376 } 377 378 template<typename _Iterator1, typename _Iterator2> 379 static std::pair<difference_type, _Distance_precision> 380 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, 381 std::random_access_iterator_tag) 382 { 383 return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); 384 } 385 386 template<typename _Iterator1, typename _Iterator2> 387 static std::pair<difference_type, _Distance_precision> 388 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, 389 std::forward_iterator_tag) 390 { 391 return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, 392 __dp_equality); 393 } 394 395 /// Is this iterator equal to the sequence's begin() iterator? 396 bool _M_is_begin() const 397 { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); } 398 399 /// Is this iterator equal to the sequence's end() iterator? 400 bool _M_is_end() const 401 { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); } 402 }; 403 404 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 405 inline bool 406 operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 407 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 408 { 409 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 410 _M_message(__msg_iter_compare_bad) 411 ._M_iterator(__lhs, "lhs") 412 ._M_iterator(__rhs, "rhs")); 413 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 414 _M_message(__msg_compare_different) 415 ._M_iterator(__lhs, "lhs") 416 ._M_iterator(__rhs, "rhs")); 417 return __lhs.base() == __rhs.base(); 418 } 419 420 template<typename _Iterator, typename _Sequence> 421 inline bool 422 operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 423 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 424 { 425 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 426 _M_message(__msg_iter_compare_bad) 427 ._M_iterator(__lhs, "lhs") 428 ._M_iterator(__rhs, "rhs")); 429 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 430 _M_message(__msg_compare_different) 431 ._M_iterator(__lhs, "lhs") 432 ._M_iterator(__rhs, "rhs")); 433 return __lhs.base() == __rhs.base(); 434 } 435 436 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 437 inline bool 438 operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 439 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 440 { 441 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 442 _M_message(__msg_iter_compare_bad) 443 ._M_iterator(__lhs, "lhs") 444 ._M_iterator(__rhs, "rhs")); 445 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 446 _M_message(__msg_compare_different) 447 ._M_iterator(__lhs, "lhs") 448 ._M_iterator(__rhs, "rhs")); 449 return __lhs.base() != __rhs.base(); 450 } 451 452 template<typename _Iterator, typename _Sequence> 453 inline bool 454 operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 455 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 456 { 457 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 458 _M_message(__msg_iter_compare_bad) 459 ._M_iterator(__lhs, "lhs") 460 ._M_iterator(__rhs, "rhs")); 461 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 462 _M_message(__msg_compare_different) 463 ._M_iterator(__lhs, "lhs") 464 ._M_iterator(__rhs, "rhs")); 465 return __lhs.base() != __rhs.base(); 466 } 467 468 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 469 inline bool 470 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 471 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 472 { 473 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 474 _M_message(__msg_iter_order_bad) 475 ._M_iterator(__lhs, "lhs") 476 ._M_iterator(__rhs, "rhs")); 477 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 478 _M_message(__msg_order_different) 479 ._M_iterator(__lhs, "lhs") 480 ._M_iterator(__rhs, "rhs")); 481 return __lhs.base() < __rhs.base(); 482 } 483 484 template<typename _Iterator, typename _Sequence> 485 inline bool 486 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 487 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 488 { 489 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 490 _M_message(__msg_iter_order_bad) 491 ._M_iterator(__lhs, "lhs") 492 ._M_iterator(__rhs, "rhs")); 493 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 494 _M_message(__msg_order_different) 495 ._M_iterator(__lhs, "lhs") 496 ._M_iterator(__rhs, "rhs")); 497 return __lhs.base() < __rhs.base(); 498 } 499 500 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 501 inline bool 502 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 503 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 504 { 505 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 506 _M_message(__msg_iter_order_bad) 507 ._M_iterator(__lhs, "lhs") 508 ._M_iterator(__rhs, "rhs")); 509 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 510 _M_message(__msg_order_different) 511 ._M_iterator(__lhs, "lhs") 512 ._M_iterator(__rhs, "rhs")); 513 return __lhs.base() <= __rhs.base(); 514 } 515 516 template<typename _Iterator, typename _Sequence> 517 inline bool 518 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 519 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 520 { 521 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 522 _M_message(__msg_iter_order_bad) 523 ._M_iterator(__lhs, "lhs") 524 ._M_iterator(__rhs, "rhs")); 525 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 526 _M_message(__msg_order_different) 527 ._M_iterator(__lhs, "lhs") 528 ._M_iterator(__rhs, "rhs")); 529 return __lhs.base() <= __rhs.base(); 530 } 531 532 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 533 inline bool 534 operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 535 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 536 { 537 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 538 _M_message(__msg_iter_order_bad) 539 ._M_iterator(__lhs, "lhs") 540 ._M_iterator(__rhs, "rhs")); 541 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 542 _M_message(__msg_order_different) 543 ._M_iterator(__lhs, "lhs") 544 ._M_iterator(__rhs, "rhs")); 545 return __lhs.base() > __rhs.base(); 546 } 547 548 template<typename _Iterator, typename _Sequence> 549 inline bool 550 operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 551 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 552 { 553 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 554 _M_message(__msg_iter_order_bad) 555 ._M_iterator(__lhs, "lhs") 556 ._M_iterator(__rhs, "rhs")); 557 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 558 _M_message(__msg_order_different) 559 ._M_iterator(__lhs, "lhs") 560 ._M_iterator(__rhs, "rhs")); 561 return __lhs.base() > __rhs.base(); 562 } 563 564 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 565 inline bool 566 operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 567 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 568 { 569 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 570 _M_message(__msg_iter_order_bad) 571 ._M_iterator(__lhs, "lhs") 572 ._M_iterator(__rhs, "rhs")); 573 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 574 _M_message(__msg_order_different) 575 ._M_iterator(__lhs, "lhs") 576 ._M_iterator(__rhs, "rhs")); 577 return __lhs.base() >= __rhs.base(); 578 } 579 580 template<typename _Iterator, typename _Sequence> 581 inline bool 582 operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 583 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 584 { 585 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 586 _M_message(__msg_iter_order_bad) 587 ._M_iterator(__lhs, "lhs") 588 ._M_iterator(__rhs, "rhs")); 589 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 590 _M_message(__msg_order_different) 591 ._M_iterator(__lhs, "lhs") 592 ._M_iterator(__rhs, "rhs")); 593 return __lhs.base() >= __rhs.base(); 594 } 595 596 // _GLIBCXX_RESOLVE_LIB_DEFECTS 597 // According to the resolution of DR179 not only the various comparison 598 // operators but also operator- must accept mixed iterator/const_iterator 599 // parameters. 600 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 601 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type 602 operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 603 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 604 { 605 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 606 _M_message(__msg_distance_bad) 607 ._M_iterator(__lhs, "lhs") 608 ._M_iterator(__rhs, "rhs")); 609 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 610 _M_message(__msg_distance_different) 611 ._M_iterator(__lhs, "lhs") 612 ._M_iterator(__rhs, "rhs")); 613 return __lhs.base() - __rhs.base(); 614 } 615 616 template<typename _Iterator, typename _Sequence> 617 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type 618 operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 619 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 620 { 621 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 622 _M_message(__msg_distance_bad) 623 ._M_iterator(__lhs, "lhs") 624 ._M_iterator(__rhs, "rhs")); 625 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 626 _M_message(__msg_distance_different) 627 ._M_iterator(__lhs, "lhs") 628 ._M_iterator(__rhs, "rhs")); 629 return __lhs.base() - __rhs.base(); 630 } 631 632 template<typename _Iterator, typename _Sequence> 633 inline _Safe_iterator<_Iterator, _Sequence> 634 operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, 635 const _Safe_iterator<_Iterator, _Sequence>& __i) 636 { return __i + __n; } 637} // namespace __gnu_debug 638 639#ifndef _GLIBCXX_EXPORT_TEMPLATE 640# include <debug/safe_iterator.tcc> 641#endif 642 643#endif 644