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