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