OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / safe_iterator.h
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
41 namespace __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