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