libstdc++
|
00001 // Safe iterator implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003, 2004, 2005, 2006, 2009 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file debug/safe_iterator.h 00027 * This file is a GNU debug extension to the Standard C++ Library. 00028 */ 00029 00030 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 00031 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 00032 00033 #include <debug/debug.h> 00034 #include <debug/macros.h> 00035 #include <debug/functions.h> 00036 #include <debug/formatter.h> 00037 #include <debug/safe_base.h> 00038 #include <bits/stl_pair.h> 00039 #include <ext/type_traits.h> 00040 00041 namespace __gnu_debug 00042 { 00043 /** Iterators that derive from _Safe_iterator_base but that aren't 00044 * _Safe_iterators can be determined singular or non-singular via 00045 * _Safe_iterator_base. 00046 */ 00047 inline bool 00048 __check_singular_aux(const _Safe_iterator_base* __x) 00049 { return __x->_M_singular(); } 00050 00051 /** \brief Safe iterator wrapper. 00052 * 00053 * The class template %_Safe_iterator is a wrapper around an 00054 * iterator that tracks the iterator's movement among sequences and 00055 * checks that operations performed on the "safe" iterator are 00056 * legal. In additional to the basic iterator operations (which are 00057 * validated, and then passed to the underlying iterator), 00058 * %_Safe_iterator has member functions for iterator invalidation, 00059 * attaching/detaching the iterator from sequences, and querying 00060 * the iterator's state. 00061 */ 00062 template<typename _Iterator, typename _Sequence> 00063 class _Safe_iterator : public _Safe_iterator_base 00064 { 00065 typedef _Safe_iterator _Self; 00066 00067 /** The precision to which we can calculate the distance between 00068 * two iterators. 00069 */ 00070 enum _Distance_precision 00071 { 00072 __dp_equality, //< Can compare iterator equality, only 00073 __dp_sign, //< Can determine equality and ordering 00074 __dp_exact //< Can determine distance precisely 00075 }; 00076 00077 /// The underlying iterator 00078 _Iterator _M_current; 00079 00080 /// Determine if this is a constant iterator. 00081 bool 00082 _M_constant() const 00083 { 00084 typedef typename _Sequence::const_iterator const_iterator; 00085 return __is_same<const_iterator, _Safe_iterator>::value; 00086 } 00087 00088 typedef std::iterator_traits<_Iterator> _Traits; 00089 00090 public: 00091 typedef _Iterator _Base_iterator; 00092 typedef typename _Traits::iterator_category iterator_category; 00093 typedef typename _Traits::value_type value_type; 00094 typedef typename _Traits::difference_type difference_type; 00095 typedef typename _Traits::reference reference; 00096 typedef typename _Traits::pointer pointer; 00097 00098 /// @post the iterator is singular and unattached 00099 _Safe_iterator() : _M_current() { } 00100 00101 /** 00102 * @brief Safe iterator construction from an unsafe iterator and 00103 * its sequence. 00104 * 00105 * @pre @p seq is not NULL 00106 * @post this is not singular 00107 */ 00108 _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) 00109 : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) 00110 { 00111 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 00112 _M_message(__msg_init_singular) 00113 ._M_iterator(*this, "this")); 00114 } 00115 00116 /** 00117 * @brief Copy construction. 00118 * @pre @p x is not singular 00119 */ 00120 _Safe_iterator(const _Safe_iterator& __x) 00121 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) 00122 { 00123 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 00124 _M_message(__msg_init_copy_singular) 00125 ._M_iterator(*this, "this") 00126 ._M_iterator(__x, "other")); 00127 } 00128 00129 /** 00130 * @brief Converting constructor from a mutable iterator to a 00131 * constant iterator. 00132 * 00133 * @pre @p x is not singular 00134 */ 00135 template<typename _MutableIterator> 00136 _Safe_iterator( 00137 const _Safe_iterator<_MutableIterator, 00138 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, 00139 typename _Sequence::iterator::_Base_iterator>::__value), 00140 _Sequence>::__type>& __x) 00141 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) 00142 { 00143 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 00144 _M_message(__msg_init_const_singular) 00145 ._M_iterator(*this, "this") 00146 ._M_iterator(__x, "other")); 00147 } 00148 00149 /** 00150 * @brief Copy assignment. 00151 * @pre @p x is not singular 00152 */ 00153 _Safe_iterator& 00154 operator=(const _Safe_iterator& __x) 00155 { 00156 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 00157 _M_message(__msg_copy_singular) 00158 ._M_iterator(*this, "this") 00159 ._M_iterator(__x, "other")); 00160 _M_current = __x._M_current; 00161 this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); 00162 return *this; 00163 } 00164 00165 /** 00166 * @brief Iterator dereference. 00167 * @pre iterator is dereferenceable 00168 */ 00169 reference 00170 operator*() const 00171 { 00172 00173 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 00174 _M_message(__msg_bad_deref) 00175 ._M_iterator(*this, "this")); 00176 return *_M_current; 00177 } 00178 00179 /** 00180 * @brief Iterator dereference. 00181 * @pre iterator is dereferenceable 00182 * @todo Make this correct w.r.t. iterators that return proxies 00183 * @todo Use addressof() instead of & operator 00184 */ 00185 pointer 00186 operator->() const 00187 { 00188 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 00189 _M_message(__msg_bad_deref) 00190 ._M_iterator(*this, "this")); 00191 return &*_M_current; 00192 } 00193 00194 // ------ Input iterator requirements ------ 00195 /** 00196 * @brief Iterator preincrement 00197 * @pre iterator is incrementable 00198 */ 00199 _Safe_iterator& 00200 operator++() 00201 { 00202 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 00203 _M_message(__msg_bad_inc) 00204 ._M_iterator(*this, "this")); 00205 ++_M_current; 00206 return *this; 00207 } 00208 00209 /** 00210 * @brief Iterator postincrement 00211 * @pre iterator is incrementable 00212 */ 00213 _Safe_iterator 00214 operator++(int) 00215 { 00216 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 00217 _M_message(__msg_bad_inc) 00218 ._M_iterator(*this, "this")); 00219 _Safe_iterator __tmp(*this); 00220 ++_M_current; 00221 return __tmp; 00222 } 00223 00224 // ------ Bidirectional iterator requirements ------ 00225 /** 00226 * @brief Iterator predecrement 00227 * @pre iterator is decrementable 00228 */ 00229 _Safe_iterator& 00230 operator--() 00231 { 00232 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 00233 _M_message(__msg_bad_dec) 00234 ._M_iterator(*this, "this")); 00235 --_M_current; 00236 return *this; 00237 } 00238 00239 /** 00240 * @brief Iterator postdecrement 00241 * @pre iterator is decrementable 00242 */ 00243 _Safe_iterator 00244 operator--(int) 00245 { 00246 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 00247 _M_message(__msg_bad_dec) 00248 ._M_iterator(*this, "this")); 00249 _Safe_iterator __tmp(*this); 00250 --_M_current; 00251 return __tmp; 00252 } 00253 00254 // ------ Random access iterator requirements ------ 00255 reference 00256 operator[](const difference_type& __n) const 00257 { 00258 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 00259 && this->_M_can_advance(__n+1), 00260 _M_message(__msg_iter_subscript_oob) 00261 ._M_iterator(*this)._M_integer(__n)); 00262 00263 return _M_current[__n]; 00264 } 00265 00266 _Safe_iterator& 00267 operator+=(const difference_type& __n) 00268 { 00269 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 00270 _M_message(__msg_advance_oob) 00271 ._M_iterator(*this)._M_integer(__n)); 00272 _M_current += __n; 00273 return *this; 00274 } 00275 00276 _Safe_iterator 00277 operator+(const difference_type& __n) const 00278 { 00279 _Safe_iterator __tmp(*this); 00280 __tmp += __n; 00281 return __tmp; 00282 } 00283 00284 _Safe_iterator& 00285 operator-=(const difference_type& __n) 00286 { 00287 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 00288 _M_message(__msg_retreat_oob) 00289 ._M_iterator(*this)._M_integer(__n)); 00290 _M_current += -__n; 00291 return *this; 00292 } 00293 00294 _Safe_iterator 00295 operator-(const difference_type& __n) const 00296 { 00297 _Safe_iterator __tmp(*this); 00298 __tmp -= __n; 00299 return __tmp; 00300 } 00301 00302 // ------ Utilities ------ 00303 /** 00304 * @brief Return the underlying iterator 00305 */ 00306 _Iterator 00307 base() const { return _M_current; } 00308 00309 /** 00310 * @brief Conversion to underlying non-debug iterator to allow 00311 * better interaction with non-debug containers. 00312 */ 00313 operator _Iterator() const { return _M_current; } 00314 00315 /** Attach iterator to the given sequence. */ 00316 void 00317 _M_attach(const _Sequence* __seq) 00318 { 00319 _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), 00320 _M_constant()); 00321 } 00322 00323 /** Likewise, but not thread-safe. */ 00324 void 00325 _M_attach_single(const _Sequence* __seq) 00326 { 00327 _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq), 00328 _M_constant()); 00329 } 00330 00331 /** Invalidate the iterator, making it singular. */ 00332 void 00333 _M_invalidate(); 00334 00335 /** Likewise, but not thread-safe. */ 00336 void 00337 _M_invalidate_single(); 00338 00339 /// Is the iterator dereferenceable? 00340 bool 00341 _M_dereferenceable() const 00342 { return !this->_M_singular() && !_M_is_end(); } 00343 00344 /// Is the iterator incrementable? 00345 bool 00346 _M_incrementable() const { return this->_M_dereferenceable(); } 00347 00348 // Is the iterator decrementable? 00349 bool 00350 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } 00351 00352 // Can we advance the iterator @p __n steps (@p __n may be negative) 00353 bool 00354 _M_can_advance(const difference_type& __n) const; 00355 00356 // Is the iterator range [*this, __rhs) valid? 00357 template<typename _Other> 00358 bool 00359 _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; 00360 00361 // The sequence this iterator references. 00362 const _Sequence* 00363 _M_get_sequence() const 00364 { return static_cast<const _Sequence*>(_M_sequence); } 00365 00366 /** Determine the distance between two iterators with some known 00367 * precision. 00368 */ 00369 template<typename _Iterator1, typename _Iterator2> 00370 static std::pair<difference_type, _Distance_precision> 00371 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) 00372 { 00373 typedef typename std::iterator_traits<_Iterator1>::iterator_category 00374 _Category; 00375 return _M_get_distance(__lhs, __rhs, _Category()); 00376 } 00377 00378 template<typename _Iterator1, typename _Iterator2> 00379 static std::pair<difference_type, _Distance_precision> 00380 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, 00381 std::random_access_iterator_tag) 00382 { 00383 return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); 00384 } 00385 00386 template<typename _Iterator1, typename _Iterator2> 00387 static std::pair<difference_type, _Distance_precision> 00388 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, 00389 std::forward_iterator_tag) 00390 { 00391 return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, 00392 __dp_equality); 00393 } 00394 00395 /// Is this iterator equal to the sequence's begin() iterator? 00396 bool _M_is_begin() const 00397 { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); } 00398 00399 /// Is this iterator equal to the sequence's end() iterator? 00400 bool _M_is_end() const 00401 { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); } 00402 }; 00403 00404 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00405 inline bool 00406 operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00407 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00408 { 00409 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00410 _M_message(__msg_iter_compare_bad) 00411 ._M_iterator(__lhs, "lhs") 00412 ._M_iterator(__rhs, "rhs")); 00413 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00414 _M_message(__msg_compare_different) 00415 ._M_iterator(__lhs, "lhs") 00416 ._M_iterator(__rhs, "rhs")); 00417 return __lhs.base() == __rhs.base(); 00418 } 00419 00420 template<typename _Iterator, typename _Sequence> 00421 inline bool 00422 operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00423 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00424 { 00425 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00426 _M_message(__msg_iter_compare_bad) 00427 ._M_iterator(__lhs, "lhs") 00428 ._M_iterator(__rhs, "rhs")); 00429 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00430 _M_message(__msg_compare_different) 00431 ._M_iterator(__lhs, "lhs") 00432 ._M_iterator(__rhs, "rhs")); 00433 return __lhs.base() == __rhs.base(); 00434 } 00435 00436 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00437 inline bool 00438 operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00439 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00440 { 00441 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00442 _M_message(__msg_iter_compare_bad) 00443 ._M_iterator(__lhs, "lhs") 00444 ._M_iterator(__rhs, "rhs")); 00445 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00446 _M_message(__msg_compare_different) 00447 ._M_iterator(__lhs, "lhs") 00448 ._M_iterator(__rhs, "rhs")); 00449 return __lhs.base() != __rhs.base(); 00450 } 00451 00452 template<typename _Iterator, typename _Sequence> 00453 inline bool 00454 operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00455 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00456 { 00457 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00458 _M_message(__msg_iter_compare_bad) 00459 ._M_iterator(__lhs, "lhs") 00460 ._M_iterator(__rhs, "rhs")); 00461 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00462 _M_message(__msg_compare_different) 00463 ._M_iterator(__lhs, "lhs") 00464 ._M_iterator(__rhs, "rhs")); 00465 return __lhs.base() != __rhs.base(); 00466 } 00467 00468 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00469 inline bool 00470 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00471 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00472 { 00473 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00474 _M_message(__msg_iter_order_bad) 00475 ._M_iterator(__lhs, "lhs") 00476 ._M_iterator(__rhs, "rhs")); 00477 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00478 _M_message(__msg_order_different) 00479 ._M_iterator(__lhs, "lhs") 00480 ._M_iterator(__rhs, "rhs")); 00481 return __lhs.base() < __rhs.base(); 00482 } 00483 00484 template<typename _Iterator, typename _Sequence> 00485 inline bool 00486 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00487 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00488 { 00489 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00490 _M_message(__msg_iter_order_bad) 00491 ._M_iterator(__lhs, "lhs") 00492 ._M_iterator(__rhs, "rhs")); 00493 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00494 _M_message(__msg_order_different) 00495 ._M_iterator(__lhs, "lhs") 00496 ._M_iterator(__rhs, "rhs")); 00497 return __lhs.base() < __rhs.base(); 00498 } 00499 00500 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00501 inline bool 00502 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00503 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00504 { 00505 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00506 _M_message(__msg_iter_order_bad) 00507 ._M_iterator(__lhs, "lhs") 00508 ._M_iterator(__rhs, "rhs")); 00509 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00510 _M_message(__msg_order_different) 00511 ._M_iterator(__lhs, "lhs") 00512 ._M_iterator(__rhs, "rhs")); 00513 return __lhs.base() <= __rhs.base(); 00514 } 00515 00516 template<typename _Iterator, typename _Sequence> 00517 inline bool 00518 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00519 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00520 { 00521 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00522 _M_message(__msg_iter_order_bad) 00523 ._M_iterator(__lhs, "lhs") 00524 ._M_iterator(__rhs, "rhs")); 00525 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00526 _M_message(__msg_order_different) 00527 ._M_iterator(__lhs, "lhs") 00528 ._M_iterator(__rhs, "rhs")); 00529 return __lhs.base() <= __rhs.base(); 00530 } 00531 00532 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00533 inline bool 00534 operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00535 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00536 { 00537 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00538 _M_message(__msg_iter_order_bad) 00539 ._M_iterator(__lhs, "lhs") 00540 ._M_iterator(__rhs, "rhs")); 00541 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00542 _M_message(__msg_order_different) 00543 ._M_iterator(__lhs, "lhs") 00544 ._M_iterator(__rhs, "rhs")); 00545 return __lhs.base() > __rhs.base(); 00546 } 00547 00548 template<typename _Iterator, typename _Sequence> 00549 inline bool 00550 operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00551 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00552 { 00553 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00554 _M_message(__msg_iter_order_bad) 00555 ._M_iterator(__lhs, "lhs") 00556 ._M_iterator(__rhs, "rhs")); 00557 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00558 _M_message(__msg_order_different) 00559 ._M_iterator(__lhs, "lhs") 00560 ._M_iterator(__rhs, "rhs")); 00561 return __lhs.base() > __rhs.base(); 00562 } 00563 00564 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00565 inline bool 00566 operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00567 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00568 { 00569 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00570 _M_message(__msg_iter_order_bad) 00571 ._M_iterator(__lhs, "lhs") 00572 ._M_iterator(__rhs, "rhs")); 00573 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00574 _M_message(__msg_order_different) 00575 ._M_iterator(__lhs, "lhs") 00576 ._M_iterator(__rhs, "rhs")); 00577 return __lhs.base() >= __rhs.base(); 00578 } 00579 00580 template<typename _Iterator, typename _Sequence> 00581 inline bool 00582 operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00583 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00584 { 00585 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00586 _M_message(__msg_iter_order_bad) 00587 ._M_iterator(__lhs, "lhs") 00588 ._M_iterator(__rhs, "rhs")); 00589 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00590 _M_message(__msg_order_different) 00591 ._M_iterator(__lhs, "lhs") 00592 ._M_iterator(__rhs, "rhs")); 00593 return __lhs.base() >= __rhs.base(); 00594 } 00595 00596 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00597 // According to the resolution of DR179 not only the various comparison 00598 // operators but also operator- must accept mixed iterator/const_iterator 00599 // parameters. 00600 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00601 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type 00602 operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00603 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00604 { 00605 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00606 _M_message(__msg_distance_bad) 00607 ._M_iterator(__lhs, "lhs") 00608 ._M_iterator(__rhs, "rhs")); 00609 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00610 _M_message(__msg_distance_different) 00611 ._M_iterator(__lhs, "lhs") 00612 ._M_iterator(__rhs, "rhs")); 00613 return __lhs.base() - __rhs.base(); 00614 } 00615 00616 template<typename _Iterator, typename _Sequence> 00617 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type 00618 operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00619 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00620 { 00621 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00622 _M_message(__msg_distance_bad) 00623 ._M_iterator(__lhs, "lhs") 00624 ._M_iterator(__rhs, "rhs")); 00625 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00626 _M_message(__msg_distance_different) 00627 ._M_iterator(__lhs, "lhs") 00628 ._M_iterator(__rhs, "rhs")); 00629 return __lhs.base() - __rhs.base(); 00630 } 00631 00632 template<typename _Iterator, typename _Sequence> 00633 inline _Safe_iterator<_Iterator, _Sequence> 00634 operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, 00635 const _Safe_iterator<_Iterator, _Sequence>& __i) 00636 { return __i + __n; } 00637 } // namespace __gnu_debug 00638 00639 #ifndef _GLIBCXX_EXPORT_TEMPLATE 00640 # include <debug/safe_iterator.tcc> 00641 #endif 00642 00643 #endif