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