libstdc++
|
00001 // Safe iterator implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003-2015 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 * Note that _Iterator must be the first base class so that it gets 00114 * initialized before the iterator is being attached to the container's list 00115 * of iterators and it is being detached before _Iterator get 00116 * destroyed. Otherwise it would result in a data race. 00117 */ 00118 template<typename _Iterator, typename _Sequence> 00119 class _Safe_iterator 00120 : private _Iterator, 00121 public _Safe_iterator_base 00122 { 00123 typedef _Iterator _Iter_base; 00124 typedef _Safe_iterator_base _Safe_base; 00125 typedef typename _Sequence::const_iterator _Const_iterator; 00126 00127 /// Determine if this is a constant iterator. 00128 bool 00129 _M_constant() const 00130 { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; } 00131 00132 typedef std::iterator_traits<_Iterator> _Traits; 00133 00134 struct _Attach_single 00135 { }; 00136 00137 _Safe_iterator(const _Iterator& __i, _Safe_sequence_base* __seq, 00138 _Attach_single) 00139 _GLIBCXX_NOEXCEPT 00140 : _Iter_base(__i) 00141 { _M_attach_single(__seq); } 00142 00143 public: 00144 typedef _Iterator iterator_type; 00145 typedef typename _Traits::iterator_category iterator_category; 00146 typedef typename _Traits::value_type value_type; 00147 typedef typename _Traits::difference_type difference_type; 00148 typedef typename _Traits::reference reference; 00149 typedef typename _Traits::pointer pointer; 00150 00151 /// @post the iterator is singular and unattached 00152 _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { } 00153 00154 /** 00155 * @brief Safe iterator construction from an unsafe iterator and 00156 * its sequence. 00157 * 00158 * @pre @p seq is not NULL 00159 * @post this is not singular 00160 */ 00161 _Safe_iterator(const _Iterator& __i, const _Safe_sequence_base* __seq) 00162 _GLIBCXX_NOEXCEPT 00163 : _Iter_base(__i), _Safe_base(__seq, _M_constant()) 00164 { 00165 _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(), 00166 _M_message(__msg_init_singular) 00167 ._M_iterator(*this, "this")); 00168 } 00169 00170 /** 00171 * @brief Copy construction. 00172 */ 00173 _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 00174 : _Iter_base(__x.base()) 00175 { 00176 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00177 // DR 408. Is vector<reverse_iterator<char*> > forbidden? 00178 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 00179 || __x.base() == _Iterator(), 00180 _M_message(__msg_init_copy_singular) 00181 ._M_iterator(*this, "this") 00182 ._M_iterator(__x, "other")); 00183 _M_attach(__x._M_sequence); 00184 } 00185 00186 #if __cplusplus >= 201103L 00187 /** 00188 * @brief Move construction. 00189 * @post __x is singular and unattached 00190 */ 00191 _Safe_iterator(_Safe_iterator&& __x) noexcept 00192 : _Iter_base() 00193 { 00194 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 00195 || __x.base() == _Iterator(), 00196 _M_message(__msg_init_copy_singular) 00197 ._M_iterator(*this, "this") 00198 ._M_iterator(__x, "other")); 00199 _Safe_sequence_base* __seq = __x._M_sequence; 00200 __x._M_detach(); 00201 std::swap(base(), __x.base()); 00202 _M_attach(__seq); 00203 } 00204 #endif 00205 00206 /** 00207 * @brief Converting constructor from a mutable iterator to a 00208 * constant iterator. 00209 */ 00210 template<typename _MutableIterator> 00211 _Safe_iterator( 00212 const _Safe_iterator<_MutableIterator, 00213 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, 00214 typename _Sequence::iterator::iterator_type>::__value), 00215 _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT 00216 : _Iter_base(__x.base()) 00217 { 00218 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00219 // DR 408. Is vector<reverse_iterator<char*> > forbidden? 00220 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 00221 || __x.base() == _Iterator(), 00222 _M_message(__msg_init_const_singular) 00223 ._M_iterator(*this, "this") 00224 ._M_iterator(__x, "other")); 00225 _M_attach(__x._M_sequence); 00226 } 00227 00228 /** 00229 * @brief Copy assignment. 00230 */ 00231 _Safe_iterator& 00232 operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 00233 { 00234 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00235 // DR 408. Is vector<reverse_iterator<char*> > forbidden? 00236 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 00237 || __x.base() == _Iterator(), 00238 _M_message(__msg_copy_singular) 00239 ._M_iterator(*this, "this") 00240 ._M_iterator(__x, "other")); 00241 00242 if (this->_M_sequence && this->_M_sequence == __x._M_sequence) 00243 { 00244 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00245 base() = __x.base(); 00246 _M_version = __x._M_sequence->_M_version; 00247 } 00248 else 00249 { 00250 _M_detach(); 00251 base() = __x.base(); 00252 _M_attach(__x._M_sequence); 00253 } 00254 00255 return *this; 00256 } 00257 00258 #if __cplusplus >= 201103L 00259 /** 00260 * @brief Move assignment. 00261 * @post __x is singular and unattached 00262 */ 00263 _Safe_iterator& 00264 operator=(_Safe_iterator&& __x) noexcept 00265 { 00266 _GLIBCXX_DEBUG_VERIFY(this != &__x, 00267 _M_message(__msg_self_move_assign) 00268 ._M_iterator(*this, "this")); 00269 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 00270 || __x.base() == _Iterator(), 00271 _M_message(__msg_copy_singular) 00272 ._M_iterator(*this, "this") 00273 ._M_iterator(__x, "other")); 00274 00275 if (this->_M_sequence && this->_M_sequence == __x._M_sequence) 00276 { 00277 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00278 base() = __x.base(); 00279 _M_version = __x._M_sequence->_M_version; 00280 } 00281 else 00282 { 00283 _M_detach(); 00284 base() = __x.base(); 00285 _M_attach(__x._M_sequence); 00286 } 00287 00288 __x._M_detach(); 00289 __x.base() = _Iterator(); 00290 return *this; 00291 } 00292 #endif 00293 00294 /** 00295 * @brief Iterator dereference. 00296 * @pre iterator is dereferenceable 00297 */ 00298 reference 00299 operator*() const _GLIBCXX_NOEXCEPT 00300 { 00301 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 00302 _M_message(__msg_bad_deref) 00303 ._M_iterator(*this, "this")); 00304 return *base(); 00305 } 00306 00307 /** 00308 * @brief Iterator dereference. 00309 * @pre iterator is dereferenceable 00310 * @todo Make this correct w.r.t. iterators that return proxies 00311 */ 00312 pointer 00313 operator->() const _GLIBCXX_NOEXCEPT 00314 { 00315 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 00316 _M_message(__msg_bad_deref) 00317 ._M_iterator(*this, "this")); 00318 return std::__addressof(*base()); 00319 } 00320 00321 // ------ Input iterator requirements ------ 00322 /** 00323 * @brief Iterator preincrement 00324 * @pre iterator is incrementable 00325 */ 00326 _Safe_iterator& 00327 operator++() _GLIBCXX_NOEXCEPT 00328 { 00329 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 00330 _M_message(__msg_bad_inc) 00331 ._M_iterator(*this, "this")); 00332 __gnu_cxx::__scoped_lock(this->_M_get_mutex()); 00333 ++base(); 00334 return *this; 00335 } 00336 00337 /** 00338 * @brief Iterator postincrement 00339 * @pre iterator is incrementable 00340 */ 00341 _Safe_iterator 00342 operator++(int) _GLIBCXX_NOEXCEPT 00343 { 00344 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 00345 _M_message(__msg_bad_inc) 00346 ._M_iterator(*this, "this")); 00347 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00348 return _Safe_iterator(base()++, this->_M_sequence, _Attach_single()); 00349 } 00350 00351 // ------ Bidirectional iterator requirements ------ 00352 /** 00353 * @brief Iterator predecrement 00354 * @pre iterator is decrementable 00355 */ 00356 _Safe_iterator& 00357 operator--() _GLIBCXX_NOEXCEPT 00358 { 00359 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 00360 _M_message(__msg_bad_dec) 00361 ._M_iterator(*this, "this")); 00362 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00363 --base(); 00364 return *this; 00365 } 00366 00367 /** 00368 * @brief Iterator postdecrement 00369 * @pre iterator is decrementable 00370 */ 00371 _Safe_iterator 00372 operator--(int) _GLIBCXX_NOEXCEPT 00373 { 00374 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 00375 _M_message(__msg_bad_dec) 00376 ._M_iterator(*this, "this")); 00377 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00378 return _Safe_iterator(base()--, this->_M_sequence, _Attach_single()); 00379 } 00380 00381 // ------ Random access iterator requirements ------ 00382 reference 00383 operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT 00384 { 00385 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 00386 && this->_M_can_advance(__n+1), 00387 _M_message(__msg_iter_subscript_oob) 00388 ._M_iterator(*this)._M_integer(__n)); 00389 return base()[__n]; 00390 } 00391 00392 _Safe_iterator& 00393 operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT 00394 { 00395 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 00396 _M_message(__msg_advance_oob) 00397 ._M_iterator(*this)._M_integer(__n)); 00398 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00399 base() += __n; 00400 return *this; 00401 } 00402 00403 _Safe_iterator 00404 operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT 00405 { 00406 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 00407 _M_message(__msg_advance_oob) 00408 ._M_iterator(*this)._M_integer(__n)); 00409 return _Safe_iterator(base() + __n, this->_M_sequence); 00410 } 00411 00412 _Safe_iterator& 00413 operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT 00414 { 00415 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 00416 _M_message(__msg_retreat_oob) 00417 ._M_iterator(*this)._M_integer(__n)); 00418 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 00419 base() -= __n; 00420 return *this; 00421 } 00422 00423 _Safe_iterator 00424 operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT 00425 { 00426 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 00427 _M_message(__msg_retreat_oob) 00428 ._M_iterator(*this)._M_integer(__n)); 00429 return _Safe_iterator(base() - __n, this->_M_sequence); 00430 } 00431 00432 // ------ Utilities ------ 00433 /** 00434 * @brief Return the underlying iterator 00435 */ 00436 _Iterator& 00437 base() _GLIBCXX_NOEXCEPT { return *this; } 00438 00439 const _Iterator& 00440 base() const _GLIBCXX_NOEXCEPT { return *this; } 00441 00442 /** 00443 * @brief Conversion to underlying non-debug iterator to allow 00444 * better interaction with non-debug containers. 00445 */ 00446 operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; } 00447 00448 /** Attach iterator to the given sequence. */ 00449 void 00450 _M_attach(_Safe_sequence_base* __seq) 00451 { _Safe_base::_M_attach(__seq, _M_constant()); } 00452 00453 /** Likewise, but not thread-safe. */ 00454 void 00455 _M_attach_single(_Safe_sequence_base* __seq) 00456 { _Safe_base::_M_attach_single(__seq, _M_constant()); } 00457 00458 /// Is the iterator dereferenceable? 00459 bool 00460 _M_dereferenceable() const 00461 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); } 00462 00463 /// Is the iterator before a dereferenceable one? 00464 bool 00465 _M_before_dereferenceable() const 00466 { 00467 if (this->_M_incrementable()) 00468 { 00469 _Iterator __base = base(); 00470 return ++__base != _M_get_sequence()->_M_base().end(); 00471 } 00472 return false; 00473 } 00474 00475 /// Is the iterator incrementable? 00476 bool 00477 _M_incrementable() const 00478 { return !this->_M_singular() && !_M_is_end(); } 00479 00480 // Is the iterator decrementable? 00481 bool 00482 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } 00483 00484 // Can we advance the iterator @p __n steps (@p __n may be negative) 00485 bool 00486 _M_can_advance(const difference_type& __n) const; 00487 00488 // Is the iterator range [*this, __rhs) valid? 00489 bool 00490 _M_valid_range(const _Safe_iterator& __rhs) const; 00491 00492 // The sequence this iterator references. 00493 typename 00494 __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator, 00495 _Safe_iterator>::__value, 00496 const _Sequence*, 00497 _Sequence*>::__type 00498 _M_get_sequence() const 00499 { return static_cast<_Sequence*>(_M_sequence); } 00500 00501 /// Is this iterator equal to the sequence's begin() iterator? 00502 bool 00503 _M_is_begin() const 00504 { return base() == _M_get_sequence()->_M_base().begin(); } 00505 00506 /// Is this iterator equal to the sequence's end() iterator? 00507 bool 00508 _M_is_end() const 00509 { return base() == _M_get_sequence()->_M_base().end(); } 00510 00511 /// Is this iterator equal to the sequence's before_begin() iterator if 00512 /// any? 00513 bool 00514 _M_is_before_begin() const 00515 { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); } 00516 00517 /// Is this iterator equal to the sequence's before_begin() iterator if 00518 /// any or begin() otherwise? 00519 bool 00520 _M_is_beginnest() const 00521 { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); } 00522 }; 00523 00524 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00525 inline bool 00526 operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00527 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00528 _GLIBCXX_NOEXCEPT 00529 { 00530 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00531 _M_message(__msg_iter_compare_bad) 00532 ._M_iterator(__lhs, "lhs") 00533 ._M_iterator(__rhs, "rhs")); 00534 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00535 _M_message(__msg_compare_different) 00536 ._M_iterator(__lhs, "lhs") 00537 ._M_iterator(__rhs, "rhs")); 00538 return __lhs.base() == __rhs.base(); 00539 } 00540 00541 template<typename _Iterator, typename _Sequence> 00542 inline bool 00543 operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00544 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00545 _GLIBCXX_NOEXCEPT 00546 { 00547 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00548 _M_message(__msg_iter_compare_bad) 00549 ._M_iterator(__lhs, "lhs") 00550 ._M_iterator(__rhs, "rhs")); 00551 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00552 _M_message(__msg_compare_different) 00553 ._M_iterator(__lhs, "lhs") 00554 ._M_iterator(__rhs, "rhs")); 00555 return __lhs.base() == __rhs.base(); 00556 } 00557 00558 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00559 inline bool 00560 operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00561 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00562 _GLIBCXX_NOEXCEPT 00563 { 00564 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00565 _M_message(__msg_iter_compare_bad) 00566 ._M_iterator(__lhs, "lhs") 00567 ._M_iterator(__rhs, "rhs")); 00568 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00569 _M_message(__msg_compare_different) 00570 ._M_iterator(__lhs, "lhs") 00571 ._M_iterator(__rhs, "rhs")); 00572 return __lhs.base() != __rhs.base(); 00573 } 00574 00575 template<typename _Iterator, typename _Sequence> 00576 inline bool 00577 operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00578 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00579 _GLIBCXX_NOEXCEPT 00580 { 00581 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00582 _M_message(__msg_iter_compare_bad) 00583 ._M_iterator(__lhs, "lhs") 00584 ._M_iterator(__rhs, "rhs")); 00585 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00586 _M_message(__msg_compare_different) 00587 ._M_iterator(__lhs, "lhs") 00588 ._M_iterator(__rhs, "rhs")); 00589 return __lhs.base() != __rhs.base(); 00590 } 00591 00592 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00593 inline bool 00594 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00595 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00596 _GLIBCXX_NOEXCEPT 00597 { 00598 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00599 _M_message(__msg_iter_order_bad) 00600 ._M_iterator(__lhs, "lhs") 00601 ._M_iterator(__rhs, "rhs")); 00602 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00603 _M_message(__msg_order_different) 00604 ._M_iterator(__lhs, "lhs") 00605 ._M_iterator(__rhs, "rhs")); 00606 return __lhs.base() < __rhs.base(); 00607 } 00608 00609 template<typename _Iterator, typename _Sequence> 00610 inline bool 00611 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00612 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00613 _GLIBCXX_NOEXCEPT 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 _IteratorL, typename _IteratorR, typename _Sequence> 00627 inline bool 00628 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00629 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00630 _GLIBCXX_NOEXCEPT 00631 { 00632 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00633 _M_message(__msg_iter_order_bad) 00634 ._M_iterator(__lhs, "lhs") 00635 ._M_iterator(__rhs, "rhs")); 00636 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00637 _M_message(__msg_order_different) 00638 ._M_iterator(__lhs, "lhs") 00639 ._M_iterator(__rhs, "rhs")); 00640 return __lhs.base() <= __rhs.base(); 00641 } 00642 00643 template<typename _Iterator, typename _Sequence> 00644 inline bool 00645 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00646 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00647 _GLIBCXX_NOEXCEPT 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 _IteratorL, typename _IteratorR, typename _Sequence> 00661 inline bool 00662 operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00663 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00664 _GLIBCXX_NOEXCEPT 00665 { 00666 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00667 _M_message(__msg_iter_order_bad) 00668 ._M_iterator(__lhs, "lhs") 00669 ._M_iterator(__rhs, "rhs")); 00670 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00671 _M_message(__msg_order_different) 00672 ._M_iterator(__lhs, "lhs") 00673 ._M_iterator(__rhs, "rhs")); 00674 return __lhs.base() > __rhs.base(); 00675 } 00676 00677 template<typename _Iterator, typename _Sequence> 00678 inline bool 00679 operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00680 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00681 _GLIBCXX_NOEXCEPT 00682 { 00683 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00684 _M_message(__msg_iter_order_bad) 00685 ._M_iterator(__lhs, "lhs") 00686 ._M_iterator(__rhs, "rhs")); 00687 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00688 _M_message(__msg_order_different) 00689 ._M_iterator(__lhs, "lhs") 00690 ._M_iterator(__rhs, "rhs")); 00691 return __lhs.base() > __rhs.base(); 00692 } 00693 00694 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00695 inline bool 00696 operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00697 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00698 _GLIBCXX_NOEXCEPT 00699 { 00700 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00701 _M_message(__msg_iter_order_bad) 00702 ._M_iterator(__lhs, "lhs") 00703 ._M_iterator(__rhs, "rhs")); 00704 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00705 _M_message(__msg_order_different) 00706 ._M_iterator(__lhs, "lhs") 00707 ._M_iterator(__rhs, "rhs")); 00708 return __lhs.base() >= __rhs.base(); 00709 } 00710 00711 template<typename _Iterator, typename _Sequence> 00712 inline bool 00713 operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00714 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00715 _GLIBCXX_NOEXCEPT 00716 { 00717 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00718 _M_message(__msg_iter_order_bad) 00719 ._M_iterator(__lhs, "lhs") 00720 ._M_iterator(__rhs, "rhs")); 00721 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00722 _M_message(__msg_order_different) 00723 ._M_iterator(__lhs, "lhs") 00724 ._M_iterator(__rhs, "rhs")); 00725 return __lhs.base() >= __rhs.base(); 00726 } 00727 00728 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00729 // According to the resolution of DR179 not only the various comparison 00730 // operators but also operator- must accept mixed iterator/const_iterator 00731 // parameters. 00732 template<typename _IteratorL, typename _IteratorR, typename _Sequence> 00733 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type 00734 operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 00735 const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 00736 _GLIBCXX_NOEXCEPT 00737 { 00738 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00739 _M_message(__msg_distance_bad) 00740 ._M_iterator(__lhs, "lhs") 00741 ._M_iterator(__rhs, "rhs")); 00742 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00743 _M_message(__msg_distance_different) 00744 ._M_iterator(__lhs, "lhs") 00745 ._M_iterator(__rhs, "rhs")); 00746 return __lhs.base() - __rhs.base(); 00747 } 00748 00749 template<typename _Iterator, typename _Sequence> 00750 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type 00751 operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 00752 const _Safe_iterator<_Iterator, _Sequence>& __rhs) 00753 _GLIBCXX_NOEXCEPT 00754 { 00755 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 00756 _M_message(__msg_distance_bad) 00757 ._M_iterator(__lhs, "lhs") 00758 ._M_iterator(__rhs, "rhs")); 00759 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 00760 _M_message(__msg_distance_different) 00761 ._M_iterator(__lhs, "lhs") 00762 ._M_iterator(__rhs, "rhs")); 00763 return __lhs.base() - __rhs.base(); 00764 } 00765 00766 template<typename _Iterator, typename _Sequence> 00767 inline _Safe_iterator<_Iterator, _Sequence> 00768 operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, 00769 const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT 00770 { return __i + __n; } 00771 } // namespace __gnu_debug 00772 00773 #include <debug/safe_iterator.tcc> 00774 00775 #endif