]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.6/include/debug/safe_iterator.h
update
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.6 / include / debug / safe_iterator.h
1 // Safe iterator implementation  -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011
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/safe_base.h>
37 #include <bits/stl_pair.h>
38 #include <bits/stl_iterator_base_types.h> // for _Iter_base
39 #include <ext/type_traits.h>
40
41 namespace __gnu_debug
42 {
43   /** Helper struct to deal with sequence offering a before_begin
44    *  iterator.
45    **/
46   template <typename _Sequence>
47     struct _BeforeBeginHelper
48     {
49       typedef typename _Sequence::const_iterator _It;
50       typedef typename _It::iterator_type _BaseIt;
51
52       static bool
53       _M_Is(_BaseIt __it, const _Sequence* __seq)
54       { return false; }
55     };
56
57   /** Iterators that derive from _Safe_iterator_base but that aren't
58    *  _Safe_iterators can be determined singular or non-singular via
59    *  _Safe_iterator_base.
60    */
61   inline bool 
62   __check_singular_aux(const _Safe_iterator_base* __x)
63   { return __x->_M_singular(); }
64
65   /** \brief Safe iterator wrapper.
66    *
67    *  The class template %_Safe_iterator is a wrapper around an
68    *  iterator that tracks the iterator's movement among sequences and
69    *  checks that operations performed on the "safe" iterator are
70    *  legal. In additional to the basic iterator operations (which are
71    *  validated, and then passed to the underlying iterator),
72    *  %_Safe_iterator has member functions for iterator invalidation,
73    *  attaching/detaching the iterator from sequences, and querying
74    *  the iterator's state.
75    */
76   template<typename _Iterator, typename _Sequence>
77     class _Safe_iterator : public _Safe_iterator_base
78     {
79       typedef _Safe_iterator _Self;
80
81       /** The precision to which we can calculate the distance between
82        *  two iterators.
83        */
84       enum _Distance_precision
85         {
86           __dp_equality, //< Can compare iterator equality, only
87           __dp_sign,     //< Can determine equality and ordering
88           __dp_exact     //< Can determine distance precisely
89         };
90
91       /// The underlying iterator
92       _Iterator _M_current;
93
94       /// Determine if this is a constant iterator.
95       bool
96       _M_constant() const
97       {
98         typedef typename _Sequence::const_iterator const_iterator;
99         return std::__are_same<const_iterator, _Safe_iterator>::__value;
100       }
101
102       typedef std::iterator_traits<_Iterator> _Traits;
103
104     public:
105       typedef _Iterator                           iterator_type;
106       typedef typename _Traits::iterator_category iterator_category;
107       typedef typename _Traits::value_type        value_type;
108       typedef typename _Traits::difference_type   difference_type;
109       typedef typename _Traits::reference         reference;
110       typedef typename _Traits::pointer           pointer;
111
112       /// @post the iterator is singular and unattached
113       _Safe_iterator() : _M_current() { }
114
115       /**
116        * @brief Safe iterator construction from an unsafe iterator and
117        * its sequence.
118        *
119        * @pre @p seq is not NULL
120        * @post this is not singular
121        */
122       _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
123       : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
124       {
125         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
126                               _M_message(__msg_init_singular)
127                               ._M_iterator(*this, "this"));
128       }
129
130       /**
131        * @brief Copy construction.
132        */
133       _Safe_iterator(const _Safe_iterator& __x)
134       : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
135       {
136         // _GLIBCXX_RESOLVE_LIB_DEFECTS
137         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
138         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
139                               || __x._M_current == _Iterator(),
140                               _M_message(__msg_init_copy_singular)
141                               ._M_iterator(*this, "this")
142                               ._M_iterator(__x, "other"));
143       }
144
145       /**
146        *  @brief Converting constructor from a mutable iterator to a
147        *  constant iterator.
148       */
149       template<typename _MutableIterator>
150         _Safe_iterator(
151           const _Safe_iterator<_MutableIterator,
152           typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
153                       typename _Sequence::iterator::iterator_type>::__value),
154                    _Sequence>::__type>& __x)
155         : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
156         {
157           // _GLIBCXX_RESOLVE_LIB_DEFECTS
158           // DR 408. Is vector<reverse_iterator<char*> > forbidden?
159           _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
160                                 || __x.base() == _Iterator(),
161                                 _M_message(__msg_init_const_singular)
162                                 ._M_iterator(*this, "this")
163                                 ._M_iterator(__x, "other"));
164         }
165
166       /**
167        * @brief Copy assignment.
168        */
169       _Safe_iterator&
170       operator=(const _Safe_iterator& __x)
171       {
172         // _GLIBCXX_RESOLVE_LIB_DEFECTS
173         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
174         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
175                               || __x._M_current == _Iterator(),
176                               _M_message(__msg_copy_singular)
177                               ._M_iterator(*this, "this")
178                               ._M_iterator(__x, "other"));
179         _M_current = __x._M_current;
180         this->_M_attach(__x._M_sequence);
181         return *this;
182       }
183
184       /**
185        *  @brief Iterator dereference.
186        *  @pre iterator is dereferenceable
187        */
188       reference
189       operator*() const
190       {
191         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
192                               _M_message(__msg_bad_deref)
193                               ._M_iterator(*this, "this"));
194         return *_M_current;
195       }
196
197       /**
198        *  @brief Iterator dereference.
199        *  @pre iterator is dereferenceable
200        *  @todo Make this correct w.r.t. iterators that return proxies
201        *  @todo Use addressof() instead of & operator
202        */
203       pointer
204       operator->() const
205       {
206         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
207                               _M_message(__msg_bad_deref)
208                               ._M_iterator(*this, "this"));
209         return &*_M_current;
210       }
211
212       // ------ Input iterator requirements ------
213       /**
214        *  @brief Iterator preincrement
215        *  @pre iterator is incrementable
216        */
217       _Safe_iterator&
218       operator++()
219       {
220         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
221                               _M_message(__msg_bad_inc)
222                               ._M_iterator(*this, "this"));
223         ++_M_current;
224         return *this;
225       }
226
227       /**
228        *  @brief Iterator postincrement
229        *  @pre iterator is incrementable
230        */
231       _Safe_iterator
232       operator++(int)
233       {
234         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
235                               _M_message(__msg_bad_inc)
236                               ._M_iterator(*this, "this"));
237         _Safe_iterator __tmp(*this);
238         ++_M_current;
239         return __tmp;
240       }
241
242       // ------ Bidirectional iterator requirements ------
243       /**
244        *  @brief Iterator predecrement
245        *  @pre iterator is decrementable
246        */
247       _Safe_iterator&
248       operator--()
249       {
250         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
251                               _M_message(__msg_bad_dec)
252                               ._M_iterator(*this, "this"));
253         --_M_current;
254         return *this;
255       }
256
257       /**
258        *  @brief Iterator postdecrement
259        *  @pre iterator is decrementable
260        */
261       _Safe_iterator
262       operator--(int)
263       {
264         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
265                               _M_message(__msg_bad_dec)
266                               ._M_iterator(*this, "this"));
267         _Safe_iterator __tmp(*this);
268         --_M_current;
269         return __tmp;
270       }
271
272       // ------ Random access iterator requirements ------
273       reference
274       operator[](const difference_type& __n) const
275       {
276         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
277                               && this->_M_can_advance(__n+1),
278                               _M_message(__msg_iter_subscript_oob)
279                               ._M_iterator(*this)._M_integer(__n));
280
281         return _M_current[__n];
282       }
283
284       _Safe_iterator&
285       operator+=(const difference_type& __n)
286       {
287         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
288                               _M_message(__msg_advance_oob)
289                               ._M_iterator(*this)._M_integer(__n));
290         _M_current += __n;
291         return *this;
292       }
293
294       _Safe_iterator
295       operator+(const difference_type& __n) const
296       {
297         _Safe_iterator __tmp(*this);
298         __tmp += __n;
299         return __tmp;
300       }
301
302       _Safe_iterator&
303       operator-=(const difference_type& __n)
304       {
305         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
306                               _M_message(__msg_retreat_oob)
307                               ._M_iterator(*this)._M_integer(__n));
308         _M_current += -__n;
309         return *this;
310       }
311
312       _Safe_iterator
313       operator-(const difference_type& __n) const
314       {
315         _Safe_iterator __tmp(*this);
316         __tmp -= __n;
317         return __tmp;
318       }
319
320       // ------ Utilities ------
321       /**
322        * @brief Return the underlying iterator
323        */
324       _Iterator
325       base() const { return _M_current; }
326
327       /**
328        * @brief Conversion to underlying non-debug iterator to allow
329        * better interaction with non-debug containers.
330        */
331       operator _Iterator() const { return _M_current; }
332
333       /** Attach iterator to the given sequence. */
334       void
335       _M_attach(_Safe_sequence_base* __seq)
336       {
337         _Safe_iterator_base::_M_attach(__seq, _M_constant());
338       }
339
340       /** Likewise, but not thread-safe. */
341       void
342       _M_attach_single(_Safe_sequence_base* __seq)
343       {
344         _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
345       }
346
347       /// Is the iterator dereferenceable?
348       bool
349       _M_dereferenceable() const
350       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
351
352       /// Is the iterator before a dereferenceable one?
353       bool
354       _M_before_dereferenceable() const
355       {
356         _Self __it = *this;
357         return __it._M_incrementable() && (++__it)._M_dereferenceable();
358       }
359
360       /// Is the iterator incrementable?
361       bool
362       _M_incrementable() const
363       { return !this->_M_singular() && !_M_is_end(); }
364
365       // Is the iterator decrementable?
366       bool
367       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
368
369       // Can we advance the iterator @p __n steps (@p __n may be negative)
370       bool
371       _M_can_advance(const difference_type& __n) const;
372
373       // Is the iterator range [*this, __rhs) valid?
374       template<typename _Other>
375         bool
376         _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
377
378       // The sequence this iterator references.
379       const _Sequence*
380       _M_get_sequence() const
381       { return static_cast<const _Sequence*>(_M_sequence); }
382
383     /** Determine the distance between two iterators with some known
384      *  precision.
385     */
386     template<typename _Iterator1, typename _Iterator2>
387       static std::pair<difference_type, _Distance_precision>
388       _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
389       {
390         typedef typename std::iterator_traits<_Iterator1>::iterator_category
391           _Category;
392         return _M_get_distance(__lhs, __rhs, _Category());
393       }
394
395     template<typename _Iterator1, typename _Iterator2>
396       static std::pair<difference_type, _Distance_precision>
397       _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
398                       std::random_access_iterator_tag)
399       { return std::make_pair(__rhs - __lhs, __dp_exact); }
400
401     template<typename _Iterator1, typename _Iterator2>
402       static std::pair<difference_type, _Distance_precision>
403       _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
404                     std::forward_iterator_tag)
405       { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
406
407       /// Is this iterator equal to the sequence's begin() iterator?
408       bool _M_is_begin() const
409       { return base() == _M_get_sequence()->_M_base().begin(); }
410
411       /// Is this iterator equal to the sequence's end() iterator?
412       bool _M_is_end() const
413       { return base() == _M_get_sequence()->_M_base().end(); }
414
415       /// Is this iterator equal to the sequence's before_begin() iterator if
416       /// any?
417       bool _M_is_before_begin() const
418       { return _BeforeBeginHelper<_Sequence>::_M_Is(base(), _M_get_sequence()); }
419     };
420
421   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
422     inline bool
423     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
424                const _Safe_iterator<_IteratorR, _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 _Iterator, typename _Sequence>
438     inline bool
439     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
440                const _Safe_iterator<_Iterator, _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 _IteratorL, typename _IteratorR, typename _Sequence>
454     inline bool
455     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
456                const _Safe_iterator<_IteratorR, _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 _Iterator, typename _Sequence>
470     inline bool
471     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
472                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
473     {
474       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
475                             _M_message(__msg_iter_compare_bad)
476                             ._M_iterator(__lhs, "lhs")
477                             ._M_iterator(__rhs, "rhs"));
478       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
479                             _M_message(__msg_compare_different)
480                             ._M_iterator(__lhs, "lhs")
481                             ._M_iterator(__rhs, "rhs"));
482       return __lhs.base() != __rhs.base();
483     }
484
485   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
486     inline bool
487     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
488               const _Safe_iterator<_IteratorR, _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 _Iterator, typename _Sequence>
502     inline bool
503     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
504               const _Safe_iterator<_Iterator, _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 _IteratorL, typename _IteratorR, typename _Sequence>
518     inline bool
519     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
520                const _Safe_iterator<_IteratorR, _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 _Iterator, typename _Sequence>
534     inline bool
535     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
536                const _Safe_iterator<_Iterator, _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 _IteratorL, typename _IteratorR, typename _Sequence>
550     inline bool
551     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
552               const _Safe_iterator<_IteratorR, _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 _Iterator, typename _Sequence>
566     inline bool
567     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
568               const _Safe_iterator<_Iterator, _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 _IteratorL, typename _IteratorR, typename _Sequence>
582     inline bool
583     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
584                const _Safe_iterator<_IteratorR, _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   template<typename _Iterator, typename _Sequence>
598     inline bool
599     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
600                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
601     {
602       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
603                             _M_message(__msg_iter_order_bad)
604                             ._M_iterator(__lhs, "lhs")
605                             ._M_iterator(__rhs, "rhs"));
606       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
607                             _M_message(__msg_order_different)
608                             ._M_iterator(__lhs, "lhs")
609                             ._M_iterator(__rhs, "rhs"));
610       return __lhs.base() >= __rhs.base();
611     }
612
613   // _GLIBCXX_RESOLVE_LIB_DEFECTS
614   // According to the resolution of DR179 not only the various comparison
615   // operators but also operator- must accept mixed iterator/const_iterator
616   // parameters.
617   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
618     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
619     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
620               const _Safe_iterator<_IteratorR, _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 typename _Safe_iterator<_Iterator, _Sequence>::difference_type
635      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
636                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
637      {
638        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
639                              _M_message(__msg_distance_bad)
640                              ._M_iterator(__lhs, "lhs")
641                              ._M_iterator(__rhs, "rhs"));
642        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
643                              _M_message(__msg_distance_different)
644                              ._M_iterator(__lhs, "lhs")
645                              ._M_iterator(__rhs, "rhs"));
646        return __lhs.base() - __rhs.base();
647      }
648
649   template<typename _Iterator, typename _Sequence>
650     inline _Safe_iterator<_Iterator, _Sequence>
651     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
652               const _Safe_iterator<_Iterator, _Sequence>& __i)
653     { return __i + __n; }
654
655   // Helper struct to detect random access safe iterators.
656   template<typename _Iterator>
657     struct __is_safe_random_iterator
658     {
659       enum { __value = 0 };
660       typedef std::__false_type __type;
661     };
662
663   template<typename _Iterator, typename _Sequence>
664     struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
665     : std::__are_same<std::random_access_iterator_tag,
666                       typename std::iterator_traits<_Iterator>::
667                       iterator_category>
668     { };
669
670   template<typename _Iterator>
671     struct _Siter_base
672     : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value>
673     { };
674
675   /** Helper function to extract base iterator of random access safe iterator
676       in order to reduce performance impact of debug mode.  Limited to random
677       access iterator because it is the only category for which it is possible
678       to check for correct iterators order in the __valid_range function
679       thanks to the < operator.
680   */
681   template<typename _Iterator>
682     inline typename _Siter_base<_Iterator>::iterator_type
683     __base(_Iterator __it)
684     { return _Siter_base<_Iterator>::_S_base(__it); }
685 } // namespace __gnu_debug
686
687 #include <debug/safe_iterator.tcc>
688
689 #endif