]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.9/include/debug/safe_iterator.h
update
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.9 / include / debug / safe_iterator.h
1 // Safe iterator implementation  -*- C++ -*-
2
3 // Copyright (C) 2003-2014 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file debug/safe_iterator.h
26  *  This file is a GNU debug extension to the Standard C++ Library.
27  */
28
29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
31
32 #include <debug/debug.h>
33 #include <debug/macros.h>
34 #include <debug/functions.h>
35 #include <debug/safe_base.h>
36 #include <bits/stl_pair.h>
37 #include <ext/type_traits.h>
38
39 namespace __gnu_debug
40 {
41   /** Helper struct to deal with sequence offering a before_begin
42    *  iterator.
43    **/
44   template <typename _Sequence>
45     struct _BeforeBeginHelper
46     {
47       template<typename _Iterator>
48         static bool
49         _S_Is(const _Safe_iterator<_Iterator, _Sequence>&)
50         { return false; }
51
52       template<typename _Iterator>
53         static bool
54         _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it)
55         { return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
56     };
57
58   /** Iterators that derive from _Safe_iterator_base can be determined singular
59    *  or non-singular.
60    **/
61   inline bool 
62   __check_singular_aux(const _Safe_iterator_base* __x)
63   { return __x->_M_singular(); }
64
65   /** The precision to which we can calculate the distance between
66    *  two iterators.
67    */
68   enum _Distance_precision
69     {
70       __dp_equality, //< Can compare iterator equality, only
71       __dp_sign,     //< Can determine equality and ordering
72       __dp_exact     //< Can determine distance precisely
73     };
74
75   /** Determine the distance between two iterators with some known
76    *    precision.
77   */
78   template<typename _Iterator>
79     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
80                      _Distance_precision>
81     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs,
82                    std::random_access_iterator_tag)
83     { return std::make_pair(__rhs - __lhs, __dp_exact); }
84
85   template<typename _Iterator>
86     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
87                      _Distance_precision>
88     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs,
89                    std::forward_iterator_tag)
90     { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
91
92   template<typename _Iterator>
93     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
94                      _Distance_precision>
95     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs)
96     {
97       typedef typename std::iterator_traits<_Iterator>::iterator_category
98           _Category;
99       return __get_distance(__lhs, __rhs, _Category());
100     }
101
102   /** \brief Safe iterator wrapper.
103    *
104    *  The class template %_Safe_iterator is a wrapper around an
105    *  iterator that tracks the iterator's movement among sequences and
106    *  checks that operations performed on the "safe" iterator are
107    *  legal. In additional to the basic iterator operations (which are
108    *  validated, and then passed to the underlying iterator),
109    *  %_Safe_iterator has member functions for iterator invalidation,
110    *  attaching/detaching the iterator from sequences, and querying
111    *  the iterator's state.
112    */
113   template<typename _Iterator, typename _Sequence>
114     class _Safe_iterator : public _Safe_iterator_base
115     {
116       typedef _Safe_iterator _Self;
117       typedef typename _Sequence::const_iterator _Const_iterator;
118
119       /// The underlying iterator
120       _Iterator _M_current;
121
122       /// Determine if this is a constant iterator.
123       bool
124       _M_constant() const
125       { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; }
126
127       typedef std::iterator_traits<_Iterator> _Traits;
128
129     public:
130       typedef _Iterator                           iterator_type;
131       typedef typename _Traits::iterator_category iterator_category;
132       typedef typename _Traits::value_type        value_type;
133       typedef typename _Traits::difference_type   difference_type;
134       typedef typename _Traits::reference         reference;
135       typedef typename _Traits::pointer           pointer;
136
137       /// @post the iterator is singular and unattached
138       _Safe_iterator() _GLIBCXX_NOEXCEPT : _M_current() { }
139
140       /**
141        * @brief Safe iterator construction from an unsafe iterator and
142        * its sequence.
143        *
144        * @pre @p seq is not NULL
145        * @post this is not singular
146        */
147       _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
148       _GLIBCXX_NOEXCEPT
149       : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
150       {
151         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
152                               _M_message(__msg_init_singular)
153                               ._M_iterator(*this, "this"));
154       }
155
156       /**
157        * @brief Copy construction.
158        */
159       _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
160       : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
161       {
162         // _GLIBCXX_RESOLVE_LIB_DEFECTS
163         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
164         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
165                               || __x._M_current == _Iterator(),
166                               _M_message(__msg_init_copy_singular)
167                               ._M_iterator(*this, "this")
168                               ._M_iterator(__x, "other"));
169       }
170
171 #if __cplusplus >= 201103L
172       /**
173        * @brief Move construction.
174        * @post __x is singular and unattached
175        */
176       _Safe_iterator(_Safe_iterator&& __x) noexcept : _M_current()
177       {
178         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
179                               || __x._M_current == _Iterator(),
180                               _M_message(__msg_init_copy_singular)
181                               ._M_iterator(*this, "this")
182                               ._M_iterator(__x, "other"));
183         std::swap(_M_current, __x._M_current);
184         this->_M_attach(__x._M_sequence);
185         __x._M_detach();
186       }
187 #endif
188
189       /**
190        *  @brief Converting constructor from a mutable iterator to a
191        *  constant iterator.
192       */
193       template<typename _MutableIterator>
194         _Safe_iterator(
195           const _Safe_iterator<_MutableIterator,
196           typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
197                       typename _Sequence::iterator::iterator_type>::__value),
198                    _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
199         : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
200         {
201           // _GLIBCXX_RESOLVE_LIB_DEFECTS
202           // DR 408. Is vector<reverse_iterator<char*> > forbidden?
203           _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
204                                 || __x.base() == _Iterator(),
205                                 _M_message(__msg_init_const_singular)
206                                 ._M_iterator(*this, "this")
207                                 ._M_iterator(__x, "other"));
208         }
209
210       /**
211        * @brief Copy assignment.
212        */
213       _Safe_iterator&
214       operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
215       {
216         // _GLIBCXX_RESOLVE_LIB_DEFECTS
217         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
218         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
219                               || __x._M_current == _Iterator(),
220                               _M_message(__msg_copy_singular)
221                               ._M_iterator(*this, "this")
222                               ._M_iterator(__x, "other"));
223         _M_current = __x._M_current;
224         this->_M_attach(__x._M_sequence);
225         return *this;
226       }
227
228 #if __cplusplus >= 201103L
229       /**
230        * @brief Move assignment.
231        * @post __x is singular and unattached
232        */
233       _Safe_iterator&
234       operator=(_Safe_iterator&& __x) noexcept
235       {
236         _GLIBCXX_DEBUG_VERIFY(this != &__x,
237                               _M_message(__msg_self_move_assign)
238                               ._M_iterator(*this, "this"));
239         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
240                               || __x._M_current == _Iterator(),
241                               _M_message(__msg_copy_singular)
242                               ._M_iterator(*this, "this")
243                               ._M_iterator(__x, "other"));
244         _M_current = __x._M_current;
245         _M_attach(__x._M_sequence);
246         __x._M_detach();
247         __x._M_current = _Iterator();
248         return *this;
249       }
250 #endif
251
252       /**
253        *  @brief Iterator dereference.
254        *  @pre iterator is dereferenceable
255        */
256       reference
257       operator*() const _GLIBCXX_NOEXCEPT
258       {
259         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
260                               _M_message(__msg_bad_deref)
261                               ._M_iterator(*this, "this"));
262         return *_M_current;
263       }
264
265       /**
266        *  @brief Iterator dereference.
267        *  @pre iterator is dereferenceable
268        *  @todo Make this correct w.r.t. iterators that return proxies
269        */
270       pointer
271       operator->() const _GLIBCXX_NOEXCEPT
272       {
273         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
274                               _M_message(__msg_bad_deref)
275                               ._M_iterator(*this, "this"));
276         return std::__addressof(*_M_current);
277       }
278
279       // ------ Input iterator requirements ------
280       /**
281        *  @brief Iterator preincrement
282        *  @pre iterator is incrementable
283        */
284       _Safe_iterator&
285       operator++() _GLIBCXX_NOEXCEPT
286       {
287         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
288                               _M_message(__msg_bad_inc)
289                               ._M_iterator(*this, "this"));
290         ++_M_current;
291         return *this;
292       }
293
294       /**
295        *  @brief Iterator postincrement
296        *  @pre iterator is incrementable
297        */
298       _Safe_iterator
299       operator++(int) _GLIBCXX_NOEXCEPT
300       {
301         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
302                               _M_message(__msg_bad_inc)
303                               ._M_iterator(*this, "this"));
304         _Safe_iterator __tmp(*this);
305         ++_M_current;
306         return __tmp;
307       }
308
309       // ------ Bidirectional iterator requirements ------
310       /**
311        *  @brief Iterator predecrement
312        *  @pre iterator is decrementable
313        */
314       _Safe_iterator&
315       operator--() _GLIBCXX_NOEXCEPT
316       {
317         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
318                               _M_message(__msg_bad_dec)
319                               ._M_iterator(*this, "this"));
320         --_M_current;
321         return *this;
322       }
323
324       /**
325        *  @brief Iterator postdecrement
326        *  @pre iterator is decrementable
327        */
328       _Safe_iterator
329       operator--(int) _GLIBCXX_NOEXCEPT
330       {
331         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
332                               _M_message(__msg_bad_dec)
333                               ._M_iterator(*this, "this"));
334         _Safe_iterator __tmp(*this);
335         --_M_current;
336         return __tmp;
337       }
338
339       // ------ Random access iterator requirements ------
340       reference
341       operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
342       {
343         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
344                               && this->_M_can_advance(__n+1),
345                               _M_message(__msg_iter_subscript_oob)
346                               ._M_iterator(*this)._M_integer(__n));
347
348         return _M_current[__n];
349       }
350
351       _Safe_iterator&
352       operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
353       {
354         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
355                               _M_message(__msg_advance_oob)
356                               ._M_iterator(*this)._M_integer(__n));
357         _M_current += __n;
358         return *this;
359       }
360
361       _Safe_iterator
362       operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
363       {
364         _Safe_iterator __tmp(*this);
365         __tmp += __n;
366         return __tmp;
367       }
368
369       _Safe_iterator&
370       operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
371       {
372         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
373                               _M_message(__msg_retreat_oob)
374                               ._M_iterator(*this)._M_integer(__n));
375         _M_current += -__n;
376         return *this;
377       }
378
379       _Safe_iterator
380       operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
381       {
382         _Safe_iterator __tmp(*this);
383         __tmp -= __n;
384         return __tmp;
385       }
386
387       // ------ Utilities ------
388       /**
389        * @brief Return the underlying iterator
390        */
391       _Iterator
392       base() const _GLIBCXX_NOEXCEPT { return _M_current; }
393
394       /**
395        * @brief Conversion to underlying non-debug iterator to allow
396        * better interaction with non-debug containers.
397        */
398       operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; }
399
400       /** Attach iterator to the given sequence. */
401       void
402       _M_attach(_Safe_sequence_base* __seq)
403       {
404         _Safe_iterator_base::_M_attach(__seq, _M_constant());
405       }
406
407       /** Likewise, but not thread-safe. */
408       void
409       _M_attach_single(_Safe_sequence_base* __seq)
410       {
411         _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
412       }
413
414       /// Is the iterator dereferenceable?
415       bool
416       _M_dereferenceable() const
417       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
418
419       /// Is the iterator before a dereferenceable one?
420       bool
421       _M_before_dereferenceable() const
422       {
423         if (this->_M_incrementable())
424         {
425           _Iterator __base = base();
426           return ++__base != _M_get_sequence()->_M_base().end();
427         }
428         return false;
429       }
430
431       /// Is the iterator incrementable?
432       bool
433       _M_incrementable() const
434       { return !this->_M_singular() && !_M_is_end(); }
435
436       // Is the iterator decrementable?
437       bool
438       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
439
440       // Can we advance the iterator @p __n steps (@p __n may be negative)
441       bool
442       _M_can_advance(const difference_type& __n) const;
443
444       // Is the iterator range [*this, __rhs) valid?
445       bool
446       _M_valid_range(const _Safe_iterator& __rhs) const;
447
448       // The sequence this iterator references.
449       typename
450       __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
451                                                     _Safe_iterator>::__value,
452                                     const _Sequence*,
453                                     _Sequence*>::__type
454       _M_get_sequence() const
455       { return static_cast<_Sequence*>(_M_sequence); }
456
457       /// Is this iterator equal to the sequence's begin() iterator?
458       bool
459       _M_is_begin() const
460       { return base() == _M_get_sequence()->_M_base().begin(); }
461
462       /// Is this iterator equal to the sequence's end() iterator?
463       bool
464       _M_is_end() const
465       { return base() == _M_get_sequence()->_M_base().end(); }
466
467       /// Is this iterator equal to the sequence's before_begin() iterator if
468       /// any?
469       bool
470       _M_is_before_begin() const
471       { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
472
473       /// Is this iterator equal to the sequence's before_begin() iterator if
474       /// any or begin() otherwise?
475       bool
476       _M_is_beginnest() const
477       { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
478     };
479
480   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
481     inline bool
482     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
483                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
484     _GLIBCXX_NOEXCEPT
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     _GLIBCXX_NOEXCEPT
502     {
503       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
504                             _M_message(__msg_iter_compare_bad)
505                             ._M_iterator(__lhs, "lhs")
506                             ._M_iterator(__rhs, "rhs"));
507       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
508                             _M_message(__msg_compare_different)
509                             ._M_iterator(__lhs, "lhs")
510                             ._M_iterator(__rhs, "rhs"));
511       return __lhs.base() == __rhs.base();
512     }
513
514   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
515     inline bool
516     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
517                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
518     _GLIBCXX_NOEXCEPT
519     {
520       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
521                             _M_message(__msg_iter_compare_bad)
522                             ._M_iterator(__lhs, "lhs")
523                             ._M_iterator(__rhs, "rhs"));
524       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
525                             _M_message(__msg_compare_different)
526                             ._M_iterator(__lhs, "lhs")
527                             ._M_iterator(__rhs, "rhs"));
528       return __lhs.base() != __rhs.base();
529     }
530
531   template<typename _Iterator, typename _Sequence>
532     inline bool
533     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
534                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
535     _GLIBCXX_NOEXCEPT
536     {
537       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
538                             _M_message(__msg_iter_compare_bad)
539                             ._M_iterator(__lhs, "lhs")
540                             ._M_iterator(__rhs, "rhs"));
541       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
542                             _M_message(__msg_compare_different)
543                             ._M_iterator(__lhs, "lhs")
544                             ._M_iterator(__rhs, "rhs"));
545       return __lhs.base() != __rhs.base();
546     }
547
548   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
549     inline bool
550     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
551               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
552     _GLIBCXX_NOEXCEPT
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     _GLIBCXX_NOEXCEPT
570     {
571       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
572                             _M_message(__msg_iter_order_bad)
573                             ._M_iterator(__lhs, "lhs")
574                             ._M_iterator(__rhs, "rhs"));
575       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
576                             _M_message(__msg_order_different)
577                             ._M_iterator(__lhs, "lhs")
578                             ._M_iterator(__rhs, "rhs"));
579       return __lhs.base() < __rhs.base();
580     }
581
582   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
583     inline bool
584     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
585                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
586     _GLIBCXX_NOEXCEPT
587     {
588       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
589                             _M_message(__msg_iter_order_bad)
590                             ._M_iterator(__lhs, "lhs")
591                             ._M_iterator(__rhs, "rhs"));
592       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
593                             _M_message(__msg_order_different)
594                             ._M_iterator(__lhs, "lhs")
595                             ._M_iterator(__rhs, "rhs"));
596       return __lhs.base() <= __rhs.base();
597     }
598
599   template<typename _Iterator, typename _Sequence>
600     inline bool
601     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
602                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
603     _GLIBCXX_NOEXCEPT
604     {
605       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
606                             _M_message(__msg_iter_order_bad)
607                             ._M_iterator(__lhs, "lhs")
608                             ._M_iterator(__rhs, "rhs"));
609       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
610                             _M_message(__msg_order_different)
611                             ._M_iterator(__lhs, "lhs")
612                             ._M_iterator(__rhs, "rhs"));
613       return __lhs.base() <= __rhs.base();
614     }
615
616   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
617     inline bool
618     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
619               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
620     _GLIBCXX_NOEXCEPT
621     {
622       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
623                             _M_message(__msg_iter_order_bad)
624                             ._M_iterator(__lhs, "lhs")
625                             ._M_iterator(__rhs, "rhs"));
626       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
627                             _M_message(__msg_order_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 bool
635     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
636               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
637     _GLIBCXX_NOEXCEPT
638     {
639       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
640                             _M_message(__msg_iter_order_bad)
641                             ._M_iterator(__lhs, "lhs")
642                             ._M_iterator(__rhs, "rhs"));
643       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
644                             _M_message(__msg_order_different)
645                             ._M_iterator(__lhs, "lhs")
646                             ._M_iterator(__rhs, "rhs"));
647       return __lhs.base() > __rhs.base();
648     }
649
650   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
651     inline bool
652     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
653                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
654     _GLIBCXX_NOEXCEPT
655     {
656       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
657                             _M_message(__msg_iter_order_bad)
658                             ._M_iterator(__lhs, "lhs")
659                             ._M_iterator(__rhs, "rhs"));
660       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
661                             _M_message(__msg_order_different)
662                             ._M_iterator(__lhs, "lhs")
663                             ._M_iterator(__rhs, "rhs"));
664       return __lhs.base() >= __rhs.base();
665     }
666
667   template<typename _Iterator, typename _Sequence>
668     inline bool
669     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
670                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
671     _GLIBCXX_NOEXCEPT
672     {
673       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
674                             _M_message(__msg_iter_order_bad)
675                             ._M_iterator(__lhs, "lhs")
676                             ._M_iterator(__rhs, "rhs"));
677       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
678                             _M_message(__msg_order_different)
679                             ._M_iterator(__lhs, "lhs")
680                             ._M_iterator(__rhs, "rhs"));
681       return __lhs.base() >= __rhs.base();
682     }
683
684   // _GLIBCXX_RESOLVE_LIB_DEFECTS
685   // According to the resolution of DR179 not only the various comparison
686   // operators but also operator- must accept mixed iterator/const_iterator
687   // parameters.
688   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
689     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
690     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
691               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
692     _GLIBCXX_NOEXCEPT
693     {
694       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
695                             _M_message(__msg_distance_bad)
696                             ._M_iterator(__lhs, "lhs")
697                             ._M_iterator(__rhs, "rhs"));
698       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
699                             _M_message(__msg_distance_different)
700                             ._M_iterator(__lhs, "lhs")
701                             ._M_iterator(__rhs, "rhs"));
702       return __lhs.base() - __rhs.base();
703     }
704
705    template<typename _Iterator, typename _Sequence>
706      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
707      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
708                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
709     _GLIBCXX_NOEXCEPT
710      {
711        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
712                              _M_message(__msg_distance_bad)
713                              ._M_iterator(__lhs, "lhs")
714                              ._M_iterator(__rhs, "rhs"));
715        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
716                              _M_message(__msg_distance_different)
717                              ._M_iterator(__lhs, "lhs")
718                              ._M_iterator(__rhs, "rhs"));
719        return __lhs.base() - __rhs.base();
720      }
721
722   template<typename _Iterator, typename _Sequence>
723     inline _Safe_iterator<_Iterator, _Sequence>
724     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
725               const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
726     { return __i + __n; }
727 } // namespace __gnu_debug
728
729 #include <debug/safe_iterator.tcc>
730
731 #endif