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