• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/arm-linux/include/c++/4.5.3/debug/
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       */
119      _Safe_iterator(const _Safe_iterator& __x)
120      : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
121      {
122	// _GLIBCXX_RESOLVE_LIB_DEFECTS
123	// DR 408. Is vector<reverse_iterator<char*> > forbidden?
124	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
125			      || __x._M_current == _Iterator(),
126			      _M_message(__msg_init_copy_singular)
127			      ._M_iterator(*this, "this")
128			      ._M_iterator(__x, "other"));
129      }
130
131      /**
132       *  @brief Converting constructor from a mutable iterator to a
133       *  constant iterator.
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_RESOLVE_LIB_DEFECTS
144	  // DR 408. Is vector<reverse_iterator<char*> > forbidden?
145	  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
146				|| __x.base() == _Iterator(),
147				_M_message(__msg_init_const_singular)
148				._M_iterator(*this, "this")
149				._M_iterator(__x, "other"));
150	}
151
152      /**
153       * @brief Copy assignment.
154       */
155      _Safe_iterator&
156      operator=(const _Safe_iterator& __x)
157      {
158	// _GLIBCXX_RESOLVE_LIB_DEFECTS
159	// DR 408. Is vector<reverse_iterator<char*> > forbidden?
160	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
161			      || __x._M_current == _Iterator(),
162			      _M_message(__msg_copy_singular)
163			      ._M_iterator(*this, "this")
164			      ._M_iterator(__x, "other"));
165	_M_current = __x._M_current;
166	this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
167	return *this;
168      }
169
170      /**
171       *  @brief Iterator dereference.
172       *  @pre iterator is dereferenceable
173       */
174      reference
175      operator*() const
176      {
177	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
178			      _M_message(__msg_bad_deref)
179			      ._M_iterator(*this, "this"));
180	return *_M_current;
181      }
182
183      /**
184       *  @brief Iterator dereference.
185       *  @pre iterator is dereferenceable
186       *  @todo Make this correct w.r.t. iterators that return proxies
187       *  @todo Use addressof() instead of & operator
188       */
189      pointer
190      operator->() const
191      {
192	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
193			      _M_message(__msg_bad_deref)
194			      ._M_iterator(*this, "this"));
195	return &*_M_current;
196      }
197
198      // ------ Input iterator requirements ------
199      /**
200       *  @brief Iterator preincrement
201       *  @pre iterator is incrementable
202       */
203      _Safe_iterator&
204      operator++()
205      {
206	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
207			      _M_message(__msg_bad_inc)
208			      ._M_iterator(*this, "this"));
209	++_M_current;
210	return *this;
211      }
212
213      /**
214       *  @brief Iterator postincrement
215       *  @pre iterator is incrementable
216       */
217      _Safe_iterator
218      operator++(int)
219      {
220	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
221			      _M_message(__msg_bad_inc)
222			      ._M_iterator(*this, "this"));
223	_Safe_iterator __tmp(*this);
224	++_M_current;
225	return __tmp;
226      }
227
228      // ------ Bidirectional iterator requirements ------
229      /**
230       *  @brief Iterator predecrement
231       *  @pre iterator is decrementable
232       */
233      _Safe_iterator&
234      operator--()
235      {
236	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
237			      _M_message(__msg_bad_dec)
238			      ._M_iterator(*this, "this"));
239	--_M_current;
240	return *this;
241      }
242
243      /**
244       *  @brief Iterator postdecrement
245       *  @pre iterator is decrementable
246       */
247      _Safe_iterator
248      operator--(int)
249      {
250	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
251			      _M_message(__msg_bad_dec)
252			      ._M_iterator(*this, "this"));
253	_Safe_iterator __tmp(*this);
254	--_M_current;
255	return __tmp;
256      }
257
258      // ------ Random access iterator requirements ------
259      reference
260      operator[](const difference_type& __n) const
261      {
262	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
263			      && this->_M_can_advance(__n+1),
264			      _M_message(__msg_iter_subscript_oob)
265			      ._M_iterator(*this)._M_integer(__n));
266
267	return _M_current[__n];
268      }
269
270      _Safe_iterator&
271      operator+=(const difference_type& __n)
272      {
273	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
274			      _M_message(__msg_advance_oob)
275			      ._M_iterator(*this)._M_integer(__n));
276	_M_current += __n;
277	return *this;
278      }
279
280      _Safe_iterator
281      operator+(const difference_type& __n) const
282      {
283	_Safe_iterator __tmp(*this);
284	__tmp += __n;
285	return __tmp;
286      }
287
288      _Safe_iterator&
289      operator-=(const difference_type& __n)
290      {
291	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
292			      _M_message(__msg_retreat_oob)
293			      ._M_iterator(*this)._M_integer(__n));
294	_M_current += -__n;
295	return *this;
296      }
297
298      _Safe_iterator
299      operator-(const difference_type& __n) const
300      {
301	_Safe_iterator __tmp(*this);
302	__tmp -= __n;
303	return __tmp;
304      }
305
306      // ------ Utilities ------
307      /**
308       * @brief Return the underlying iterator
309       */
310      _Iterator
311      base() const { return _M_current; }
312
313      /**
314       * @brief Conversion to underlying non-debug iterator to allow
315       * better interaction with non-debug containers.
316       */
317      operator _Iterator() const { return _M_current; }
318
319      /** Attach iterator to the given sequence. */
320      void
321      _M_attach(const _Sequence* __seq)
322      {
323	_Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
324				       _M_constant());
325      }
326
327      /** Likewise, but not thread-safe. */
328      void
329      _M_attach_single(const _Sequence* __seq)
330      {
331	_Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq),
332					      _M_constant());
333      }
334
335      /** Invalidate the iterator, making it singular. */
336      void
337      _M_invalidate();
338
339      /** Likewise, but not thread-safe. */
340      void
341      _M_invalidate_single();
342
343      /// Is the iterator dereferenceable?
344      bool
345      _M_dereferenceable() const
346      { return !this->_M_singular() && !_M_is_end(); }
347
348      /// Is the iterator incrementable?
349      bool
350      _M_incrementable() const { return this->_M_dereferenceable(); }
351
352      // Is the iterator decrementable?
353      bool
354      _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
355
356      // Can we advance the iterator @p __n steps (@p __n may be negative)
357      bool
358      _M_can_advance(const difference_type& __n) const;
359
360      // Is the iterator range [*this, __rhs) valid?
361      template<typename _Other>
362        bool
363        _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
364
365      // The sequence this iterator references.
366      const _Sequence*
367      _M_get_sequence() const
368      { return static_cast<const _Sequence*>(_M_sequence); }
369
370    /** Determine the distance between two iterators with some known
371     *	precision.
372    */
373    template<typename _Iterator1, typename _Iterator2>
374      static std::pair<difference_type, _Distance_precision>
375      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
376      {
377        typedef typename std::iterator_traits<_Iterator1>::iterator_category
378	  _Category;
379        return _M_get_distance(__lhs, __rhs, _Category());
380      }
381
382    template<typename _Iterator1, typename _Iterator2>
383      static std::pair<difference_type, _Distance_precision>
384      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
385		      std::random_access_iterator_tag)
386      {
387        return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
388      }
389
390    template<typename _Iterator1, typename _Iterator2>
391      static std::pair<difference_type, _Distance_precision>
392      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
393		    std::forward_iterator_tag)
394      {
395        return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
396			      __dp_equality);
397      }
398
399      /// Is this iterator equal to the sequence's begin() iterator?
400      bool _M_is_begin() const
401      {	return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); }
402
403      /// Is this iterator equal to the sequence's end() iterator?
404      bool _M_is_end() const
405      {	return *this == static_cast<const _Sequence*>(_M_sequence)->end(); }
406    };
407
408  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
409    inline bool
410    operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
411	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
412    {
413      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
414			    _M_message(__msg_iter_compare_bad)
415			    ._M_iterator(__lhs, "lhs")
416			    ._M_iterator(__rhs, "rhs"));
417      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
418			    _M_message(__msg_compare_different)
419			    ._M_iterator(__lhs, "lhs")
420			    ._M_iterator(__rhs, "rhs"));
421      return __lhs.base() == __rhs.base();
422    }
423
424  template<typename _Iterator, typename _Sequence>
425    inline bool
426    operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
427               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
428    {
429      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
430			    _M_message(__msg_iter_compare_bad)
431			    ._M_iterator(__lhs, "lhs")
432			    ._M_iterator(__rhs, "rhs"));
433      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
434			    _M_message(__msg_compare_different)
435			    ._M_iterator(__lhs, "lhs")
436			    ._M_iterator(__rhs, "rhs"));
437      return __lhs.base() == __rhs.base();
438    }
439
440  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
441    inline bool
442    operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
443	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
444    {
445      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
446			    _M_message(__msg_iter_compare_bad)
447			    ._M_iterator(__lhs, "lhs")
448			    ._M_iterator(__rhs, "rhs"));
449      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
450			    _M_message(__msg_compare_different)
451			    ._M_iterator(__lhs, "lhs")
452			    ._M_iterator(__rhs, "rhs"));
453      return __lhs.base() != __rhs.base();
454    }
455
456  template<typename _Iterator, typename _Sequence>
457    inline bool
458    operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
459               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
460    {
461      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
462			    _M_message(__msg_iter_compare_bad)
463			    ._M_iterator(__lhs, "lhs")
464			    ._M_iterator(__rhs, "rhs"));
465      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
466			    _M_message(__msg_compare_different)
467			    ._M_iterator(__lhs, "lhs")
468			    ._M_iterator(__rhs, "rhs"));
469      return __lhs.base() != __rhs.base();
470    }
471
472  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
473    inline bool
474    operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
475	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
476    {
477      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
478			    _M_message(__msg_iter_order_bad)
479			    ._M_iterator(__lhs, "lhs")
480			    ._M_iterator(__rhs, "rhs"));
481      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
482			    _M_message(__msg_order_different)
483			    ._M_iterator(__lhs, "lhs")
484			    ._M_iterator(__rhs, "rhs"));
485      return __lhs.base() < __rhs.base();
486    }
487
488  template<typename _Iterator, typename _Sequence>
489    inline bool
490    operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
491	      const _Safe_iterator<_Iterator, _Sequence>& __rhs)
492    {
493      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
494			    _M_message(__msg_iter_order_bad)
495			    ._M_iterator(__lhs, "lhs")
496			    ._M_iterator(__rhs, "rhs"));
497      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
498			    _M_message(__msg_order_different)
499			    ._M_iterator(__lhs, "lhs")
500			    ._M_iterator(__rhs, "rhs"));
501      return __lhs.base() < __rhs.base();
502    }
503
504  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
505    inline bool
506    operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
507	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
508    {
509      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
510			    _M_message(__msg_iter_order_bad)
511			    ._M_iterator(__lhs, "lhs")
512			    ._M_iterator(__rhs, "rhs"));
513      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
514			    _M_message(__msg_order_different)
515			    ._M_iterator(__lhs, "lhs")
516			    ._M_iterator(__rhs, "rhs"));
517      return __lhs.base() <= __rhs.base();
518    }
519
520  template<typename _Iterator, typename _Sequence>
521    inline bool
522    operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
523               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
524    {
525      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
526			    _M_message(__msg_iter_order_bad)
527			    ._M_iterator(__lhs, "lhs")
528			    ._M_iterator(__rhs, "rhs"));
529      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
530			    _M_message(__msg_order_different)
531			    ._M_iterator(__lhs, "lhs")
532			    ._M_iterator(__rhs, "rhs"));
533      return __lhs.base() <= __rhs.base();
534    }
535
536  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
537    inline bool
538    operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
539	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
540    {
541      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
542			    _M_message(__msg_iter_order_bad)
543			    ._M_iterator(__lhs, "lhs")
544			    ._M_iterator(__rhs, "rhs"));
545      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
546			    _M_message(__msg_order_different)
547			    ._M_iterator(__lhs, "lhs")
548			    ._M_iterator(__rhs, "rhs"));
549      return __lhs.base() > __rhs.base();
550    }
551
552  template<typename _Iterator, typename _Sequence>
553    inline bool
554    operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
555	      const _Safe_iterator<_Iterator, _Sequence>& __rhs)
556    {
557      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
558			    _M_message(__msg_iter_order_bad)
559			    ._M_iterator(__lhs, "lhs")
560			    ._M_iterator(__rhs, "rhs"));
561      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
562			    _M_message(__msg_order_different)
563			    ._M_iterator(__lhs, "lhs")
564			    ._M_iterator(__rhs, "rhs"));
565      return __lhs.base() > __rhs.base();
566    }
567
568  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
569    inline bool
570    operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
571	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
572    {
573      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
574			    _M_message(__msg_iter_order_bad)
575			    ._M_iterator(__lhs, "lhs")
576			    ._M_iterator(__rhs, "rhs"));
577      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
578			    _M_message(__msg_order_different)
579			    ._M_iterator(__lhs, "lhs")
580			    ._M_iterator(__rhs, "rhs"));
581      return __lhs.base() >= __rhs.base();
582    }
583
584  template<typename _Iterator, typename _Sequence>
585    inline bool
586    operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
587               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
588    {
589      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
590			    _M_message(__msg_iter_order_bad)
591			    ._M_iterator(__lhs, "lhs")
592			    ._M_iterator(__rhs, "rhs"));
593      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
594			    _M_message(__msg_order_different)
595			    ._M_iterator(__lhs, "lhs")
596			    ._M_iterator(__rhs, "rhs"));
597      return __lhs.base() >= __rhs.base();
598    }
599
600  // _GLIBCXX_RESOLVE_LIB_DEFECTS
601  // According to the resolution of DR179 not only the various comparison
602  // operators but also operator- must accept mixed iterator/const_iterator
603  // parameters.
604  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
605    inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
606    operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
607	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
608    {
609      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
610			    _M_message(__msg_distance_bad)
611			    ._M_iterator(__lhs, "lhs")
612			    ._M_iterator(__rhs, "rhs"));
613      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
614			    _M_message(__msg_distance_different)
615			    ._M_iterator(__lhs, "lhs")
616			    ._M_iterator(__rhs, "rhs"));
617      return __lhs.base() - __rhs.base();
618    }
619
620   template<typename _Iterator, typename _Sequence>
621     inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
622     operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
623	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
624     {
625       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
626			     _M_message(__msg_distance_bad)
627			     ._M_iterator(__lhs, "lhs")
628			     ._M_iterator(__rhs, "rhs"));
629       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
630			     _M_message(__msg_distance_different)
631			     ._M_iterator(__lhs, "lhs")
632			     ._M_iterator(__rhs, "rhs"));
633       return __lhs.base() - __rhs.base();
634     }
635
636  template<typename _Iterator, typename _Sequence>
637    inline _Safe_iterator<_Iterator, _Sequence>
638    operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
639	      const _Safe_iterator<_Iterator, _Sequence>& __i)
640    { return __i + __n; }
641} // namespace __gnu_debug
642
643#ifndef _GLIBCXX_EXPORT_TEMPLATE
644#  include <debug/safe_iterator.tcc>
645#endif
646
647#endif
648