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