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