1*404b540aSrobert // Safe iterator implementation -*- C++ -*- 2*404b540aSrobert 3*404b540aSrobert // Copyright (C) 2003, 2004, 2005, 2006 4*404b540aSrobert // Free Software Foundation, Inc. 5*404b540aSrobert // 6*404b540aSrobert // This file is part of the GNU ISO C++ Library. This library is free 7*404b540aSrobert // software; you can redistribute it and/or modify it under the 8*404b540aSrobert // terms of the GNU General Public License as published by the 9*404b540aSrobert // Free Software Foundation; either version 2, or (at your option) 10*404b540aSrobert // any later version. 11*404b540aSrobert 12*404b540aSrobert // This library is distributed in the hope that it will be useful, 13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of 14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*404b540aSrobert // GNU General Public License for more details. 16*404b540aSrobert 17*404b540aSrobert // You should have received a copy of the GNU General Public License along 18*404b540aSrobert // with this library; see the file COPYING. If not, write to the Free 19*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20*404b540aSrobert // USA. 21*404b540aSrobert 22*404b540aSrobert // As a special exception, you may use this file as part of a free software 23*404b540aSrobert // library without restriction. Specifically, if other files instantiate 24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile 25*404b540aSrobert // this file and link it with other files to produce an executable, this 26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by 27*404b540aSrobert // the GNU General Public License. This exception does not however 28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by 29*404b540aSrobert // the GNU General Public License. 30*404b540aSrobert 31*404b540aSrobert /** @file debug/safe_iterator.h 32*404b540aSrobert * This file is a GNU debug extension to the Standard C++ Library. 33*404b540aSrobert */ 34*404b540aSrobert 35*404b540aSrobert #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 36*404b540aSrobert #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 37*404b540aSrobert 38*404b540aSrobert #include <debug/debug.h> 39*404b540aSrobert #include <debug/macros.h> 40*404b540aSrobert #include <debug/functions.h> 41*404b540aSrobert #include <debug/formatter.h> 42*404b540aSrobert #include <debug/safe_base.h> 43*404b540aSrobert #include <bits/stl_pair.h> 44*404b540aSrobert #include <ext/type_traits.h> 45*404b540aSrobert 46*404b540aSrobert namespace __gnu_debug 47*404b540aSrobert { 48*404b540aSrobert /** Iterators that derive from _Safe_iterator_base but that aren't 49*404b540aSrobert * _Safe_iterators can be determined singular or non-singular via 50*404b540aSrobert * _Safe_iterator_base. 51*404b540aSrobert */ 52*404b540aSrobert inline bool __check_singular_aux(const _Safe_iterator_base * __x)53*404b540aSrobert __check_singular_aux(const _Safe_iterator_base* __x) 54*404b540aSrobert { return __x->_M_singular(); } 55*404b540aSrobert 56*404b540aSrobert /** \brief Safe iterator wrapper. 57*404b540aSrobert * 58*404b540aSrobert * The class template %_Safe_iterator is a wrapper around an 59*404b540aSrobert * iterator that tracks the iterator's movement among sequences and 60*404b540aSrobert * checks that operations performed on the "safe" iterator are 61*404b540aSrobert * legal. In additional to the basic iterator operations (which are 62*404b540aSrobert * validated, and then passed to the underlying iterator), 63*404b540aSrobert * %_Safe_iterator has member functions for iterator invalidation, 64*404b540aSrobert * attaching/detaching the iterator from sequences, and querying 65*404b540aSrobert * the iterator's state. 66*404b540aSrobert */ 67*404b540aSrobert template<typename _Iterator, typename _Sequence> 68*404b540aSrobert class _Safe_iterator : public _Safe_iterator_base 69*404b540aSrobert { 70*404b540aSrobert typedef _Safe_iterator _Self; 71*404b540aSrobert 72*404b540aSrobert /** The precision to which we can calculate the distance between 73*404b540aSrobert * two iterators. 74*404b540aSrobert */ 75*404b540aSrobert enum _Distance_precision 76*404b540aSrobert { 77*404b540aSrobert __dp_equality, //< Can compare iterator equality, only 78*404b540aSrobert __dp_sign, //< Can determine equality and ordering 79*404b540aSrobert __dp_exact //< Can determine distance precisely 80*404b540aSrobert }; 81*404b540aSrobert 82*404b540aSrobert /// The underlying iterator 83*404b540aSrobert _Iterator _M_current; 84*404b540aSrobert 85*404b540aSrobert /// Determine if this is a constant iterator. 86*404b540aSrobert bool _M_constant()87*404b540aSrobert _M_constant() const 88*404b540aSrobert { 89*404b540aSrobert typedef typename _Sequence::const_iterator const_iterator; 90*404b540aSrobert return __is_same<const_iterator, _Safe_iterator>::value; 91*404b540aSrobert } 92*404b540aSrobert 93*404b540aSrobert typedef std::iterator_traits<_Iterator> _Traits; 94*404b540aSrobert 95*404b540aSrobert public: 96*404b540aSrobert typedef _Iterator _Base_iterator; 97*404b540aSrobert typedef typename _Traits::iterator_category iterator_category; 98*404b540aSrobert typedef typename _Traits::value_type value_type; 99*404b540aSrobert typedef typename _Traits::difference_type difference_type; 100*404b540aSrobert typedef typename _Traits::reference reference; 101*404b540aSrobert typedef typename _Traits::pointer pointer; 102*404b540aSrobert 103*404b540aSrobert /// @post the iterator is singular and unattached _Safe_iterator()104*404b540aSrobert _Safe_iterator() : _M_current() { } 105*404b540aSrobert 106*404b540aSrobert /** 107*404b540aSrobert * @brief Safe iterator construction from an unsafe iterator and 108*404b540aSrobert * its sequence. 109*404b540aSrobert * 110*404b540aSrobert * @pre @p seq is not NULL 111*404b540aSrobert * @post this is not singular 112*404b540aSrobert */ _Safe_iterator(const _Iterator & __i,const _Sequence * __seq)113*404b540aSrobert _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) 114*404b540aSrobert : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) 115*404b540aSrobert { 116*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), 117*404b540aSrobert _M_message(__msg_init_singular) 118*404b540aSrobert ._M_iterator(*this, "this")); 119*404b540aSrobert } 120*404b540aSrobert 121*404b540aSrobert /** 122*404b540aSrobert * @brief Copy construction. 123*404b540aSrobert * @pre @p x is not singular 124*404b540aSrobert */ _Safe_iterator(const _Safe_iterator & __x)125*404b540aSrobert _Safe_iterator(const _Safe_iterator& __x) 126*404b540aSrobert : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) 127*404b540aSrobert { 128*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 129*404b540aSrobert _M_message(__msg_init_copy_singular) 130*404b540aSrobert ._M_iterator(*this, "this") 131*404b540aSrobert ._M_iterator(__x, "other")); 132*404b540aSrobert } 133*404b540aSrobert 134*404b540aSrobert /** 135*404b540aSrobert * @brief Converting constructor from a mutable iterator to a 136*404b540aSrobert * constant iterator. 137*404b540aSrobert * 138*404b540aSrobert * @pre @p x is not singular 139*404b540aSrobert */ 140*404b540aSrobert template<typename _MutableIterator> _Safe_iterator(const _Safe_iterator<_MutableIterator,typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,typename _Sequence::iterator::_Base_iterator>::__value),_Sequence>::__type> & __x)141*404b540aSrobert _Safe_iterator( 142*404b540aSrobert const _Safe_iterator<_MutableIterator, 143*404b540aSrobert typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, 144*404b540aSrobert typename _Sequence::iterator::_Base_iterator>::__value), 145*404b540aSrobert _Sequence>::__type>& __x) 146*404b540aSrobert : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) 147*404b540aSrobert { 148*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 149*404b540aSrobert _M_message(__msg_init_const_singular) 150*404b540aSrobert ._M_iterator(*this, "this") 151*404b540aSrobert ._M_iterator(__x, "other")); 152*404b540aSrobert } 153*404b540aSrobert 154*404b540aSrobert /** 155*404b540aSrobert * @brief Copy assignment. 156*404b540aSrobert * @pre @p x is not singular 157*404b540aSrobert */ 158*404b540aSrobert _Safe_iterator& 159*404b540aSrobert operator=(const _Safe_iterator& __x) 160*404b540aSrobert { 161*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), 162*404b540aSrobert _M_message(__msg_copy_singular) 163*404b540aSrobert ._M_iterator(*this, "this") 164*404b540aSrobert ._M_iterator(__x, "other")); 165*404b540aSrobert _M_current = __x._M_current; 166*404b540aSrobert this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); 167*404b540aSrobert return *this; 168*404b540aSrobert } 169*404b540aSrobert 170*404b540aSrobert /** 171*404b540aSrobert * @brief Iterator dereference. 172*404b540aSrobert * @pre iterator is dereferenceable 173*404b540aSrobert */ 174*404b540aSrobert reference 175*404b540aSrobert operator*() const 176*404b540aSrobert { 177*404b540aSrobert 178*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 179*404b540aSrobert _M_message(__msg_bad_deref) 180*404b540aSrobert ._M_iterator(*this, "this")); 181*404b540aSrobert return *_M_current; 182*404b540aSrobert } 183*404b540aSrobert 184*404b540aSrobert /** 185*404b540aSrobert * @brief Iterator dereference. 186*404b540aSrobert * @pre iterator is dereferenceable 187*404b540aSrobert * @todo Make this correct w.r.t. iterators that return proxies 188*404b540aSrobert * @todo Use addressof() instead of & operator 189*404b540aSrobert */ 190*404b540aSrobert pointer 191*404b540aSrobert operator->() const 192*404b540aSrobert { 193*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 194*404b540aSrobert _M_message(__msg_bad_deref) 195*404b540aSrobert ._M_iterator(*this, "this")); 196*404b540aSrobert return &*_M_current; 197*404b540aSrobert } 198*404b540aSrobert 199*404b540aSrobert // ------ Input iterator requirements ------ 200*404b540aSrobert /** 201*404b540aSrobert * @brief Iterator preincrement 202*404b540aSrobert * @pre iterator is incrementable 203*404b540aSrobert */ 204*404b540aSrobert _Safe_iterator& 205*404b540aSrobert operator++() 206*404b540aSrobert { 207*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 208*404b540aSrobert _M_message(__msg_bad_inc) 209*404b540aSrobert ._M_iterator(*this, "this")); 210*404b540aSrobert ++_M_current; 211*404b540aSrobert return *this; 212*404b540aSrobert } 213*404b540aSrobert 214*404b540aSrobert /** 215*404b540aSrobert * @brief Iterator postincrement 216*404b540aSrobert * @pre iterator is incrementable 217*404b540aSrobert */ 218*404b540aSrobert _Safe_iterator 219*404b540aSrobert operator++(int) 220*404b540aSrobert { 221*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 222*404b540aSrobert _M_message(__msg_bad_inc) 223*404b540aSrobert ._M_iterator(*this, "this")); 224*404b540aSrobert _Safe_iterator __tmp(*this); 225*404b540aSrobert ++_M_current; 226*404b540aSrobert return __tmp; 227*404b540aSrobert } 228*404b540aSrobert 229*404b540aSrobert // ------ Bidirectional iterator requirements ------ 230*404b540aSrobert /** 231*404b540aSrobert * @brief Iterator predecrement 232*404b540aSrobert * @pre iterator is decrementable 233*404b540aSrobert */ 234*404b540aSrobert _Safe_iterator& 235*404b540aSrobert operator--() 236*404b540aSrobert { 237*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 238*404b540aSrobert _M_message(__msg_bad_dec) 239*404b540aSrobert ._M_iterator(*this, "this")); 240*404b540aSrobert --_M_current; 241*404b540aSrobert return *this; 242*404b540aSrobert } 243*404b540aSrobert 244*404b540aSrobert /** 245*404b540aSrobert * @brief Iterator postdecrement 246*404b540aSrobert * @pre iterator is decrementable 247*404b540aSrobert */ 248*404b540aSrobert _Safe_iterator 249*404b540aSrobert operator--(int) 250*404b540aSrobert { 251*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 252*404b540aSrobert _M_message(__msg_bad_dec) 253*404b540aSrobert ._M_iterator(*this, "this")); 254*404b540aSrobert _Safe_iterator __tmp(*this); 255*404b540aSrobert --_M_current; 256*404b540aSrobert return __tmp; 257*404b540aSrobert } 258*404b540aSrobert 259*404b540aSrobert // ------ Random access iterator requirements ------ 260*404b540aSrobert reference 261*404b540aSrobert operator[](const difference_type& __n) const 262*404b540aSrobert { 263*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 264*404b540aSrobert && this->_M_can_advance(__n+1), 265*404b540aSrobert _M_message(__msg_iter_subscript_oob) 266*404b540aSrobert ._M_iterator(*this)._M_integer(__n)); 267*404b540aSrobert 268*404b540aSrobert return _M_current[__n]; 269*404b540aSrobert } 270*404b540aSrobert 271*404b540aSrobert _Safe_iterator& 272*404b540aSrobert operator+=(const difference_type& __n) 273*404b540aSrobert { 274*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 275*404b540aSrobert _M_message(__msg_advance_oob) 276*404b540aSrobert ._M_iterator(*this)._M_integer(__n)); 277*404b540aSrobert _M_current += __n; 278*404b540aSrobert return *this; 279*404b540aSrobert } 280*404b540aSrobert 281*404b540aSrobert _Safe_iterator 282*404b540aSrobert operator+(const difference_type& __n) const 283*404b540aSrobert { 284*404b540aSrobert _Safe_iterator __tmp(*this); 285*404b540aSrobert __tmp += __n; 286*404b540aSrobert return __tmp; 287*404b540aSrobert } 288*404b540aSrobert 289*404b540aSrobert _Safe_iterator& 290*404b540aSrobert operator-=(const difference_type& __n) 291*404b540aSrobert { 292*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 293*404b540aSrobert _M_message(__msg_retreat_oob) 294*404b540aSrobert ._M_iterator(*this)._M_integer(__n)); 295*404b540aSrobert _M_current += -__n; 296*404b540aSrobert return *this; 297*404b540aSrobert } 298*404b540aSrobert 299*404b540aSrobert _Safe_iterator 300*404b540aSrobert operator-(const difference_type& __n) const 301*404b540aSrobert { 302*404b540aSrobert _Safe_iterator __tmp(*this); 303*404b540aSrobert __tmp -= __n; 304*404b540aSrobert return __tmp; 305*404b540aSrobert } 306*404b540aSrobert 307*404b540aSrobert // ------ Utilities ------ 308*404b540aSrobert /** 309*404b540aSrobert * @brief Return the underlying iterator 310*404b540aSrobert */ 311*404b540aSrobert _Iterator base()312*404b540aSrobert base() const { return _M_current; } 313*404b540aSrobert 314*404b540aSrobert /** 315*404b540aSrobert * @brief Conversion to underlying non-debug iterator to allow 316*404b540aSrobert * better interaction with non-debug containers. 317*404b540aSrobert */ _Iterator()318*404b540aSrobert operator _Iterator() const { return _M_current; } 319*404b540aSrobert 320*404b540aSrobert /** Attach iterator to the given sequence. */ 321*404b540aSrobert void _M_attach(const _Sequence * __seq)322*404b540aSrobert _M_attach(const _Sequence* __seq) 323*404b540aSrobert { 324*404b540aSrobert _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), 325*404b540aSrobert _M_constant()); 326*404b540aSrobert } 327*404b540aSrobert 328*404b540aSrobert /** Likewise, but not thread-safe. */ 329*404b540aSrobert void _M_attach_single(const _Sequence * __seq)330*404b540aSrobert _M_attach_single(const _Sequence* __seq) 331*404b540aSrobert { 332*404b540aSrobert _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq), 333*404b540aSrobert _M_constant()); 334*404b540aSrobert } 335*404b540aSrobert 336*404b540aSrobert /** Invalidate the iterator, making it singular. */ 337*404b540aSrobert void 338*404b540aSrobert _M_invalidate(); 339*404b540aSrobert 340*404b540aSrobert /** Likewise, but not thread-safe. */ 341*404b540aSrobert void 342*404b540aSrobert _M_invalidate_single(); 343*404b540aSrobert 344*404b540aSrobert /// Is the iterator dereferenceable? 345*404b540aSrobert bool _M_dereferenceable()346*404b540aSrobert _M_dereferenceable() const 347*404b540aSrobert { return !this->_M_singular() && !_M_is_end(); } 348*404b540aSrobert 349*404b540aSrobert /// Is the iterator incrementable? 350*404b540aSrobert bool _M_incrementable()351*404b540aSrobert _M_incrementable() const { return this->_M_dereferenceable(); } 352*404b540aSrobert 353*404b540aSrobert // Is the iterator decrementable? 354*404b540aSrobert bool _M_decrementable()355*404b540aSrobert _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } 356*404b540aSrobert 357*404b540aSrobert // Can we advance the iterator @p __n steps (@p __n may be negative) 358*404b540aSrobert bool 359*404b540aSrobert _M_can_advance(const difference_type& __n) const; 360*404b540aSrobert 361*404b540aSrobert // Is the iterator range [*this, __rhs) valid? 362*404b540aSrobert template<typename _Other> 363*404b540aSrobert bool 364*404b540aSrobert _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; 365*404b540aSrobert 366*404b540aSrobert // The sequence this iterator references. 367*404b540aSrobert const _Sequence* _M_get_sequence()368*404b540aSrobert _M_get_sequence() const 369*404b540aSrobert { return static_cast<const _Sequence*>(_M_sequence); } 370*404b540aSrobert 371*404b540aSrobert /** Determine the distance between two iterators with some known 372*404b540aSrobert * precision. 373*404b540aSrobert */ 374*404b540aSrobert template<typename _Iterator1, typename _Iterator2> 375*404b540aSrobert static std::pair<difference_type, _Distance_precision> _M_get_distance(const _Iterator1 & __lhs,const _Iterator2 & __rhs)376*404b540aSrobert _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) 377*404b540aSrobert { 378*404b540aSrobert typedef typename std::iterator_traits<_Iterator1>::iterator_category 379*404b540aSrobert _Category; 380*404b540aSrobert return _M_get_distance(__lhs, __rhs, _Category()); 381*404b540aSrobert } 382*404b540aSrobert 383*404b540aSrobert template<typename _Iterator1, typename _Iterator2> 384*404b540aSrobert static std::pair<difference_type, _Distance_precision> _M_get_distance(const _Iterator1 & __lhs,const _Iterator2 & __rhs,std::random_access_iterator_tag)385*404b540aSrobert _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, 386*404b540aSrobert std::random_access_iterator_tag) 387*404b540aSrobert { 388*404b540aSrobert return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); 389*404b540aSrobert } 390*404b540aSrobert 391*404b540aSrobert template<typename _Iterator1, typename _Iterator2> 392*404b540aSrobert static std::pair<difference_type, _Distance_precision> _M_get_distance(const _Iterator1 & __lhs,const _Iterator2 & __rhs,std::forward_iterator_tag)393*404b540aSrobert _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, 394*404b540aSrobert std::forward_iterator_tag) 395*404b540aSrobert { 396*404b540aSrobert return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, 397*404b540aSrobert __dp_equality); 398*404b540aSrobert } 399*404b540aSrobert 400*404b540aSrobert /// Is this iterator equal to the sequence's begin() iterator? _M_is_begin()401*404b540aSrobert bool _M_is_begin() const 402*404b540aSrobert { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); } 403*404b540aSrobert 404*404b540aSrobert /// Is this iterator equal to the sequence's end() iterator? _M_is_end()405*404b540aSrobert bool _M_is_end() const 406*404b540aSrobert { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); } 407*404b540aSrobert }; 408*404b540aSrobert 409*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 410*404b540aSrobert inline bool 411*404b540aSrobert operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 412*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 413*404b540aSrobert { 414*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 415*404b540aSrobert _M_message(__msg_iter_compare_bad) 416*404b540aSrobert ._M_iterator(__lhs, "lhs") 417*404b540aSrobert ._M_iterator(__rhs, "rhs")); 418*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 419*404b540aSrobert _M_message(__msg_compare_different) 420*404b540aSrobert ._M_iterator(__lhs, "lhs") 421*404b540aSrobert ._M_iterator(__rhs, "rhs")); 422*404b540aSrobert return __lhs.base() == __rhs.base(); 423*404b540aSrobert } 424*404b540aSrobert 425*404b540aSrobert template<typename _Iterator, typename _Sequence> 426*404b540aSrobert inline bool 427*404b540aSrobert operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 428*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 429*404b540aSrobert { 430*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 431*404b540aSrobert _M_message(__msg_iter_compare_bad) 432*404b540aSrobert ._M_iterator(__lhs, "lhs") 433*404b540aSrobert ._M_iterator(__rhs, "rhs")); 434*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 435*404b540aSrobert _M_message(__msg_compare_different) 436*404b540aSrobert ._M_iterator(__lhs, "lhs") 437*404b540aSrobert ._M_iterator(__rhs, "rhs")); 438*404b540aSrobert return __lhs.base() == __rhs.base(); 439*404b540aSrobert } 440*404b540aSrobert 441*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 442*404b540aSrobert inline bool 443*404b540aSrobert operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 444*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 445*404b540aSrobert { 446*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 447*404b540aSrobert _M_message(__msg_iter_compare_bad) 448*404b540aSrobert ._M_iterator(__lhs, "lhs") 449*404b540aSrobert ._M_iterator(__rhs, "rhs")); 450*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 451*404b540aSrobert _M_message(__msg_compare_different) 452*404b540aSrobert ._M_iterator(__lhs, "lhs") 453*404b540aSrobert ._M_iterator(__rhs, "rhs")); 454*404b540aSrobert return __lhs.base() != __rhs.base(); 455*404b540aSrobert } 456*404b540aSrobert 457*404b540aSrobert template<typename _Iterator, typename _Sequence> 458*404b540aSrobert inline bool 459*404b540aSrobert operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 460*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 461*404b540aSrobert { 462*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 463*404b540aSrobert _M_message(__msg_iter_compare_bad) 464*404b540aSrobert ._M_iterator(__lhs, "lhs") 465*404b540aSrobert ._M_iterator(__rhs, "rhs")); 466*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 467*404b540aSrobert _M_message(__msg_compare_different) 468*404b540aSrobert ._M_iterator(__lhs, "lhs") 469*404b540aSrobert ._M_iterator(__rhs, "rhs")); 470*404b540aSrobert return __lhs.base() != __rhs.base(); 471*404b540aSrobert } 472*404b540aSrobert 473*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 474*404b540aSrobert inline bool 475*404b540aSrobert operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 476*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 477*404b540aSrobert { 478*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 479*404b540aSrobert _M_message(__msg_iter_order_bad) 480*404b540aSrobert ._M_iterator(__lhs, "lhs") 481*404b540aSrobert ._M_iterator(__rhs, "rhs")); 482*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 483*404b540aSrobert _M_message(__msg_order_different) 484*404b540aSrobert ._M_iterator(__lhs, "lhs") 485*404b540aSrobert ._M_iterator(__rhs, "rhs")); 486*404b540aSrobert return __lhs.base() < __rhs.base(); 487*404b540aSrobert } 488*404b540aSrobert 489*404b540aSrobert template<typename _Iterator, typename _Sequence> 490*404b540aSrobert inline bool 491*404b540aSrobert operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 492*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 493*404b540aSrobert { 494*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 495*404b540aSrobert _M_message(__msg_iter_order_bad) 496*404b540aSrobert ._M_iterator(__lhs, "lhs") 497*404b540aSrobert ._M_iterator(__rhs, "rhs")); 498*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 499*404b540aSrobert _M_message(__msg_order_different) 500*404b540aSrobert ._M_iterator(__lhs, "lhs") 501*404b540aSrobert ._M_iterator(__rhs, "rhs")); 502*404b540aSrobert return __lhs.base() < __rhs.base(); 503*404b540aSrobert } 504*404b540aSrobert 505*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 506*404b540aSrobert inline bool 507*404b540aSrobert operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 508*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 509*404b540aSrobert { 510*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 511*404b540aSrobert _M_message(__msg_iter_order_bad) 512*404b540aSrobert ._M_iterator(__lhs, "lhs") 513*404b540aSrobert ._M_iterator(__rhs, "rhs")); 514*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 515*404b540aSrobert _M_message(__msg_order_different) 516*404b540aSrobert ._M_iterator(__lhs, "lhs") 517*404b540aSrobert ._M_iterator(__rhs, "rhs")); 518*404b540aSrobert return __lhs.base() <= __rhs.base(); 519*404b540aSrobert } 520*404b540aSrobert 521*404b540aSrobert template<typename _Iterator, typename _Sequence> 522*404b540aSrobert inline bool 523*404b540aSrobert operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 524*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 525*404b540aSrobert { 526*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 527*404b540aSrobert _M_message(__msg_iter_order_bad) 528*404b540aSrobert ._M_iterator(__lhs, "lhs") 529*404b540aSrobert ._M_iterator(__rhs, "rhs")); 530*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 531*404b540aSrobert _M_message(__msg_order_different) 532*404b540aSrobert ._M_iterator(__lhs, "lhs") 533*404b540aSrobert ._M_iterator(__rhs, "rhs")); 534*404b540aSrobert return __lhs.base() <= __rhs.base(); 535*404b540aSrobert } 536*404b540aSrobert 537*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 538*404b540aSrobert inline bool 539*404b540aSrobert operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 540*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 541*404b540aSrobert { 542*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 543*404b540aSrobert _M_message(__msg_iter_order_bad) 544*404b540aSrobert ._M_iterator(__lhs, "lhs") 545*404b540aSrobert ._M_iterator(__rhs, "rhs")); 546*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 547*404b540aSrobert _M_message(__msg_order_different) 548*404b540aSrobert ._M_iterator(__lhs, "lhs") 549*404b540aSrobert ._M_iterator(__rhs, "rhs")); 550*404b540aSrobert return __lhs.base() > __rhs.base(); 551*404b540aSrobert } 552*404b540aSrobert 553*404b540aSrobert template<typename _Iterator, typename _Sequence> 554*404b540aSrobert inline bool 555*404b540aSrobert operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 556*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 557*404b540aSrobert { 558*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 559*404b540aSrobert _M_message(__msg_iter_order_bad) 560*404b540aSrobert ._M_iterator(__lhs, "lhs") 561*404b540aSrobert ._M_iterator(__rhs, "rhs")); 562*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 563*404b540aSrobert _M_message(__msg_order_different) 564*404b540aSrobert ._M_iterator(__lhs, "lhs") 565*404b540aSrobert ._M_iterator(__rhs, "rhs")); 566*404b540aSrobert return __lhs.base() > __rhs.base(); 567*404b540aSrobert } 568*404b540aSrobert 569*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 570*404b540aSrobert inline bool 571*404b540aSrobert operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 572*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 573*404b540aSrobert { 574*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 575*404b540aSrobert _M_message(__msg_iter_order_bad) 576*404b540aSrobert ._M_iterator(__lhs, "lhs") 577*404b540aSrobert ._M_iterator(__rhs, "rhs")); 578*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 579*404b540aSrobert _M_message(__msg_order_different) 580*404b540aSrobert ._M_iterator(__lhs, "lhs") 581*404b540aSrobert ._M_iterator(__rhs, "rhs")); 582*404b540aSrobert return __lhs.base() >= __rhs.base(); 583*404b540aSrobert } 584*404b540aSrobert 585*404b540aSrobert template<typename _Iterator, typename _Sequence> 586*404b540aSrobert inline bool 587*404b540aSrobert operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 588*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 589*404b540aSrobert { 590*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 591*404b540aSrobert _M_message(__msg_iter_order_bad) 592*404b540aSrobert ._M_iterator(__lhs, "lhs") 593*404b540aSrobert ._M_iterator(__rhs, "rhs")); 594*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 595*404b540aSrobert _M_message(__msg_order_different) 596*404b540aSrobert ._M_iterator(__lhs, "lhs") 597*404b540aSrobert ._M_iterator(__rhs, "rhs")); 598*404b540aSrobert return __lhs.base() >= __rhs.base(); 599*404b540aSrobert } 600*404b540aSrobert 601*404b540aSrobert // _GLIBCXX_RESOLVE_LIB_DEFECTS 602*404b540aSrobert // According to the resolution of DR179 not only the various comparison 603*404b540aSrobert // operators but also operator- must accept mixed iterator/const_iterator 604*404b540aSrobert // parameters. 605*404b540aSrobert template<typename _IteratorL, typename _IteratorR, typename _Sequence> 606*404b540aSrobert inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type 607*404b540aSrobert operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 608*404b540aSrobert const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 609*404b540aSrobert { 610*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 611*404b540aSrobert _M_message(__msg_distance_bad) 612*404b540aSrobert ._M_iterator(__lhs, "lhs") 613*404b540aSrobert ._M_iterator(__rhs, "rhs")); 614*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 615*404b540aSrobert _M_message(__msg_distance_different) 616*404b540aSrobert ._M_iterator(__lhs, "lhs") 617*404b540aSrobert ._M_iterator(__rhs, "rhs")); 618*404b540aSrobert return __lhs.base() - __rhs.base(); 619*404b540aSrobert } 620*404b540aSrobert 621*404b540aSrobert template<typename _Iterator, typename _Sequence> 622*404b540aSrobert inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type 623*404b540aSrobert operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 624*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __rhs) 625*404b540aSrobert { 626*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 627*404b540aSrobert _M_message(__msg_distance_bad) 628*404b540aSrobert ._M_iterator(__lhs, "lhs") 629*404b540aSrobert ._M_iterator(__rhs, "rhs")); 630*404b540aSrobert _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 631*404b540aSrobert _M_message(__msg_distance_different) 632*404b540aSrobert ._M_iterator(__lhs, "lhs") 633*404b540aSrobert ._M_iterator(__rhs, "rhs")); 634*404b540aSrobert return __lhs.base() - __rhs.base(); 635*404b540aSrobert } 636*404b540aSrobert 637*404b540aSrobert template<typename _Iterator, typename _Sequence> 638*404b540aSrobert inline _Safe_iterator<_Iterator, _Sequence> 639*404b540aSrobert operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, 640*404b540aSrobert const _Safe_iterator<_Iterator, _Sequence>& __i) 641*404b540aSrobert { return __i + __n; } 642*404b540aSrobert } // namespace __gnu_debug 643*404b540aSrobert 644*404b540aSrobert #ifndef _GLIBCXX_EXPORT_TEMPLATE 645*404b540aSrobert # include <debug/safe_iterator.tcc> 646*404b540aSrobert #endif 647*404b540aSrobert 648*404b540aSrobert #endif 649