1 // Safe iterator implementation -*- C++ -*-
3 // Copyright (C) 2003-2013 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file debug/safe_iterator.h
26 * This file is a GNU debug extension to the Standard C++ Library.
29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
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>
41 /** Helper struct to deal with sequence offering a before_begin
44 template <typename _Sequence
>
45 struct _BeforeBeginHelper
47 typedef typename
_Sequence::const_iterator _It
;
48 typedef typename
_It::iterator_type _BaseIt
;
51 _S_Is(_BaseIt
, const _Sequence
*)
55 _S_Is_Beginnest(_BaseIt __it
, const _Sequence
* __seq
)
56 { return __it
== __seq
->_M_base().begin(); }
59 /** Iterators that derive from _Safe_iterator_base but that aren't
60 * _Safe_iterators can be determined singular or non-singular via
61 * _Safe_iterator_base.
64 __check_singular_aux(const _Safe_iterator_base
* __x
)
65 { return __x
->_M_singular(); }
67 /** The precision to which we can calculate the distance between
70 enum _Distance_precision
72 __dp_equality
, //< Can compare iterator equality, only
73 __dp_sign
, //< Can determine equality and ordering
74 __dp_exact
//< Can determine distance precisely
77 /** Determine the distance between two iterators with some known
80 template<typename _Iterator1
, typename _Iterator2
>
81 inline std::pair
<typename
std::iterator_traits
<_Iterator1
>::difference_type
,
83 __get_distance(const _Iterator1
& __lhs
, const _Iterator2
& __rhs
,
84 std::random_access_iterator_tag
)
85 { return std::make_pair(__rhs
- __lhs
, __dp_exact
); }
87 template<typename _Iterator1
, typename _Iterator2
>
88 inline std::pair
<typename
std::iterator_traits
<_Iterator1
>::difference_type
,
90 __get_distance(const _Iterator1
& __lhs
, const _Iterator2
& __rhs
,
91 std::forward_iterator_tag
)
92 { return std::make_pair(__lhs
== __rhs
? 0 : 1, __dp_equality
); }
94 template<typename _Iterator1
, typename _Iterator2
>
95 inline std::pair
<typename
std::iterator_traits
<_Iterator1
>::difference_type
,
97 __get_distance(const _Iterator1
& __lhs
, const _Iterator2
& __rhs
)
99 typedef typename
std::iterator_traits
<_Iterator1
>::iterator_category
101 return __get_distance(__lhs
, __rhs
, _Category());
104 /** \brief Safe iterator wrapper.
106 * The class template %_Safe_iterator is a wrapper around an
107 * iterator that tracks the iterator's movement among sequences and
108 * checks that operations performed on the "safe" iterator are
109 * legal. In additional to the basic iterator operations (which are
110 * validated, and then passed to the underlying iterator),
111 * %_Safe_iterator has member functions for iterator invalidation,
112 * attaching/detaching the iterator from sequences, and querying
113 * the iterator's state.
115 template<typename _Iterator
, typename _Sequence
>
116 class _Safe_iterator
: public _Safe_iterator_base
118 typedef _Safe_iterator _Self
;
120 /// The underlying iterator
121 _Iterator _M_current
;
123 /// Determine if this is a constant iterator.
127 typedef typename
_Sequence::const_iterator const_iterator
;
128 return std::__are_same
<const_iterator
, _Safe_iterator
>::__value
;
131 typedef std::iterator_traits
<_Iterator
> _Traits
;
134 typedef _Iterator iterator_type
;
135 typedef typename
_Traits::iterator_category iterator_category
;
136 typedef typename
_Traits::value_type value_type
;
137 typedef typename
_Traits::difference_type difference_type
;
138 typedef typename
_Traits::reference reference
;
139 typedef typename
_Traits::pointer pointer
;
141 /// @post the iterator is singular and unattached
142 _Safe_iterator() _GLIBCXX_NOEXCEPT
: _M_current() { }
145 * @brief Safe iterator construction from an unsafe iterator and
148 * @pre @p seq is not NULL
149 * @post this is not singular
151 _Safe_iterator(const _Iterator
& __i
, const _Sequence
* __seq
)
153 : _Safe_iterator_base(__seq
, _M_constant()), _M_current(__i
)
155 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
156 _M_message(__msg_init_singular
)
157 ._M_iterator(*this, "this"));
161 * @brief Copy construction.
163 _Safe_iterator(const _Safe_iterator
& __x
) _GLIBCXX_NOEXCEPT
164 : _Safe_iterator_base(__x
, _M_constant()), _M_current(__x
._M_current
)
166 // _GLIBCXX_RESOLVE_LIB_DEFECTS
167 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
168 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
169 || __x
._M_current
== _Iterator(),
170 _M_message(__msg_init_copy_singular
)
171 ._M_iterator(*this, "this")
172 ._M_iterator(__x
, "other"));
175 #if __cplusplus >= 201103L
177 * @brief Move construction.
178 * @post __x is singular and unattached
180 _Safe_iterator(_Safe_iterator
&& __x
) noexcept
: _M_current()
182 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
183 || __x
._M_current
== _Iterator(),
184 _M_message(__msg_init_copy_singular
)
185 ._M_iterator(*this, "this")
186 ._M_iterator(__x
, "other"));
187 std::swap(_M_current
, __x
._M_current
);
188 this->_M_attach(__x
._M_sequence
);
194 * @brief Converting constructor from a mutable iterator to a
197 template<typename _MutableIterator
>
199 const _Safe_iterator
<_MutableIterator
,
200 typename
__gnu_cxx::__enable_if
<(std::__are_same
<_MutableIterator
,
201 typename
_Sequence::iterator::iterator_type
>::__value
),
202 _Sequence
>::__type
>& __x
) _GLIBCXX_NOEXCEPT
203 : _Safe_iterator_base(__x
, _M_constant()), _M_current(__x
.base())
205 // _GLIBCXX_RESOLVE_LIB_DEFECTS
206 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
207 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
208 || __x
.base() == _Iterator(),
209 _M_message(__msg_init_const_singular
)
210 ._M_iterator(*this, "this")
211 ._M_iterator(__x
, "other"));
215 * @brief Copy assignment.
218 operator=(const _Safe_iterator
& __x
) _GLIBCXX_NOEXCEPT
220 // _GLIBCXX_RESOLVE_LIB_DEFECTS
221 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
222 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
223 || __x
._M_current
== _Iterator(),
224 _M_message(__msg_copy_singular
)
225 ._M_iterator(*this, "this")
226 ._M_iterator(__x
, "other"));
227 _M_current
= __x
._M_current
;
228 this->_M_attach(__x
._M_sequence
);
232 #if __cplusplus >= 201103L
234 * @brief Move assignment.
235 * @post __x is singular and unattached
238 operator=(_Safe_iterator
&& __x
) noexcept
240 _GLIBCXX_DEBUG_VERIFY(this != &__x
,
241 _M_message(__msg_self_move_assign
)
242 ._M_iterator(*this, "this"));
243 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
244 || __x
._M_current
== _Iterator(),
245 _M_message(__msg_copy_singular
)
246 ._M_iterator(*this, "this")
247 ._M_iterator(__x
, "other"));
248 _M_current
= __x
._M_current
;
249 _M_attach(__x
._M_sequence
);
251 __x
._M_current
= _Iterator();
257 * @brief Iterator dereference.
258 * @pre iterator is dereferenceable
261 operator*() const _GLIBCXX_NOEXCEPT
263 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
264 _M_message(__msg_bad_deref
)
265 ._M_iterator(*this, "this"));
270 * @brief Iterator dereference.
271 * @pre iterator is dereferenceable
272 * @todo Make this correct w.r.t. iterators that return proxies
275 operator->() const _GLIBCXX_NOEXCEPT
277 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
278 _M_message(__msg_bad_deref
)
279 ._M_iterator(*this, "this"));
280 return std::__addressof(*_M_current
);
283 // ------ Input iterator requirements ------
285 * @brief Iterator preincrement
286 * @pre iterator is incrementable
289 operator++() _GLIBCXX_NOEXCEPT
291 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
292 _M_message(__msg_bad_inc
)
293 ._M_iterator(*this, "this"));
299 * @brief Iterator postincrement
300 * @pre iterator is incrementable
303 operator++(int) _GLIBCXX_NOEXCEPT
305 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
306 _M_message(__msg_bad_inc
)
307 ._M_iterator(*this, "this"));
308 _Safe_iterator
__tmp(*this);
313 // ------ Bidirectional iterator requirements ------
315 * @brief Iterator predecrement
316 * @pre iterator is decrementable
319 operator--() _GLIBCXX_NOEXCEPT
321 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
322 _M_message(__msg_bad_dec
)
323 ._M_iterator(*this, "this"));
329 * @brief Iterator postdecrement
330 * @pre iterator is decrementable
333 operator--(int) _GLIBCXX_NOEXCEPT
335 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
336 _M_message(__msg_bad_dec
)
337 ._M_iterator(*this, "this"));
338 _Safe_iterator
__tmp(*this);
343 // ------ Random access iterator requirements ------
345 operator[](const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
347 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
)
348 && this->_M_can_advance(__n
+1),
349 _M_message(__msg_iter_subscript_oob
)
350 ._M_iterator(*this)._M_integer(__n
));
352 return _M_current
[__n
];
356 operator+=(const difference_type
& __n
) _GLIBCXX_NOEXCEPT
358 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
),
359 _M_message(__msg_advance_oob
)
360 ._M_iterator(*this)._M_integer(__n
));
366 operator+(const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
368 _Safe_iterator
__tmp(*this);
374 operator-=(const difference_type
& __n
) _GLIBCXX_NOEXCEPT
376 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n
),
377 _M_message(__msg_retreat_oob
)
378 ._M_iterator(*this)._M_integer(__n
));
384 operator-(const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
386 _Safe_iterator
__tmp(*this);
391 // ------ Utilities ------
393 * @brief Return the underlying iterator
396 base() const _GLIBCXX_NOEXCEPT
{ return _M_current
; }
399 * @brief Conversion to underlying non-debug iterator to allow
400 * better interaction with non-debug containers.
402 operator _Iterator() const _GLIBCXX_NOEXCEPT
{ return _M_current
; }
404 /** Attach iterator to the given sequence. */
406 _M_attach(_Safe_sequence_base
* __seq
)
408 _Safe_iterator_base::_M_attach(__seq
, _M_constant());
411 /** Likewise, but not thread-safe. */
413 _M_attach_single(_Safe_sequence_base
* __seq
)
415 _Safe_iterator_base::_M_attach_single(__seq
, _M_constant());
418 /// Is the iterator dereferenceable?
420 _M_dereferenceable() const
421 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
423 /// Is the iterator before a dereferenceable one?
425 _M_before_dereferenceable() const
427 if (this->_M_incrementable())
429 _Iterator __base
= base();
430 return ++__base
!= _M_get_sequence()->_M_base().end();
435 /// Is the iterator incrementable?
437 _M_incrementable() const
438 { return !this->_M_singular() && !_M_is_end(); }
440 // Is the iterator decrementable?
442 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
444 // Can we advance the iterator @p __n steps (@p __n may be negative)
446 _M_can_advance(const difference_type
& __n
) const;
448 // Is the iterator range [*this, __rhs) valid?
449 template<typename _Other
>
451 _M_valid_range(const _Safe_iterator
<_Other
, _Sequence
>& __rhs
) const;
453 // The sequence this iterator references.
455 _M_get_sequence() const
456 { return static_cast<const _Sequence
*>(_M_sequence
); }
458 /// Is this iterator equal to the sequence's begin() iterator?
459 bool _M_is_begin() const
460 { return base() == _M_get_sequence()->_M_base().begin(); }
462 /// Is this iterator equal to the sequence's end() iterator?
463 bool _M_is_end() const
464 { return base() == _M_get_sequence()->_M_base().end(); }
466 /// Is this iterator equal to the sequence's before_begin() iterator if
468 bool _M_is_before_begin() const
470 return _BeforeBeginHelper
<_Sequence
>::_S_Is(base(), _M_get_sequence());
473 /// Is this iterator equal to the sequence's before_begin() iterator if
474 /// any or begin() otherwise?
475 bool _M_is_beginnest() const
477 return _BeforeBeginHelper
<_Sequence
>::_S_Is_Beginnest(base(),
482 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
484 operator==(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
485 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
488 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
489 _M_message(__msg_iter_compare_bad
)
490 ._M_iterator(__lhs
, "lhs")
491 ._M_iterator(__rhs
, "rhs"));
492 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
493 _M_message(__msg_compare_different
)
494 ._M_iterator(__lhs
, "lhs")
495 ._M_iterator(__rhs
, "rhs"));
496 return __lhs
.base() == __rhs
.base();
499 template<typename _Iterator
, typename _Sequence
>
501 operator==(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
502 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
505 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
506 _M_message(__msg_iter_compare_bad
)
507 ._M_iterator(__lhs
, "lhs")
508 ._M_iterator(__rhs
, "rhs"));
509 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
510 _M_message(__msg_compare_different
)
511 ._M_iterator(__lhs
, "lhs")
512 ._M_iterator(__rhs
, "rhs"));
513 return __lhs
.base() == __rhs
.base();
516 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
518 operator!=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
519 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
522 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
523 _M_message(__msg_iter_compare_bad
)
524 ._M_iterator(__lhs
, "lhs")
525 ._M_iterator(__rhs
, "rhs"));
526 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
527 _M_message(__msg_compare_different
)
528 ._M_iterator(__lhs
, "lhs")
529 ._M_iterator(__rhs
, "rhs"));
530 return __lhs
.base() != __rhs
.base();
533 template<typename _Iterator
, typename _Sequence
>
535 operator!=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
536 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
539 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
540 _M_message(__msg_iter_compare_bad
)
541 ._M_iterator(__lhs
, "lhs")
542 ._M_iterator(__rhs
, "rhs"));
543 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
544 _M_message(__msg_compare_different
)
545 ._M_iterator(__lhs
, "lhs")
546 ._M_iterator(__rhs
, "rhs"));
547 return __lhs
.base() != __rhs
.base();
550 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
552 operator<(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
553 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
556 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
557 _M_message(__msg_iter_order_bad
)
558 ._M_iterator(__lhs
, "lhs")
559 ._M_iterator(__rhs
, "rhs"));
560 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
561 _M_message(__msg_order_different
)
562 ._M_iterator(__lhs
, "lhs")
563 ._M_iterator(__rhs
, "rhs"));
564 return __lhs
.base() < __rhs
.base();
567 template<typename _Iterator
, typename _Sequence
>
569 operator<(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
570 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
573 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
574 _M_message(__msg_iter_order_bad
)
575 ._M_iterator(__lhs
, "lhs")
576 ._M_iterator(__rhs
, "rhs"));
577 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
578 _M_message(__msg_order_different
)
579 ._M_iterator(__lhs
, "lhs")
580 ._M_iterator(__rhs
, "rhs"));
581 return __lhs
.base() < __rhs
.base();
584 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
586 operator<=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
587 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
590 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
591 _M_message(__msg_iter_order_bad
)
592 ._M_iterator(__lhs
, "lhs")
593 ._M_iterator(__rhs
, "rhs"));
594 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
595 _M_message(__msg_order_different
)
596 ._M_iterator(__lhs
, "lhs")
597 ._M_iterator(__rhs
, "rhs"));
598 return __lhs
.base() <= __rhs
.base();
601 template<typename _Iterator
, typename _Sequence
>
603 operator<=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
604 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
607 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
608 _M_message(__msg_iter_order_bad
)
609 ._M_iterator(__lhs
, "lhs")
610 ._M_iterator(__rhs
, "rhs"));
611 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
612 _M_message(__msg_order_different
)
613 ._M_iterator(__lhs
, "lhs")
614 ._M_iterator(__rhs
, "rhs"));
615 return __lhs
.base() <= __rhs
.base();
618 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
620 operator>(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
621 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
624 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
625 _M_message(__msg_iter_order_bad
)
626 ._M_iterator(__lhs
, "lhs")
627 ._M_iterator(__rhs
, "rhs"));
628 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
629 _M_message(__msg_order_different
)
630 ._M_iterator(__lhs
, "lhs")
631 ._M_iterator(__rhs
, "rhs"));
632 return __lhs
.base() > __rhs
.base();
635 template<typename _Iterator
, typename _Sequence
>
637 operator>(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
638 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
641 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
642 _M_message(__msg_iter_order_bad
)
643 ._M_iterator(__lhs
, "lhs")
644 ._M_iterator(__rhs
, "rhs"));
645 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
646 _M_message(__msg_order_different
)
647 ._M_iterator(__lhs
, "lhs")
648 ._M_iterator(__rhs
, "rhs"));
649 return __lhs
.base() > __rhs
.base();
652 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
654 operator>=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
655 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
658 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
659 _M_message(__msg_iter_order_bad
)
660 ._M_iterator(__lhs
, "lhs")
661 ._M_iterator(__rhs
, "rhs"));
662 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
663 _M_message(__msg_order_different
)
664 ._M_iterator(__lhs
, "lhs")
665 ._M_iterator(__rhs
, "rhs"));
666 return __lhs
.base() >= __rhs
.base();
669 template<typename _Iterator
, typename _Sequence
>
671 operator>=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
672 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
675 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
676 _M_message(__msg_iter_order_bad
)
677 ._M_iterator(__lhs
, "lhs")
678 ._M_iterator(__rhs
, "rhs"));
679 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
680 _M_message(__msg_order_different
)
681 ._M_iterator(__lhs
, "lhs")
682 ._M_iterator(__rhs
, "rhs"));
683 return __lhs
.base() >= __rhs
.base();
686 // _GLIBCXX_RESOLVE_LIB_DEFECTS
687 // According to the resolution of DR179 not only the various comparison
688 // operators but also operator- must accept mixed iterator/const_iterator
690 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
691 inline typename _Safe_iterator
<_IteratorL
, _Sequence
>::difference_type
692 operator-(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
693 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
696 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
697 _M_message(__msg_distance_bad
)
698 ._M_iterator(__lhs
, "lhs")
699 ._M_iterator(__rhs
, "rhs"));
700 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
701 _M_message(__msg_distance_different
)
702 ._M_iterator(__lhs
, "lhs")
703 ._M_iterator(__rhs
, "rhs"));
704 return __lhs
.base() - __rhs
.base();
707 template<typename _Iterator
, typename _Sequence
>
708 inline typename _Safe_iterator
<_Iterator
, _Sequence
>::difference_type
709 operator-(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
710 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
713 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
714 _M_message(__msg_distance_bad
)
715 ._M_iterator(__lhs
, "lhs")
716 ._M_iterator(__rhs
, "rhs"));
717 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
718 _M_message(__msg_distance_different
)
719 ._M_iterator(__lhs
, "lhs")
720 ._M_iterator(__rhs
, "rhs"));
721 return __lhs
.base() - __rhs
.base();
724 template<typename _Iterator
, typename _Sequence
>
725 inline _Safe_iterator
<_Iterator
, _Sequence
>
726 operator+(typename _Safe_iterator
<_Iterator
,_Sequence
>::difference_type __n
,
727 const _Safe_iterator
<_Iterator
, _Sequence
>& __i
) _GLIBCXX_NOEXCEPT
728 { return __i
+ __n
; }
729 } // namespace __gnu_debug
731 #include <debug/safe_iterator.tcc>