1*38fd1498Szrj // Safe iterator implementation -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2003-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file debug/safe_iterator.h 26*38fd1498Szrj * This file is a GNU debug extension to the Standard C++ Library. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 30*38fd1498Szrj #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 31*38fd1498Szrj 32*38fd1498Szrj #include <debug/assertions.h> 33*38fd1498Szrj #include <debug/macros.h> 34*38fd1498Szrj #include <debug/functions.h> 35*38fd1498Szrj #include <debug/safe_base.h> 36*38fd1498Szrj #include <bits/stl_pair.h> 37*38fd1498Szrj #include <ext/type_traits.h> 38*38fd1498Szrj 39*38fd1498Szrj namespace __gnu_debug 40*38fd1498Szrj { 41*38fd1498Szrj /** Helper struct to deal with sequence offering a before_begin 42*38fd1498Szrj * iterator. 43*38fd1498Szrj **/ 44*38fd1498Szrj template<typename _Sequence> 45*38fd1498Szrj struct _BeforeBeginHelper 46*38fd1498Szrj { 47*38fd1498Szrj template<typename _Iterator> 48*38fd1498Szrj static bool _S_Is_BeforeBeginHelper49*38fd1498Szrj _S_Is(const _Safe_iterator<_Iterator, _Sequence>&) 50*38fd1498Szrj { return false; } 51*38fd1498Szrj 52*38fd1498Szrj template<typename _Iterator> 53*38fd1498Szrj static bool _S_Is_Beginnest_BeforeBeginHelper54*38fd1498Szrj _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it) 55*38fd1498Szrj { return __it.base() == __it._M_get_sequence()->_M_base().begin(); } 56*38fd1498Szrj }; 57*38fd1498Szrj 58*38fd1498Szrj /** Sequence traits giving the size of a container if possible. */ 59*38fd1498Szrj template<typename _Sequence> 60*38fd1498Szrj struct _Sequence_traits 61*38fd1498Szrj { 62*38fd1498Szrj typedef _Distance_traits<typename _Sequence::iterator> _DistTraits; 63*38fd1498Szrj 64*38fd1498Szrj static typename _DistTraits::__type _S_size_Sequence_traits65*38fd1498Szrj _S_size(const _Sequence& __seq) 66*38fd1498Szrj { return std::make_pair(__seq.size(), __dp_exact); } 67*38fd1498Szrj }; 68*38fd1498Szrj 69*38fd1498Szrj /** \brief Safe iterator wrapper. 70*38fd1498Szrj * 71*38fd1498Szrj * The class template %_Safe_iterator is a wrapper around an 72*38fd1498Szrj * iterator that tracks the iterator's movement among sequences and 73*38fd1498Szrj * checks that operations performed on the "safe" iterator are 74*38fd1498Szrj * legal. In additional to the basic iterator operations (which are 75*38fd1498Szrj * validated, and then passed to the underlying iterator), 76*38fd1498Szrj * %_Safe_iterator has member functions for iterator invalidation, 77*38fd1498Szrj * attaching/detaching the iterator from sequences, and querying 78*38fd1498Szrj * the iterator's state. 79*38fd1498Szrj * 80*38fd1498Szrj * Note that _Iterator must be the first base class so that it gets 81*38fd1498Szrj * initialized before the iterator is being attached to the container's list 82*38fd1498Szrj * of iterators and it is being detached before _Iterator get 83*38fd1498Szrj * destroyed. Otherwise it would result in a data race. 84*38fd1498Szrj */ 85*38fd1498Szrj template<typename _Iterator, typename _Sequence> 86*38fd1498Szrj class _Safe_iterator 87*38fd1498Szrj : private _Iterator, 88*38fd1498Szrj public _Safe_iterator_base 89*38fd1498Szrj { 90*38fd1498Szrj typedef _Iterator _Iter_base; 91*38fd1498Szrj typedef _Safe_iterator_base _Safe_base; 92*38fd1498Szrj typedef typename _Sequence::const_iterator _Const_iterator; 93*38fd1498Szrj 94*38fd1498Szrj /// Determine if this is a constant iterator. 95*38fd1498Szrj bool _M_constant()96*38fd1498Szrj _M_constant() const 97*38fd1498Szrj { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; } 98*38fd1498Szrj 99*38fd1498Szrj typedef std::iterator_traits<_Iterator> _Traits; 100*38fd1498Szrj 101*38fd1498Szrj struct _Attach_single 102*38fd1498Szrj { }; 103*38fd1498Szrj _Safe_iterator(const _Iterator & __i,_Safe_sequence_base * __seq,_Attach_single)104*38fd1498Szrj _Safe_iterator(const _Iterator& __i, _Safe_sequence_base* __seq, 105*38fd1498Szrj _Attach_single) 106*38fd1498Szrj _GLIBCXX_NOEXCEPT 107*38fd1498Szrj : _Iter_base(__i) 108*38fd1498Szrj { _M_attach_single(__seq); } 109*38fd1498Szrj 110*38fd1498Szrj public: 111*38fd1498Szrj typedef _Iterator iterator_type; 112*38fd1498Szrj typedef typename _Traits::iterator_category iterator_category; 113*38fd1498Szrj typedef typename _Traits::value_type value_type; 114*38fd1498Szrj typedef typename _Traits::difference_type difference_type; 115*38fd1498Szrj typedef typename _Traits::reference reference; 116*38fd1498Szrj typedef typename _Traits::pointer pointer; 117*38fd1498Szrj 118*38fd1498Szrj /// @post the iterator is singular and unattached _Safe_iterator()119*38fd1498Szrj _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { } 120*38fd1498Szrj 121*38fd1498Szrj /** 122*38fd1498Szrj * @brief Safe iterator construction from an unsafe iterator and 123*38fd1498Szrj * its sequence. 124*38fd1498Szrj * 125*38fd1498Szrj * @pre @p seq is not NULL 126*38fd1498Szrj * @post this is not singular 127*38fd1498Szrj */ _Safe_iterator(const _Iterator & __i,const _Safe_sequence_base * __seq)128*38fd1498Szrj _Safe_iterator(const _Iterator& __i, const _Safe_sequence_base* __seq) 129*38fd1498Szrj _GLIBCXX_NOEXCEPT 130*38fd1498Szrj : _Iter_base(__i), _Safe_base(__seq, _M_constant()) 131*38fd1498Szrj { 132*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(), 133*38fd1498Szrj _M_message(__msg_init_singular) 134*38fd1498Szrj ._M_iterator(*this, "this")); 135*38fd1498Szrj } 136*38fd1498Szrj 137*38fd1498Szrj /** 138*38fd1498Szrj * @brief Copy construction. 139*38fd1498Szrj */ _Safe_iterator(const _Safe_iterator & __x)140*38fd1498Szrj _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 141*38fd1498Szrj : _Iter_base(__x.base()) 142*38fd1498Szrj { 143*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 144*38fd1498Szrj // DR 408. Is vector<reverse_iterator<char*> > forbidden? 145*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 146*38fd1498Szrj || __x.base() == _Iterator(), 147*38fd1498Szrj _M_message(__msg_init_copy_singular) 148*38fd1498Szrj ._M_iterator(*this, "this") 149*38fd1498Szrj ._M_iterator(__x, "other")); 150*38fd1498Szrj _M_attach(__x._M_sequence); 151*38fd1498Szrj } 152*38fd1498Szrj 153*38fd1498Szrj #if __cplusplus >= 201103L 154*38fd1498Szrj /** 155*38fd1498Szrj * @brief Move construction. 156*38fd1498Szrj * @post __x is singular and unattached 157*38fd1498Szrj */ _Safe_iterator(_Safe_iterator && __x)158*38fd1498Szrj _Safe_iterator(_Safe_iterator&& __x) noexcept 159*38fd1498Szrj : _Iter_base() 160*38fd1498Szrj { 161*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 162*38fd1498Szrj || __x.base() == _Iterator(), 163*38fd1498Szrj _M_message(__msg_init_copy_singular) 164*38fd1498Szrj ._M_iterator(*this, "this") 165*38fd1498Szrj ._M_iterator(__x, "other")); 166*38fd1498Szrj _Safe_sequence_base* __seq = __x._M_sequence; 167*38fd1498Szrj __x._M_detach(); 168*38fd1498Szrj std::swap(base(), __x.base()); 169*38fd1498Szrj _M_attach(__seq); 170*38fd1498Szrj } 171*38fd1498Szrj #endif 172*38fd1498Szrj 173*38fd1498Szrj /** 174*38fd1498Szrj * @brief Converting constructor from a mutable iterator to a 175*38fd1498Szrj * constant iterator. 176*38fd1498Szrj */ 177*38fd1498Szrj template<typename _MutableIterator> _Safe_iterator(const _Safe_iterator<_MutableIterator,typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,typename _Sequence::iterator::iterator_type>::__value),_Sequence>::__type> & __x)178*38fd1498Szrj _Safe_iterator( 179*38fd1498Szrj const _Safe_iterator<_MutableIterator, 180*38fd1498Szrj typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, 181*38fd1498Szrj typename _Sequence::iterator::iterator_type>::__value), 182*38fd1498Szrj _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT 183*38fd1498Szrj : _Iter_base(__x.base()) 184*38fd1498Szrj { 185*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 186*38fd1498Szrj // DR 408. Is vector<reverse_iterator<char*> > forbidden? 187*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 188*38fd1498Szrj || __x.base() == _Iterator(), 189*38fd1498Szrj _M_message(__msg_init_const_singular) 190*38fd1498Szrj ._M_iterator(*this, "this") 191*38fd1498Szrj ._M_iterator(__x, "other")); 192*38fd1498Szrj _M_attach(__x._M_sequence); 193*38fd1498Szrj } 194*38fd1498Szrj 195*38fd1498Szrj /** 196*38fd1498Szrj * @brief Copy assignment. 197*38fd1498Szrj */ 198*38fd1498Szrj _Safe_iterator& 199*38fd1498Szrj operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT 200*38fd1498Szrj { 201*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 202*38fd1498Szrj // DR 408. Is vector<reverse_iterator<char*> > forbidden? 203*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 204*38fd1498Szrj || __x.base() == _Iterator(), 205*38fd1498Szrj _M_message(__msg_copy_singular) 206*38fd1498Szrj ._M_iterator(*this, "this") 207*38fd1498Szrj ._M_iterator(__x, "other")); 208*38fd1498Szrj 209*38fd1498Szrj if (this->_M_sequence && this->_M_sequence == __x._M_sequence) 210*38fd1498Szrj { 211*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 212*38fd1498Szrj base() = __x.base(); 213*38fd1498Szrj _M_version = __x._M_sequence->_M_version; 214*38fd1498Szrj } 215*38fd1498Szrj else 216*38fd1498Szrj { 217*38fd1498Szrj _M_detach(); 218*38fd1498Szrj base() = __x.base(); 219*38fd1498Szrj _M_attach(__x._M_sequence); 220*38fd1498Szrj } 221*38fd1498Szrj 222*38fd1498Szrj return *this; 223*38fd1498Szrj } 224*38fd1498Szrj 225*38fd1498Szrj #if __cplusplus >= 201103L 226*38fd1498Szrj /** 227*38fd1498Szrj * @brief Move assignment. 228*38fd1498Szrj * @post __x is singular and unattached 229*38fd1498Szrj */ 230*38fd1498Szrj _Safe_iterator& 231*38fd1498Szrj operator=(_Safe_iterator&& __x) noexcept 232*38fd1498Szrj { 233*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this != &__x, 234*38fd1498Szrj _M_message(__msg_self_move_assign) 235*38fd1498Szrj ._M_iterator(*this, "this")); 236*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() 237*38fd1498Szrj || __x.base() == _Iterator(), 238*38fd1498Szrj _M_message(__msg_copy_singular) 239*38fd1498Szrj ._M_iterator(*this, "this") 240*38fd1498Szrj ._M_iterator(__x, "other")); 241*38fd1498Szrj 242*38fd1498Szrj if (this->_M_sequence && this->_M_sequence == __x._M_sequence) 243*38fd1498Szrj { 244*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 245*38fd1498Szrj base() = __x.base(); 246*38fd1498Szrj _M_version = __x._M_sequence->_M_version; 247*38fd1498Szrj } 248*38fd1498Szrj else 249*38fd1498Szrj { 250*38fd1498Szrj _M_detach(); 251*38fd1498Szrj base() = __x.base(); 252*38fd1498Szrj _M_attach(__x._M_sequence); 253*38fd1498Szrj } 254*38fd1498Szrj 255*38fd1498Szrj __x._M_detach(); 256*38fd1498Szrj __x.base() = _Iterator(); 257*38fd1498Szrj return *this; 258*38fd1498Szrj } 259*38fd1498Szrj #endif 260*38fd1498Szrj 261*38fd1498Szrj /** 262*38fd1498Szrj * @brief Iterator dereference. 263*38fd1498Szrj * @pre iterator is dereferenceable 264*38fd1498Szrj */ 265*38fd1498Szrj reference 266*38fd1498Szrj operator*() const _GLIBCXX_NOEXCEPT 267*38fd1498Szrj { 268*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 269*38fd1498Szrj _M_message(__msg_bad_deref) 270*38fd1498Szrj ._M_iterator(*this, "this")); 271*38fd1498Szrj return *base(); 272*38fd1498Szrj } 273*38fd1498Szrj 274*38fd1498Szrj /** 275*38fd1498Szrj * @brief Iterator dereference. 276*38fd1498Szrj * @pre iterator is dereferenceable 277*38fd1498Szrj */ 278*38fd1498Szrj pointer 279*38fd1498Szrj operator->() const _GLIBCXX_NOEXCEPT 280*38fd1498Szrj { 281*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), 282*38fd1498Szrj _M_message(__msg_bad_deref) 283*38fd1498Szrj ._M_iterator(*this, "this")); 284*38fd1498Szrj return base().operator->(); 285*38fd1498Szrj } 286*38fd1498Szrj 287*38fd1498Szrj // ------ Input iterator requirements ------ 288*38fd1498Szrj /** 289*38fd1498Szrj * @brief Iterator preincrement 290*38fd1498Szrj * @pre iterator is incrementable 291*38fd1498Szrj */ 292*38fd1498Szrj _Safe_iterator& 293*38fd1498Szrj operator++() _GLIBCXX_NOEXCEPT 294*38fd1498Szrj { 295*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 296*38fd1498Szrj _M_message(__msg_bad_inc) 297*38fd1498Szrj ._M_iterator(*this, "this")); 298*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 299*38fd1498Szrj ++base(); 300*38fd1498Szrj return *this; 301*38fd1498Szrj } 302*38fd1498Szrj 303*38fd1498Szrj /** 304*38fd1498Szrj * @brief Iterator postincrement 305*38fd1498Szrj * @pre iterator is incrementable 306*38fd1498Szrj */ 307*38fd1498Szrj _Safe_iterator 308*38fd1498Szrj operator++(int) _GLIBCXX_NOEXCEPT 309*38fd1498Szrj { 310*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), 311*38fd1498Szrj _M_message(__msg_bad_inc) 312*38fd1498Szrj ._M_iterator(*this, "this")); 313*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 314*38fd1498Szrj return _Safe_iterator(base()++, this->_M_sequence, _Attach_single()); 315*38fd1498Szrj } 316*38fd1498Szrj 317*38fd1498Szrj // ------ Bidirectional iterator requirements ------ 318*38fd1498Szrj /** 319*38fd1498Szrj * @brief Iterator predecrement 320*38fd1498Szrj * @pre iterator is decrementable 321*38fd1498Szrj */ 322*38fd1498Szrj _Safe_iterator& 323*38fd1498Szrj operator--() _GLIBCXX_NOEXCEPT 324*38fd1498Szrj { 325*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 326*38fd1498Szrj _M_message(__msg_bad_dec) 327*38fd1498Szrj ._M_iterator(*this, "this")); 328*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 329*38fd1498Szrj --base(); 330*38fd1498Szrj return *this; 331*38fd1498Szrj } 332*38fd1498Szrj 333*38fd1498Szrj /** 334*38fd1498Szrj * @brief Iterator postdecrement 335*38fd1498Szrj * @pre iterator is decrementable 336*38fd1498Szrj */ 337*38fd1498Szrj _Safe_iterator 338*38fd1498Szrj operator--(int) _GLIBCXX_NOEXCEPT 339*38fd1498Szrj { 340*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), 341*38fd1498Szrj _M_message(__msg_bad_dec) 342*38fd1498Szrj ._M_iterator(*this, "this")); 343*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 344*38fd1498Szrj return _Safe_iterator(base()--, this->_M_sequence, _Attach_single()); 345*38fd1498Szrj } 346*38fd1498Szrj 347*38fd1498Szrj // ------ Random access iterator requirements ------ 348*38fd1498Szrj reference 349*38fd1498Szrj operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT 350*38fd1498Szrj { 351*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 352*38fd1498Szrj && this->_M_can_advance(__n+1), 353*38fd1498Szrj _M_message(__msg_iter_subscript_oob) 354*38fd1498Szrj ._M_iterator(*this)._M_integer(__n)); 355*38fd1498Szrj return base()[__n]; 356*38fd1498Szrj } 357*38fd1498Szrj 358*38fd1498Szrj _Safe_iterator& 359*38fd1498Szrj operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT 360*38fd1498Szrj { 361*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 362*38fd1498Szrj _M_message(__msg_advance_oob) 363*38fd1498Szrj ._M_iterator(*this)._M_integer(__n)); 364*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 365*38fd1498Szrj base() += __n; 366*38fd1498Szrj return *this; 367*38fd1498Szrj } 368*38fd1498Szrj 369*38fd1498Szrj _Safe_iterator 370*38fd1498Szrj operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT 371*38fd1498Szrj { 372*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), 373*38fd1498Szrj _M_message(__msg_advance_oob) 374*38fd1498Szrj ._M_iterator(*this)._M_integer(__n)); 375*38fd1498Szrj return _Safe_iterator(base() + __n, this->_M_sequence); 376*38fd1498Szrj } 377*38fd1498Szrj 378*38fd1498Szrj _Safe_iterator& 379*38fd1498Szrj operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT 380*38fd1498Szrj { 381*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 382*38fd1498Szrj _M_message(__msg_retreat_oob) 383*38fd1498Szrj ._M_iterator(*this)._M_integer(__n)); 384*38fd1498Szrj __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 385*38fd1498Szrj base() -= __n; 386*38fd1498Szrj return *this; 387*38fd1498Szrj } 388*38fd1498Szrj 389*38fd1498Szrj _Safe_iterator 390*38fd1498Szrj operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT 391*38fd1498Szrj { 392*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), 393*38fd1498Szrj _M_message(__msg_retreat_oob) 394*38fd1498Szrj ._M_iterator(*this)._M_integer(__n)); 395*38fd1498Szrj return _Safe_iterator(base() - __n, this->_M_sequence); 396*38fd1498Szrj } 397*38fd1498Szrj 398*38fd1498Szrj // ------ Utilities ------ 399*38fd1498Szrj /** 400*38fd1498Szrj * @brief Return the underlying iterator 401*38fd1498Szrj */ 402*38fd1498Szrj _Iterator& base()403*38fd1498Szrj base() _GLIBCXX_NOEXCEPT { return *this; } 404*38fd1498Szrj 405*38fd1498Szrj const _Iterator& base()406*38fd1498Szrj base() const _GLIBCXX_NOEXCEPT { return *this; } 407*38fd1498Szrj 408*38fd1498Szrj /** 409*38fd1498Szrj * @brief Conversion to underlying non-debug iterator to allow 410*38fd1498Szrj * better interaction with non-debug containers. 411*38fd1498Szrj */ _Iterator()412*38fd1498Szrj operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; } 413*38fd1498Szrj 414*38fd1498Szrj /** Attach iterator to the given sequence. */ 415*38fd1498Szrj void _M_attach(_Safe_sequence_base * __seq)416*38fd1498Szrj _M_attach(_Safe_sequence_base* __seq) 417*38fd1498Szrj { _Safe_base::_M_attach(__seq, _M_constant()); } 418*38fd1498Szrj 419*38fd1498Szrj /** Likewise, but not thread-safe. */ 420*38fd1498Szrj void _M_attach_single(_Safe_sequence_base * __seq)421*38fd1498Szrj _M_attach_single(_Safe_sequence_base* __seq) 422*38fd1498Szrj { _Safe_base::_M_attach_single(__seq, _M_constant()); } 423*38fd1498Szrj 424*38fd1498Szrj /// Is the iterator dereferenceable? 425*38fd1498Szrj bool _M_dereferenceable()426*38fd1498Szrj _M_dereferenceable() const 427*38fd1498Szrj { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); } 428*38fd1498Szrj 429*38fd1498Szrj /// Is the iterator before a dereferenceable one? 430*38fd1498Szrj bool _M_before_dereferenceable()431*38fd1498Szrj _M_before_dereferenceable() const 432*38fd1498Szrj { 433*38fd1498Szrj if (this->_M_incrementable()) 434*38fd1498Szrj { 435*38fd1498Szrj _Iterator __base = base(); 436*38fd1498Szrj return ++__base != _M_get_sequence()->_M_base().end(); 437*38fd1498Szrj } 438*38fd1498Szrj return false; 439*38fd1498Szrj } 440*38fd1498Szrj 441*38fd1498Szrj /// Is the iterator incrementable? 442*38fd1498Szrj bool _M_incrementable()443*38fd1498Szrj _M_incrementable() const 444*38fd1498Szrj { return !this->_M_singular() && !_M_is_end(); } 445*38fd1498Szrj 446*38fd1498Szrj // Is the iterator decrementable? 447*38fd1498Szrj bool _M_decrementable()448*38fd1498Szrj _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } 449*38fd1498Szrj 450*38fd1498Szrj // Can we advance the iterator @p __n steps (@p __n may be negative) 451*38fd1498Szrj bool 452*38fd1498Szrj _M_can_advance(const difference_type& __n) const; 453*38fd1498Szrj 454*38fd1498Szrj // Is the iterator range [*this, __rhs) valid? 455*38fd1498Szrj bool 456*38fd1498Szrj _M_valid_range(const _Safe_iterator& __rhs, 457*38fd1498Szrj std::pair<difference_type, _Distance_precision>& __dist, 458*38fd1498Szrj bool __check_dereferenceable = true) const; 459*38fd1498Szrj 460*38fd1498Szrj // The sequence this iterator references. 461*38fd1498Szrj typename 462*38fd1498Szrj __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator, 463*38fd1498Szrj _Safe_iterator>::__value, 464*38fd1498Szrj const _Sequence*, 465*38fd1498Szrj _Sequence*>::__type _M_get_sequence()466*38fd1498Szrj _M_get_sequence() const 467*38fd1498Szrj { return static_cast<_Sequence*>(_M_sequence); } 468*38fd1498Szrj 469*38fd1498Szrj /// Is this iterator equal to the sequence's begin() iterator? 470*38fd1498Szrj bool _M_is_begin()471*38fd1498Szrj _M_is_begin() const 472*38fd1498Szrj { return base() == _M_get_sequence()->_M_base().begin(); } 473*38fd1498Szrj 474*38fd1498Szrj /// Is this iterator equal to the sequence's end() iterator? 475*38fd1498Szrj bool _M_is_end()476*38fd1498Szrj _M_is_end() const 477*38fd1498Szrj { return base() == _M_get_sequence()->_M_base().end(); } 478*38fd1498Szrj 479*38fd1498Szrj /// Is this iterator equal to the sequence's before_begin() iterator if 480*38fd1498Szrj /// any? 481*38fd1498Szrj bool _M_is_before_begin()482*38fd1498Szrj _M_is_before_begin() const 483*38fd1498Szrj { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); } 484*38fd1498Szrj 485*38fd1498Szrj /// Is this iterator equal to the sequence's before_begin() iterator if 486*38fd1498Szrj /// any or begin() otherwise? 487*38fd1498Szrj bool _M_is_beginnest()488*38fd1498Szrj _M_is_beginnest() const 489*38fd1498Szrj { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); } 490*38fd1498Szrj }; 491*38fd1498Szrj 492*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 493*38fd1498Szrj inline bool 494*38fd1498Szrj operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 495*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 496*38fd1498Szrj _GLIBCXX_NOEXCEPT 497*38fd1498Szrj { 498*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 499*38fd1498Szrj _M_message(__msg_iter_compare_bad) 500*38fd1498Szrj ._M_iterator(__lhs, "lhs") 501*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 502*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 503*38fd1498Szrj _M_message(__msg_compare_different) 504*38fd1498Szrj ._M_iterator(__lhs, "lhs") 505*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 506*38fd1498Szrj return __lhs.base() == __rhs.base(); 507*38fd1498Szrj } 508*38fd1498Szrj 509*38fd1498Szrj template<typename _Iterator, typename _Sequence> 510*38fd1498Szrj inline bool 511*38fd1498Szrj operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 512*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 513*38fd1498Szrj _GLIBCXX_NOEXCEPT 514*38fd1498Szrj { 515*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 516*38fd1498Szrj _M_message(__msg_iter_compare_bad) 517*38fd1498Szrj ._M_iterator(__lhs, "lhs") 518*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 519*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 520*38fd1498Szrj _M_message(__msg_compare_different) 521*38fd1498Szrj ._M_iterator(__lhs, "lhs") 522*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 523*38fd1498Szrj return __lhs.base() == __rhs.base(); 524*38fd1498Szrj } 525*38fd1498Szrj 526*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 527*38fd1498Szrj inline bool 528*38fd1498Szrj operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 529*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 530*38fd1498Szrj _GLIBCXX_NOEXCEPT 531*38fd1498Szrj { 532*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 533*38fd1498Szrj _M_message(__msg_iter_compare_bad) 534*38fd1498Szrj ._M_iterator(__lhs, "lhs") 535*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 536*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 537*38fd1498Szrj _M_message(__msg_compare_different) 538*38fd1498Szrj ._M_iterator(__lhs, "lhs") 539*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 540*38fd1498Szrj return __lhs.base() != __rhs.base(); 541*38fd1498Szrj } 542*38fd1498Szrj 543*38fd1498Szrj template<typename _Iterator, typename _Sequence> 544*38fd1498Szrj inline bool 545*38fd1498Szrj operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 546*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 547*38fd1498Szrj _GLIBCXX_NOEXCEPT 548*38fd1498Szrj { 549*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 550*38fd1498Szrj _M_message(__msg_iter_compare_bad) 551*38fd1498Szrj ._M_iterator(__lhs, "lhs") 552*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 553*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 554*38fd1498Szrj _M_message(__msg_compare_different) 555*38fd1498Szrj ._M_iterator(__lhs, "lhs") 556*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 557*38fd1498Szrj return __lhs.base() != __rhs.base(); 558*38fd1498Szrj } 559*38fd1498Szrj 560*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 561*38fd1498Szrj inline bool 562*38fd1498Szrj operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 563*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 564*38fd1498Szrj _GLIBCXX_NOEXCEPT 565*38fd1498Szrj { 566*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 567*38fd1498Szrj _M_message(__msg_iter_order_bad) 568*38fd1498Szrj ._M_iterator(__lhs, "lhs") 569*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 570*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 571*38fd1498Szrj _M_message(__msg_order_different) 572*38fd1498Szrj ._M_iterator(__lhs, "lhs") 573*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 574*38fd1498Szrj return __lhs.base() < __rhs.base(); 575*38fd1498Szrj } 576*38fd1498Szrj 577*38fd1498Szrj template<typename _Iterator, typename _Sequence> 578*38fd1498Szrj inline bool 579*38fd1498Szrj operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 580*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 581*38fd1498Szrj _GLIBCXX_NOEXCEPT 582*38fd1498Szrj { 583*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 584*38fd1498Szrj _M_message(__msg_iter_order_bad) 585*38fd1498Szrj ._M_iterator(__lhs, "lhs") 586*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 587*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 588*38fd1498Szrj _M_message(__msg_order_different) 589*38fd1498Szrj ._M_iterator(__lhs, "lhs") 590*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 591*38fd1498Szrj return __lhs.base() < __rhs.base(); 592*38fd1498Szrj } 593*38fd1498Szrj 594*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 595*38fd1498Szrj inline bool 596*38fd1498Szrj operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 597*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 598*38fd1498Szrj _GLIBCXX_NOEXCEPT 599*38fd1498Szrj { 600*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 601*38fd1498Szrj _M_message(__msg_iter_order_bad) 602*38fd1498Szrj ._M_iterator(__lhs, "lhs") 603*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 604*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 605*38fd1498Szrj _M_message(__msg_order_different) 606*38fd1498Szrj ._M_iterator(__lhs, "lhs") 607*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 608*38fd1498Szrj return __lhs.base() <= __rhs.base(); 609*38fd1498Szrj } 610*38fd1498Szrj 611*38fd1498Szrj template<typename _Iterator, typename _Sequence> 612*38fd1498Szrj inline bool 613*38fd1498Szrj operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 614*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 615*38fd1498Szrj _GLIBCXX_NOEXCEPT 616*38fd1498Szrj { 617*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 618*38fd1498Szrj _M_message(__msg_iter_order_bad) 619*38fd1498Szrj ._M_iterator(__lhs, "lhs") 620*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 621*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 622*38fd1498Szrj _M_message(__msg_order_different) 623*38fd1498Szrj ._M_iterator(__lhs, "lhs") 624*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 625*38fd1498Szrj return __lhs.base() <= __rhs.base(); 626*38fd1498Szrj } 627*38fd1498Szrj 628*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 629*38fd1498Szrj inline bool 630*38fd1498Szrj operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 631*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 632*38fd1498Szrj _GLIBCXX_NOEXCEPT 633*38fd1498Szrj { 634*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 635*38fd1498Szrj _M_message(__msg_iter_order_bad) 636*38fd1498Szrj ._M_iterator(__lhs, "lhs") 637*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 638*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 639*38fd1498Szrj _M_message(__msg_order_different) 640*38fd1498Szrj ._M_iterator(__lhs, "lhs") 641*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 642*38fd1498Szrj return __lhs.base() > __rhs.base(); 643*38fd1498Szrj } 644*38fd1498Szrj 645*38fd1498Szrj template<typename _Iterator, typename _Sequence> 646*38fd1498Szrj inline bool 647*38fd1498Szrj operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 648*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 649*38fd1498Szrj _GLIBCXX_NOEXCEPT 650*38fd1498Szrj { 651*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 652*38fd1498Szrj _M_message(__msg_iter_order_bad) 653*38fd1498Szrj ._M_iterator(__lhs, "lhs") 654*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 655*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 656*38fd1498Szrj _M_message(__msg_order_different) 657*38fd1498Szrj ._M_iterator(__lhs, "lhs") 658*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 659*38fd1498Szrj return __lhs.base() > __rhs.base(); 660*38fd1498Szrj } 661*38fd1498Szrj 662*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 663*38fd1498Szrj inline bool 664*38fd1498Szrj operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 665*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 666*38fd1498Szrj _GLIBCXX_NOEXCEPT 667*38fd1498Szrj { 668*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 669*38fd1498Szrj _M_message(__msg_iter_order_bad) 670*38fd1498Szrj ._M_iterator(__lhs, "lhs") 671*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 672*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 673*38fd1498Szrj _M_message(__msg_order_different) 674*38fd1498Szrj ._M_iterator(__lhs, "lhs") 675*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 676*38fd1498Szrj return __lhs.base() >= __rhs.base(); 677*38fd1498Szrj } 678*38fd1498Szrj 679*38fd1498Szrj template<typename _Iterator, typename _Sequence> 680*38fd1498Szrj inline bool 681*38fd1498Szrj operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 682*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 683*38fd1498Szrj _GLIBCXX_NOEXCEPT 684*38fd1498Szrj { 685*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 686*38fd1498Szrj _M_message(__msg_iter_order_bad) 687*38fd1498Szrj ._M_iterator(__lhs, "lhs") 688*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 689*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 690*38fd1498Szrj _M_message(__msg_order_different) 691*38fd1498Szrj ._M_iterator(__lhs, "lhs") 692*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 693*38fd1498Szrj return __lhs.base() >= __rhs.base(); 694*38fd1498Szrj } 695*38fd1498Szrj 696*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 697*38fd1498Szrj // According to the resolution of DR179 not only the various comparison 698*38fd1498Szrj // operators but also operator- must accept mixed iterator/const_iterator 699*38fd1498Szrj // parameters. 700*38fd1498Szrj template<typename _IteratorL, typename _IteratorR, typename _Sequence> 701*38fd1498Szrj inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type 702*38fd1498Szrj operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, 703*38fd1498Szrj const _Safe_iterator<_IteratorR, _Sequence>& __rhs) 704*38fd1498Szrj _GLIBCXX_NOEXCEPT 705*38fd1498Szrj { 706*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 707*38fd1498Szrj _M_message(__msg_distance_bad) 708*38fd1498Szrj ._M_iterator(__lhs, "lhs") 709*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 710*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 711*38fd1498Szrj _M_message(__msg_distance_different) 712*38fd1498Szrj ._M_iterator(__lhs, "lhs") 713*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 714*38fd1498Szrj return __lhs.base() - __rhs.base(); 715*38fd1498Szrj } 716*38fd1498Szrj 717*38fd1498Szrj template<typename _Iterator, typename _Sequence> 718*38fd1498Szrj inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type 719*38fd1498Szrj operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, 720*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __rhs) 721*38fd1498Szrj _GLIBCXX_NOEXCEPT 722*38fd1498Szrj { 723*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), 724*38fd1498Szrj _M_message(__msg_distance_bad) 725*38fd1498Szrj ._M_iterator(__lhs, "lhs") 726*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 727*38fd1498Szrj _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), 728*38fd1498Szrj _M_message(__msg_distance_different) 729*38fd1498Szrj ._M_iterator(__lhs, "lhs") 730*38fd1498Szrj ._M_iterator(__rhs, "rhs")); 731*38fd1498Szrj return __lhs.base() - __rhs.base(); 732*38fd1498Szrj } 733*38fd1498Szrj 734*38fd1498Szrj template<typename _Iterator, typename _Sequence> 735*38fd1498Szrj inline _Safe_iterator<_Iterator, _Sequence> 736*38fd1498Szrj operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, 737*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT 738*38fd1498Szrj { return __i + __n; } 739*38fd1498Szrj 740*38fd1498Szrj /** Safe iterators know if they are dereferenceable. */ 741*38fd1498Szrj template<typename _Iterator, typename _Sequence> 742*38fd1498Szrj inline bool __check_dereferenceable(const _Safe_iterator<_Iterator,_Sequence> & __x)743*38fd1498Szrj __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) 744*38fd1498Szrj { return __x._M_dereferenceable(); } 745*38fd1498Szrj 746*38fd1498Szrj /** Safe iterators know how to check if they form a valid range. */ 747*38fd1498Szrj template<typename _Iterator, typename _Sequence> 748*38fd1498Szrj inline bool __valid_range(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last,typename _Distance_traits<_Iterator>::__type & __dist)749*38fd1498Szrj __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, 750*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __last, 751*38fd1498Szrj typename _Distance_traits<_Iterator>::__type& __dist) 752*38fd1498Szrj { return __first._M_valid_range(__last, __dist); } 753*38fd1498Szrj 754*38fd1498Szrj /** Safe iterators can help to get better distance knowledge. */ 755*38fd1498Szrj template<typename _Iterator, typename _Sequence> 756*38fd1498Szrj inline typename _Distance_traits<_Iterator>::__type __get_distance(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last,std::random_access_iterator_tag)757*38fd1498Szrj __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first, 758*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __last, 759*38fd1498Szrj std::random_access_iterator_tag) 760*38fd1498Szrj { return std::make_pair(__last.base() - __first.base(), __dp_exact); } 761*38fd1498Szrj 762*38fd1498Szrj template<typename _Iterator, typename _Sequence> 763*38fd1498Szrj inline typename _Distance_traits<_Iterator>::__type __get_distance(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last,std::input_iterator_tag)764*38fd1498Szrj __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first, 765*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& __last, 766*38fd1498Szrj std::input_iterator_tag) 767*38fd1498Szrj { 768*38fd1498Szrj typedef typename _Distance_traits<_Iterator>::__type _Diff; 769*38fd1498Szrj typedef _Sequence_traits<_Sequence> _SeqTraits; 770*38fd1498Szrj 771*38fd1498Szrj if (__first.base() == __last.base()) 772*38fd1498Szrj return std::make_pair(0, __dp_exact); 773*38fd1498Szrj 774*38fd1498Szrj if (__first._M_is_before_begin()) 775*38fd1498Szrj { 776*38fd1498Szrj if (__last._M_is_begin()) 777*38fd1498Szrj return std::make_pair(1, __dp_exact); 778*38fd1498Szrj 779*38fd1498Szrj return std::make_pair(1, __dp_sign); 780*38fd1498Szrj } 781*38fd1498Szrj 782*38fd1498Szrj if (__first._M_is_begin()) 783*38fd1498Szrj { 784*38fd1498Szrj if (__last._M_is_before_begin()) 785*38fd1498Szrj return std::make_pair(-1, __dp_exact); 786*38fd1498Szrj 787*38fd1498Szrj if (__last._M_is_end()) 788*38fd1498Szrj return _SeqTraits::_S_size(*__first._M_get_sequence()); 789*38fd1498Szrj 790*38fd1498Szrj return std::make_pair(1, __dp_sign); 791*38fd1498Szrj } 792*38fd1498Szrj 793*38fd1498Szrj if (__first._M_is_end()) 794*38fd1498Szrj { 795*38fd1498Szrj if (__last._M_is_before_begin()) 796*38fd1498Szrj return std::make_pair(-1, __dp_exact); 797*38fd1498Szrj 798*38fd1498Szrj if (__last._M_is_begin()) 799*38fd1498Szrj { 800*38fd1498Szrj _Diff __diff = _SeqTraits::_S_size(*__first._M_get_sequence()); 801*38fd1498Szrj return std::make_pair(-__diff.first, __diff.second); 802*38fd1498Szrj } 803*38fd1498Szrj 804*38fd1498Szrj return std::make_pair(-1, __dp_sign); 805*38fd1498Szrj } 806*38fd1498Szrj 807*38fd1498Szrj if (__last._M_is_before_begin() || __last._M_is_begin()) 808*38fd1498Szrj return std::make_pair(-1, __dp_sign); 809*38fd1498Szrj 810*38fd1498Szrj if (__last._M_is_end()) 811*38fd1498Szrj return std::make_pair(1, __dp_sign); 812*38fd1498Szrj 813*38fd1498Szrj return std::make_pair(1, __dp_equality); 814*38fd1498Szrj } 815*38fd1498Szrj 816*38fd1498Szrj // Get distance from sequence begin to specified iterator. 817*38fd1498Szrj template<typename _Iterator, typename _Sequence> 818*38fd1498Szrj inline typename _Distance_traits<_Iterator>::__type __get_distance_from_begin(const _Safe_iterator<_Iterator,_Sequence> & __it)819*38fd1498Szrj __get_distance_from_begin(const _Safe_iterator<_Iterator, _Sequence>& __it) 820*38fd1498Szrj { 821*38fd1498Szrj typedef _Sequence_traits<_Sequence> _SeqTraits; 822*38fd1498Szrj 823*38fd1498Szrj // No need to consider before_begin as this function is only used in 824*38fd1498Szrj // _M_can_advance which won't be used for forward_list iterators. 825*38fd1498Szrj if (__it._M_is_begin()) 826*38fd1498Szrj return std::make_pair(0, __dp_exact); 827*38fd1498Szrj 828*38fd1498Szrj if (__it._M_is_end()) 829*38fd1498Szrj return _SeqTraits::_S_size(*__it._M_get_sequence()); 830*38fd1498Szrj 831*38fd1498Szrj typename _Distance_traits<_Iterator>::__type __res 832*38fd1498Szrj = __get_distance(__it._M_get_sequence()->_M_base().begin(), __it.base()); 833*38fd1498Szrj 834*38fd1498Szrj if (__res.second == __dp_equality) 835*38fd1498Szrj return std::make_pair(1, __dp_sign); 836*38fd1498Szrj 837*38fd1498Szrj return __res; 838*38fd1498Szrj } 839*38fd1498Szrj 840*38fd1498Szrj // Get distance from specified iterator to sequence end. 841*38fd1498Szrj template<typename _Iterator, typename _Sequence> 842*38fd1498Szrj inline typename _Distance_traits<_Iterator>::__type __get_distance_to_end(const _Safe_iterator<_Iterator,_Sequence> & __it)843*38fd1498Szrj __get_distance_to_end(const _Safe_iterator<_Iterator, _Sequence>& __it) 844*38fd1498Szrj { 845*38fd1498Szrj typedef _Sequence_traits<_Sequence> _SeqTraits; 846*38fd1498Szrj 847*38fd1498Szrj // No need to consider before_begin as this function is only used in 848*38fd1498Szrj // _M_can_advance which won't be used for forward_list iterators. 849*38fd1498Szrj if (__it._M_is_begin()) 850*38fd1498Szrj return _SeqTraits::_S_size(*__it._M_get_sequence()); 851*38fd1498Szrj 852*38fd1498Szrj if (__it._M_is_end()) 853*38fd1498Szrj return std::make_pair(0, __dp_exact); 854*38fd1498Szrj 855*38fd1498Szrj typename _Distance_traits<_Iterator>::__type __res 856*38fd1498Szrj = __get_distance(__it.base(), __it._M_get_sequence()->_M_base().end()); 857*38fd1498Szrj 858*38fd1498Szrj if (__res.second == __dp_equality) 859*38fd1498Szrj return std::make_pair(1, __dp_sign); 860*38fd1498Szrj 861*38fd1498Szrj return __res; 862*38fd1498Szrj } 863*38fd1498Szrj 864*38fd1498Szrj #if __cplusplus < 201103L 865*38fd1498Szrj template<typename _Iterator, typename _Sequence> 866*38fd1498Szrj struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> > 867*38fd1498Szrj : std::__are_same<std::random_access_iterator_tag, 868*38fd1498Szrj typename std::iterator_traits<_Iterator>:: 869*38fd1498Szrj iterator_category> 870*38fd1498Szrj { }; 871*38fd1498Szrj #else 872*38fd1498Szrj template<typename _Iterator, typename _Sequence> 873*38fd1498Szrj _Iterator 874*38fd1498Szrj __base(const _Safe_iterator<_Iterator, _Sequence>& __it, 875*38fd1498Szrj std::random_access_iterator_tag) 876*38fd1498Szrj { return __it.base(); } 877*38fd1498Szrj 878*38fd1498Szrj template<typename _Iterator, typename _Sequence> 879*38fd1498Szrj const _Safe_iterator<_Iterator, _Sequence>& 880*38fd1498Szrj __base(const _Safe_iterator<_Iterator, _Sequence>& __it, 881*38fd1498Szrj std::input_iterator_tag) 882*38fd1498Szrj { return __it; } 883*38fd1498Szrj 884*38fd1498Szrj template<typename _Iterator, typename _Sequence> 885*38fd1498Szrj auto 886*38fd1498Szrj __base(const _Safe_iterator<_Iterator, _Sequence>& __it) 887*38fd1498Szrj -> decltype(__base(__it, std::__iterator_category(__it))) 888*38fd1498Szrj { return __base(__it, std::__iterator_category(__it)); } 889*38fd1498Szrj #endif 890*38fd1498Szrj 891*38fd1498Szrj #if __cplusplus < 201103L 892*38fd1498Szrj template<typename _Iterator, typename _Sequence> 893*38fd1498Szrj struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> > 894*38fd1498Szrj { typedef _Iterator _Type; }; 895*38fd1498Szrj #endif 896*38fd1498Szrj 897*38fd1498Szrj template<typename _Iterator, typename _Sequence> 898*38fd1498Szrj inline _Iterator 899*38fd1498Szrj __unsafe(const _Safe_iterator<_Iterator, _Sequence>& __it) 900*38fd1498Szrj { return __it.base(); } 901*38fd1498Szrj 902*38fd1498Szrj } // namespace __gnu_debug 903*38fd1498Szrj 904*38fd1498Szrj #include <debug/safe_iterator.tcc> 905*38fd1498Szrj 906*38fd1498Szrj #endif 907