OSDN Git Service

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