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