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