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