Import gcc-4.7.2 to new vendor branch
[dragonfly.git] / contrib / gcc-4.7 / libstdc++-v3 / include / debug / safe_iterator.h
1 // Safe iterator implementation  -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2012
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       _S_Is(_BaseIt, const _Sequence*)
54       { return false; }
55
56       static bool
57       _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
58       { return __it == __seq->_M_base().begin(); }
59     };
60
61   /** Iterators that derive from _Safe_iterator_base but that aren't
62    *  _Safe_iterators can be determined singular or non-singular via
63    *  _Safe_iterator_base.
64    */
65   inline bool 
66   __check_singular_aux(const _Safe_iterator_base* __x)
67   { return __x->_M_singular(); }
68
69   /** The precision to which we can calculate the distance between
70    *  two iterators.
71    */
72   enum _Distance_precision
73     {
74       __dp_equality, //< Can compare iterator equality, only
75       __dp_sign,     //< Can determine equality and ordering
76       __dp_exact     //< Can determine distance precisely
77     };
78
79   /** Determine the distance between two iterators with some known
80    *    precision.
81   */
82   template<typename _Iterator1, typename _Iterator2>
83     inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
84                      _Distance_precision>
85     __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
86                    std::random_access_iterator_tag)
87     { return std::make_pair(__rhs - __lhs, __dp_exact); }
88
89   template<typename _Iterator1, typename _Iterator2>
90     inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
91                      _Distance_precision>
92     __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
93                    std::forward_iterator_tag)
94     { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
95
96   template<typename _Iterator1, typename _Iterator2>
97     inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
98                      _Distance_precision>
99     __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
100     {
101       typedef typename std::iterator_traits<_Iterator1>::iterator_category
102           _Category;
103       return __get_distance(__lhs, __rhs, _Category());
104     }
105
106   /** \brief Safe iterator wrapper.
107    *
108    *  The class template %_Safe_iterator is a wrapper around an
109    *  iterator that tracks the iterator's movement among sequences and
110    *  checks that operations performed on the "safe" iterator are
111    *  legal. In additional to the basic iterator operations (which are
112    *  validated, and then passed to the underlying iterator),
113    *  %_Safe_iterator has member functions for iterator invalidation,
114    *  attaching/detaching the iterator from sequences, and querying
115    *  the iterator's state.
116    */
117   template<typename _Iterator, typename _Sequence>
118     class _Safe_iterator : public _Safe_iterator_base
119     {
120       typedef _Safe_iterator _Self;
121
122       /// The underlying iterator
123       _Iterator _M_current;
124
125       /// Determine if this is a constant iterator.
126       bool
127       _M_constant() const
128       {
129         typedef typename _Sequence::const_iterator const_iterator;
130         return std::__are_same<const_iterator, _Safe_iterator>::__value;
131       }
132
133       typedef std::iterator_traits<_Iterator> _Traits;
134
135     public:
136       typedef _Iterator                           iterator_type;
137       typedef typename _Traits::iterator_category iterator_category;
138       typedef typename _Traits::value_type        value_type;
139       typedef typename _Traits::difference_type   difference_type;
140       typedef typename _Traits::reference         reference;
141       typedef typename _Traits::pointer           pointer;
142
143       /// @post the iterator is singular and unattached
144       _Safe_iterator() : _M_current() { }
145
146       /**
147        * @brief Safe iterator construction from an unsafe iterator and
148        * its sequence.
149        *
150        * @pre @p seq is not NULL
151        * @post this is not singular
152        */
153       _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
154       : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
155       {
156         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
157                               _M_message(__msg_init_singular)
158                               ._M_iterator(*this, "this"));
159       }
160
161       /**
162        * @brief Copy construction.
163        */
164       _Safe_iterator(const _Safe_iterator& __x)
165       : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
166       {
167         // _GLIBCXX_RESOLVE_LIB_DEFECTS
168         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
169         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
170                               || __x._M_current == _Iterator(),
171                               _M_message(__msg_init_copy_singular)
172                               ._M_iterator(*this, "this")
173                               ._M_iterator(__x, "other"));
174       }
175
176 #ifdef __GXX_EXPERIMENTAL_CXX0X__
177       /**
178        * @brief Move construction.
179        * @post __x is singular and unattached
180        */
181       _Safe_iterator(_Safe_iterator&& __x) : _M_current()
182       {
183         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
184                               || __x._M_current == _Iterator(),
185                               _M_message(__msg_init_copy_singular)
186                               ._M_iterator(*this, "this")
187                               ._M_iterator(__x, "other"));
188         std::swap(_M_current, __x._M_current);
189         this->_M_attach(__x._M_sequence);
190         __x._M_detach();
191       }
192 #endif
193
194       /**
195        *  @brief Converting constructor from a mutable iterator to a
196        *  constant iterator.
197       */
198       template<typename _MutableIterator>
199         _Safe_iterator(
200           const _Safe_iterator<_MutableIterator,
201           typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
202                       typename _Sequence::iterator::iterator_type>::__value),
203                    _Sequence>::__type>& __x)
204         : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
205         {
206           // _GLIBCXX_RESOLVE_LIB_DEFECTS
207           // DR 408. Is vector<reverse_iterator<char*> > forbidden?
208           _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
209                                 || __x.base() == _Iterator(),
210                                 _M_message(__msg_init_const_singular)
211                                 ._M_iterator(*this, "this")
212                                 ._M_iterator(__x, "other"));
213         }
214
215       /**
216        * @brief Copy assignment.
217        */
218       _Safe_iterator&
219       operator=(const _Safe_iterator& __x)
220       {
221         // _GLIBCXX_RESOLVE_LIB_DEFECTS
222         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
223         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
224                               || __x._M_current == _Iterator(),
225                               _M_message(__msg_copy_singular)
226                               ._M_iterator(*this, "this")
227                               ._M_iterator(__x, "other"));
228         _M_current = __x._M_current;
229         this->_M_attach(__x._M_sequence);
230         return *this;
231       }
232
233 #ifdef __GXX_EXPERIMENTAL_CXX0X__
234       /**
235        * @brief Move assignment.
236        * @post __x is singular and unattached
237        */
238       _Safe_iterator&
239       operator=(_Safe_iterator&& __x)
240       {
241         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
242                               || __x._M_current == _Iterator(),
243                               _M_message(__msg_copy_singular)
244                               ._M_iterator(*this, "this")
245                               ._M_iterator(__x, "other"));
246         _M_current = __x._M_current;
247         _M_attach(__x._M_sequence);
248         __x._M_detach();
249         __x._M_current = _Iterator();
250         return *this;
251       }
252 #endif
253
254       /**
255        *  @brief Iterator dereference.
256        *  @pre iterator is dereferenceable
257        */
258       reference
259       operator*() const
260       {
261         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
262                               _M_message(__msg_bad_deref)
263                               ._M_iterator(*this, "this"));
264         return *_M_current;
265       }
266
267       /**
268        *  @brief Iterator dereference.
269        *  @pre iterator is dereferenceable
270        *  @todo Make this correct w.r.t. iterators that return proxies
271        *  @todo Use addressof() instead of & operator
272        */
273       pointer
274       operator->() const
275       {
276         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
277                               _M_message(__msg_bad_deref)
278                               ._M_iterator(*this, "this"));
279         return &*_M_current;
280       }
281
282       // ------ Input iterator requirements ------
283       /**
284        *  @brief Iterator preincrement
285        *  @pre iterator is incrementable
286        */
287       _Safe_iterator&
288       operator++()
289       {
290         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
291                               _M_message(__msg_bad_inc)
292                               ._M_iterator(*this, "this"));
293         ++_M_current;
294         return *this;
295       }
296
297       /**
298        *  @brief Iterator postincrement
299        *  @pre iterator is incrementable
300        */
301       _Safe_iterator
302       operator++(int)
303       {
304         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
305                               _M_message(__msg_bad_inc)
306                               ._M_iterator(*this, "this"));
307         _Safe_iterator __tmp(*this);
308         ++_M_current;
309         return __tmp;
310       }
311
312       // ------ Bidirectional iterator requirements ------
313       /**
314        *  @brief Iterator predecrement
315        *  @pre iterator is decrementable
316        */
317       _Safe_iterator&
318       operator--()
319       {
320         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
321                               _M_message(__msg_bad_dec)
322                               ._M_iterator(*this, "this"));
323         --_M_current;
324         return *this;
325       }
326
327       /**
328        *  @brief Iterator postdecrement
329        *  @pre iterator is decrementable
330        */
331       _Safe_iterator
332       operator--(int)
333       {
334         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
335                               _M_message(__msg_bad_dec)
336                               ._M_iterator(*this, "this"));
337         _Safe_iterator __tmp(*this);
338         --_M_current;
339         return __tmp;
340       }
341
342       // ------ Random access iterator requirements ------
343       reference
344       operator[](const difference_type& __n) const
345       {
346         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
347                               && this->_M_can_advance(__n+1),
348                               _M_message(__msg_iter_subscript_oob)
349                               ._M_iterator(*this)._M_integer(__n));
350
351         return _M_current[__n];
352       }
353
354       _Safe_iterator&
355       operator+=(const difference_type& __n)
356       {
357         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
358                               _M_message(__msg_advance_oob)
359                               ._M_iterator(*this)._M_integer(__n));
360         _M_current += __n;
361         return *this;
362       }
363
364       _Safe_iterator
365       operator+(const difference_type& __n) const
366       {
367         _Safe_iterator __tmp(*this);
368         __tmp += __n;
369         return __tmp;
370       }
371
372       _Safe_iterator&
373       operator-=(const difference_type& __n)
374       {
375         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
376                               _M_message(__msg_retreat_oob)
377                               ._M_iterator(*this)._M_integer(__n));
378         _M_current += -__n;
379         return *this;
380       }
381
382       _Safe_iterator
383       operator-(const difference_type& __n) const
384       {
385         _Safe_iterator __tmp(*this);
386         __tmp -= __n;
387         return __tmp;
388       }
389
390       // ------ Utilities ------
391       /**
392        * @brief Return the underlying iterator
393        */
394       _Iterator
395       base() const { return _M_current; }
396
397       /**
398        * @brief Conversion to underlying non-debug iterator to allow
399        * better interaction with non-debug containers.
400        */
401       operator _Iterator() const { return _M_current; }
402
403       /** Attach iterator to the given sequence. */
404       void
405       _M_attach(_Safe_sequence_base* __seq)
406       {
407         _Safe_iterator_base::_M_attach(__seq, _M_constant());
408       }
409
410       /** Likewise, but not thread-safe. */
411       void
412       _M_attach_single(_Safe_sequence_base* __seq)
413       {
414         _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
415       }
416
417       /// Is the iterator dereferenceable?
418       bool
419       _M_dereferenceable() const
420       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
421
422       /// Is the iterator before a dereferenceable one?
423       bool
424       _M_before_dereferenceable() const
425       {
426         if (this->_M_incrementable())
427         {
428           _Iterator __base = base();
429           return ++__base != _M_get_sequence()->_M_base().end();
430         }
431         return false;
432       }
433
434       /// Is the iterator incrementable?
435       bool
436       _M_incrementable() const
437       { return !this->_M_singular() && !_M_is_end(); }
438
439       // Is the iterator decrementable?
440       bool
441       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
442
443       // Can we advance the iterator @p __n steps (@p __n may be negative)
444       bool
445       _M_can_advance(const difference_type& __n) const;
446
447       // Is the iterator range [*this, __rhs) valid?
448       template<typename _Other>
449         bool
450         _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
451
452       // The sequence this iterator references.
453       const _Sequence*
454       _M_get_sequence() const
455       { return static_cast<const _Sequence*>(_M_sequence); }
456
457       /// Is this iterator equal to the sequence's begin() iterator?
458       bool _M_is_begin() const
459       { return base() == _M_get_sequence()->_M_base().begin(); }
460
461       /// Is this iterator equal to the sequence's end() iterator?
462       bool _M_is_end() const
463       { return base() == _M_get_sequence()->_M_base().end(); }
464
465       /// Is this iterator equal to the sequence's before_begin() iterator if
466       /// any?
467       bool _M_is_before_begin() const
468       {
469         return _BeforeBeginHelper<_Sequence>::_S_Is(base(), _M_get_sequence());
470       }
471
472       /// Is this iterator equal to the sequence's before_begin() iterator if
473       /// any or begin() otherwise?
474       bool _M_is_beginnest() const
475       {
476         return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(base(),
477                                                           _M_get_sequence());
478       }
479     };
480
481   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
482     inline bool
483     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
484                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
485     {
486       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
487                             _M_message(__msg_iter_compare_bad)
488                             ._M_iterator(__lhs, "lhs")
489                             ._M_iterator(__rhs, "rhs"));
490       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
491                             _M_message(__msg_compare_different)
492                             ._M_iterator(__lhs, "lhs")
493                             ._M_iterator(__rhs, "rhs"));
494       return __lhs.base() == __rhs.base();
495     }
496
497   template<typename _Iterator, typename _Sequence>
498     inline bool
499     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
500                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
501     {
502       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
503                             _M_message(__msg_iter_compare_bad)
504                             ._M_iterator(__lhs, "lhs")
505                             ._M_iterator(__rhs, "rhs"));
506       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
507                             _M_message(__msg_compare_different)
508                             ._M_iterator(__lhs, "lhs")
509                             ._M_iterator(__rhs, "rhs"));
510       return __lhs.base() == __rhs.base();
511     }
512
513   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
514     inline bool
515     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
516                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
517     {
518       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
519                             _M_message(__msg_iter_compare_bad)
520                             ._M_iterator(__lhs, "lhs")
521                             ._M_iterator(__rhs, "rhs"));
522       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
523                             _M_message(__msg_compare_different)
524                             ._M_iterator(__lhs, "lhs")
525                             ._M_iterator(__rhs, "rhs"));
526       return __lhs.base() != __rhs.base();
527     }
528
529   template<typename _Iterator, typename _Sequence>
530     inline bool
531     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
532                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
533     {
534       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
535                             _M_message(__msg_iter_compare_bad)
536                             ._M_iterator(__lhs, "lhs")
537                             ._M_iterator(__rhs, "rhs"));
538       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
539                             _M_message(__msg_compare_different)
540                             ._M_iterator(__lhs, "lhs")
541                             ._M_iterator(__rhs, "rhs"));
542       return __lhs.base() != __rhs.base();
543     }
544
545   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
546     inline bool
547     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
548               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
549     {
550       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
551                             _M_message(__msg_iter_order_bad)
552                             ._M_iterator(__lhs, "lhs")
553                             ._M_iterator(__rhs, "rhs"));
554       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
555                             _M_message(__msg_order_different)
556                             ._M_iterator(__lhs, "lhs")
557                             ._M_iterator(__rhs, "rhs"));
558       return __lhs.base() < __rhs.base();
559     }
560
561   template<typename _Iterator, typename _Sequence>
562     inline bool
563     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
564               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
565     {
566       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
567                             _M_message(__msg_iter_order_bad)
568                             ._M_iterator(__lhs, "lhs")
569                             ._M_iterator(__rhs, "rhs"));
570       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
571                             _M_message(__msg_order_different)
572                             ._M_iterator(__lhs, "lhs")
573                             ._M_iterator(__rhs, "rhs"));
574       return __lhs.base() < __rhs.base();
575     }
576
577   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
578     inline bool
579     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
580                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
581     {
582       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
583                             _M_message(__msg_iter_order_bad)
584                             ._M_iterator(__lhs, "lhs")
585                             ._M_iterator(__rhs, "rhs"));
586       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
587                             _M_message(__msg_order_different)
588                             ._M_iterator(__lhs, "lhs")
589                             ._M_iterator(__rhs, "rhs"));
590       return __lhs.base() <= __rhs.base();
591     }
592
593   template<typename _Iterator, typename _Sequence>
594     inline bool
595     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
596                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
597     {
598       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
599                             _M_message(__msg_iter_order_bad)
600                             ._M_iterator(__lhs, "lhs")
601                             ._M_iterator(__rhs, "rhs"));
602       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
603                             _M_message(__msg_order_different)
604                             ._M_iterator(__lhs, "lhs")
605                             ._M_iterator(__rhs, "rhs"));
606       return __lhs.base() <= __rhs.base();
607     }
608
609   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
610     inline bool
611     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
612               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
613     {
614       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
615                             _M_message(__msg_iter_order_bad)
616                             ._M_iterator(__lhs, "lhs")
617                             ._M_iterator(__rhs, "rhs"));
618       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
619                             _M_message(__msg_order_different)
620                             ._M_iterator(__lhs, "lhs")
621                             ._M_iterator(__rhs, "rhs"));
622       return __lhs.base() > __rhs.base();
623     }
624
625   template<typename _Iterator, typename _Sequence>
626     inline bool
627     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
628               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
629     {
630       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
631                             _M_message(__msg_iter_order_bad)
632                             ._M_iterator(__lhs, "lhs")
633                             ._M_iterator(__rhs, "rhs"));
634       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
635                             _M_message(__msg_order_different)
636                             ._M_iterator(__lhs, "lhs")
637                             ._M_iterator(__rhs, "rhs"));
638       return __lhs.base() > __rhs.base();
639     }
640
641   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
642     inline bool
643     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
644                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
645     {
646       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
647                             _M_message(__msg_iter_order_bad)
648                             ._M_iterator(__lhs, "lhs")
649                             ._M_iterator(__rhs, "rhs"));
650       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
651                             _M_message(__msg_order_different)
652                             ._M_iterator(__lhs, "lhs")
653                             ._M_iterator(__rhs, "rhs"));
654       return __lhs.base() >= __rhs.base();
655     }
656
657   template<typename _Iterator, typename _Sequence>
658     inline bool
659     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
660                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
661     {
662       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
663                             _M_message(__msg_iter_order_bad)
664                             ._M_iterator(__lhs, "lhs")
665                             ._M_iterator(__rhs, "rhs"));
666       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
667                             _M_message(__msg_order_different)
668                             ._M_iterator(__lhs, "lhs")
669                             ._M_iterator(__rhs, "rhs"));
670       return __lhs.base() >= __rhs.base();
671     }
672
673   // _GLIBCXX_RESOLVE_LIB_DEFECTS
674   // According to the resolution of DR179 not only the various comparison
675   // operators but also operator- must accept mixed iterator/const_iterator
676   // parameters.
677   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
678     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
679     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
680               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
681     {
682       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
683                             _M_message(__msg_distance_bad)
684                             ._M_iterator(__lhs, "lhs")
685                             ._M_iterator(__rhs, "rhs"));
686       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
687                             _M_message(__msg_distance_different)
688                             ._M_iterator(__lhs, "lhs")
689                             ._M_iterator(__rhs, "rhs"));
690       return __lhs.base() - __rhs.base();
691     }
692
693    template<typename _Iterator, typename _Sequence>
694      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
695      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
696                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
697      {
698        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
699                              _M_message(__msg_distance_bad)
700                              ._M_iterator(__lhs, "lhs")
701                              ._M_iterator(__rhs, "rhs"));
702        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
703                              _M_message(__msg_distance_different)
704                              ._M_iterator(__lhs, "lhs")
705                              ._M_iterator(__rhs, "rhs"));
706        return __lhs.base() - __rhs.base();
707      }
708
709   template<typename _Iterator, typename _Sequence>
710     inline _Safe_iterator<_Iterator, _Sequence>
711     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
712               const _Safe_iterator<_Iterator, _Sequence>& __i)
713     { return __i + __n; }
714
715   // Helper struct to detect random access safe iterators.
716   template<typename _Iterator>
717     struct __is_safe_random_iterator
718     {
719       enum { __value = 0 };
720       typedef std::__false_type __type;
721     };
722
723   template<typename _Iterator, typename _Sequence>
724     struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
725     : std::__are_same<std::random_access_iterator_tag,
726                       typename std::iterator_traits<_Iterator>::
727                       iterator_category>
728     { };
729
730   template<typename _Iterator>
731     struct _Siter_base
732     : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value>
733     { };
734
735   /** Helper function to extract base iterator of random access safe iterator
736       in order to reduce performance impact of debug mode.  Limited to random
737       access iterator because it is the only category for which it is possible
738       to check for correct iterators order in the __valid_range function
739       thanks to the < operator.
740   */
741   template<typename _Iterator>
742     inline typename _Siter_base<_Iterator>::iterator_type
743     __base(_Iterator __it)
744     { return _Siter_base<_Iterator>::_S_base(__it); }
745 } // namespace __gnu_debug
746
747 #include <debug/safe_iterator.tcc>
748
749 #endif