1 // Safe iterator implementation -*- C++ -*-
3 // Copyright (C) 2003-2015 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 template<typename _Iterator
>
49 _S_Is(const _Safe_iterator
<_Iterator
, _Sequence
>&)
52 template<typename _Iterator
>
54 _S_Is_Beginnest(const _Safe_iterator
<_Iterator
, _Sequence
>& __it
)
55 { return __it
.base() == __it
._M_get_sequence()->_M_base().begin(); }
58 /** Iterators that derive from _Safe_iterator_base can be determined singular
62 __check_singular_aux(const _Safe_iterator_base
* __x
)
63 { return __x
->_M_singular(); }
65 /** The precision to which we can calculate the distance between
68 enum _Distance_precision
70 __dp_equality
, //< Can compare iterator equality, only
71 __dp_sign
, //< Can determine equality and ordering
72 __dp_exact
//< Can determine distance precisely
75 /** Determine the distance between two iterators with some known
78 template<typename _Iterator
>
79 inline std::pair
<typename
std::iterator_traits
<_Iterator
>::difference_type
,
81 __get_distance(const _Iterator
& __lhs
, const _Iterator
& __rhs
,
82 std::random_access_iterator_tag
)
83 { return std::make_pair(__rhs
- __lhs
, __dp_exact
); }
85 template<typename _Iterator
>
86 inline std::pair
<typename
std::iterator_traits
<_Iterator
>::difference_type
,
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
); }
92 template<typename _Iterator
>
93 inline std::pair
<typename
std::iterator_traits
<_Iterator
>::difference_type
,
95 __get_distance(const _Iterator
& __lhs
, const _Iterator
& __rhs
)
97 typedef typename
std::iterator_traits
<_Iterator
>::iterator_category
99 return __get_distance(__lhs
, __rhs
, _Category());
102 /** \brief Safe iterator wrapper.
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.
113 * Note that _Iterator must be the first base class so that it gets
114 * initialized before the iterator is being attached to the container's list
115 * of iterators and it is being detached before _Iterator get
116 * destroyed. Otherwise it would result in a data race.
118 template<typename _Iterator
, typename _Sequence
>
121 public _Safe_iterator_base
123 typedef _Iterator _Iter_base
;
124 typedef _Safe_iterator_base _Safe_base
;
125 typedef typename
_Sequence::const_iterator _Const_iterator
;
127 /// Determine if this is a constant iterator.
130 { return std::__are_same
<_Const_iterator
, _Safe_iterator
>::__value
; }
132 typedef std::iterator_traits
<_Iterator
> _Traits
;
134 struct _Attach_single
137 _Safe_iterator(const _Iterator
& __i
, _Safe_sequence_base
* __seq
,
141 { _M_attach_single(__seq
); }
144 typedef _Iterator iterator_type
;
145 typedef typename
_Traits::iterator_category iterator_category
;
146 typedef typename
_Traits::value_type value_type
;
147 typedef typename
_Traits::difference_type difference_type
;
148 typedef typename
_Traits::reference reference
;
149 typedef typename
_Traits::pointer pointer
;
151 /// @post the iterator is singular and unattached
152 _Safe_iterator() _GLIBCXX_NOEXCEPT
: _Iter_base() { }
155 * @brief Safe iterator construction from an unsafe iterator and
158 * @pre @p seq is not NULL
159 * @post this is not singular
161 _Safe_iterator(const _Iterator
& __i
, const _Safe_sequence_base
* __seq
)
163 : _Iter_base(__i
), _Safe_base(__seq
, _M_constant())
165 _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
166 _M_message(__msg_init_singular
)
167 ._M_iterator(*this, "this"));
171 * @brief Copy construction.
173 _Safe_iterator(const _Safe_iterator
& __x
) _GLIBCXX_NOEXCEPT
174 : _Iter_base(__x
.base())
176 // _GLIBCXX_RESOLVE_LIB_DEFECTS
177 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
178 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
179 || __x
.base() == _Iterator(),
180 _M_message(__msg_init_copy_singular
)
181 ._M_iterator(*this, "this")
182 ._M_iterator(__x
, "other"));
183 _M_attach(__x
._M_sequence
);
186 #if __cplusplus >= 201103L
188 * @brief Move construction.
189 * @post __x is singular and unattached
191 _Safe_iterator(_Safe_iterator
&& __x
) noexcept
194 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
195 || __x
.base() == _Iterator(),
196 _M_message(__msg_init_copy_singular
)
197 ._M_iterator(*this, "this")
198 ._M_iterator(__x
, "other"));
199 _Safe_sequence_base
* __seq
= __x
._M_sequence
;
201 std::swap(base(), __x
.base());
207 * @brief Converting constructor from a mutable iterator to a
210 template<typename _MutableIterator
>
212 const _Safe_iterator
<_MutableIterator
,
213 typename
__gnu_cxx::__enable_if
<(std::__are_same
<_MutableIterator
,
214 typename
_Sequence::iterator::iterator_type
>::__value
),
215 _Sequence
>::__type
>& __x
) _GLIBCXX_NOEXCEPT
216 : _Iter_base(__x
.base())
218 // _GLIBCXX_RESOLVE_LIB_DEFECTS
219 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
220 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
221 || __x
.base() == _Iterator(),
222 _M_message(__msg_init_const_singular
)
223 ._M_iterator(*this, "this")
224 ._M_iterator(__x
, "other"));
225 _M_attach(__x
._M_sequence
);
229 * @brief Copy assignment.
232 operator=(const _Safe_iterator
& __x
) _GLIBCXX_NOEXCEPT
234 // _GLIBCXX_RESOLVE_LIB_DEFECTS
235 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
236 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
237 || __x
.base() == _Iterator(),
238 _M_message(__msg_copy_singular
)
239 ._M_iterator(*this, "this")
240 ._M_iterator(__x
, "other"));
242 if (this->_M_sequence
&& this->_M_sequence
== __x
._M_sequence
)
244 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
246 _M_version
= __x
._M_sequence
->_M_version
;
252 _M_attach(__x
._M_sequence
);
258 #if __cplusplus >= 201103L
260 * @brief Move assignment.
261 * @post __x is singular and unattached
264 operator=(_Safe_iterator
&& __x
) noexcept
266 _GLIBCXX_DEBUG_VERIFY(this != &__x
,
267 _M_message(__msg_self_move_assign
)
268 ._M_iterator(*this, "this"));
269 _GLIBCXX_DEBUG_VERIFY(!__x
._M_singular()
270 || __x
.base() == _Iterator(),
271 _M_message(__msg_copy_singular
)
272 ._M_iterator(*this, "this")
273 ._M_iterator(__x
, "other"));
275 if (this->_M_sequence
&& this->_M_sequence
== __x
._M_sequence
)
277 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
279 _M_version
= __x
._M_sequence
->_M_version
;
285 _M_attach(__x
._M_sequence
);
289 __x
.base() = _Iterator();
295 * @brief Iterator dereference.
296 * @pre iterator is dereferenceable
299 operator*() const _GLIBCXX_NOEXCEPT
301 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
302 _M_message(__msg_bad_deref
)
303 ._M_iterator(*this, "this"));
308 * @brief Iterator dereference.
309 * @pre iterator is dereferenceable
310 * @todo Make this correct w.r.t. iterators that return proxies
313 operator->() const _GLIBCXX_NOEXCEPT
315 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
316 _M_message(__msg_bad_deref
)
317 ._M_iterator(*this, "this"));
318 return std::__addressof(*base());
321 // ------ Input iterator requirements ------
323 * @brief Iterator preincrement
324 * @pre iterator is incrementable
327 operator++() _GLIBCXX_NOEXCEPT
329 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
330 _M_message(__msg_bad_inc
)
331 ._M_iterator(*this, "this"));
332 __gnu_cxx::__scoped_lock(this->_M_get_mutex());
338 * @brief Iterator postincrement
339 * @pre iterator is incrementable
342 operator++(int) _GLIBCXX_NOEXCEPT
344 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
345 _M_message(__msg_bad_inc
)
346 ._M_iterator(*this, "this"));
347 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
348 return _Safe_iterator(base()++, this->_M_sequence
, _Attach_single());
351 // ------ Bidirectional iterator requirements ------
353 * @brief Iterator predecrement
354 * @pre iterator is decrementable
357 operator--() _GLIBCXX_NOEXCEPT
359 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
360 _M_message(__msg_bad_dec
)
361 ._M_iterator(*this, "this"));
362 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
368 * @brief Iterator postdecrement
369 * @pre iterator is decrementable
372 operator--(int) _GLIBCXX_NOEXCEPT
374 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
375 _M_message(__msg_bad_dec
)
376 ._M_iterator(*this, "this"));
377 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
378 return _Safe_iterator(base()--, this->_M_sequence
, _Attach_single());
381 // ------ Random access iterator requirements ------
383 operator[](const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
385 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
)
386 && this->_M_can_advance(__n
+1),
387 _M_message(__msg_iter_subscript_oob
)
388 ._M_iterator(*this)._M_integer(__n
));
393 operator+=(const difference_type
& __n
) _GLIBCXX_NOEXCEPT
395 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
),
396 _M_message(__msg_advance_oob
)
397 ._M_iterator(*this)._M_integer(__n
));
398 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
404 operator+(const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
406 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
),
407 _M_message(__msg_advance_oob
)
408 ._M_iterator(*this)._M_integer(__n
));
409 return _Safe_iterator(base() + __n
, this->_M_sequence
);
413 operator-=(const difference_type
& __n
) _GLIBCXX_NOEXCEPT
415 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n
),
416 _M_message(__msg_retreat_oob
)
417 ._M_iterator(*this)._M_integer(__n
));
418 __gnu_cxx::__scoped_lock
__l(this->_M_get_mutex());
424 operator-(const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
426 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n
),
427 _M_message(__msg_retreat_oob
)
428 ._M_iterator(*this)._M_integer(__n
));
429 return _Safe_iterator(base() - __n
, this->_M_sequence
);
432 // ------ Utilities ------
434 * @brief Return the underlying iterator
437 base() _GLIBCXX_NOEXCEPT
{ return *this; }
440 base() const _GLIBCXX_NOEXCEPT
{ return *this; }
443 * @brief Conversion to underlying non-debug iterator to allow
444 * better interaction with non-debug containers.
446 operator _Iterator() const _GLIBCXX_NOEXCEPT
{ return *this; }
448 /** Attach iterator to the given sequence. */
450 _M_attach(_Safe_sequence_base
* __seq
)
451 { _Safe_base::_M_attach(__seq
, _M_constant()); }
453 /** Likewise, but not thread-safe. */
455 _M_attach_single(_Safe_sequence_base
* __seq
)
456 { _Safe_base::_M_attach_single(__seq
, _M_constant()); }
458 /// Is the iterator dereferenceable?
460 _M_dereferenceable() const
461 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
463 /// Is the iterator before a dereferenceable one?
465 _M_before_dereferenceable() const
467 if (this->_M_incrementable())
469 _Iterator __base
= base();
470 return ++__base
!= _M_get_sequence()->_M_base().end();
475 /// Is the iterator incrementable?
477 _M_incrementable() const
478 { return !this->_M_singular() && !_M_is_end(); }
480 // Is the iterator decrementable?
482 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
484 // Can we advance the iterator @p __n steps (@p __n may be negative)
486 _M_can_advance(const difference_type
& __n
) const;
488 // Is the iterator range [*this, __rhs) valid?
490 _M_valid_range(const _Safe_iterator
& __rhs
) const;
492 // The sequence this iterator references.
494 __gnu_cxx::__conditional_type
<std::__are_same
<_Const_iterator
,
495 _Safe_iterator
>::__value
,
498 _M_get_sequence() const
499 { return static_cast<_Sequence
*>(_M_sequence
); }
501 /// Is this iterator equal to the sequence's begin() iterator?
504 { return base() == _M_get_sequence()->_M_base().begin(); }
506 /// Is this iterator equal to the sequence's end() iterator?
509 { return base() == _M_get_sequence()->_M_base().end(); }
511 /// Is this iterator equal to the sequence's before_begin() iterator if
514 _M_is_before_begin() const
515 { return _BeforeBeginHelper
<_Sequence
>::_S_Is(*this); }
517 /// Is this iterator equal to the sequence's before_begin() iterator if
518 /// any or begin() otherwise?
520 _M_is_beginnest() const
521 { return _BeforeBeginHelper
<_Sequence
>::_S_Is_Beginnest(*this); }
524 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
526 operator==(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
527 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
530 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
531 _M_message(__msg_iter_compare_bad
)
532 ._M_iterator(__lhs
, "lhs")
533 ._M_iterator(__rhs
, "rhs"));
534 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
535 _M_message(__msg_compare_different
)
536 ._M_iterator(__lhs
, "lhs")
537 ._M_iterator(__rhs
, "rhs"));
538 return __lhs
.base() == __rhs
.base();
541 template<typename _Iterator
, typename _Sequence
>
543 operator==(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
544 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
547 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
548 _M_message(__msg_iter_compare_bad
)
549 ._M_iterator(__lhs
, "lhs")
550 ._M_iterator(__rhs
, "rhs"));
551 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
552 _M_message(__msg_compare_different
)
553 ._M_iterator(__lhs
, "lhs")
554 ._M_iterator(__rhs
, "rhs"));
555 return __lhs
.base() == __rhs
.base();
558 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
560 operator!=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
561 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
564 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
565 _M_message(__msg_iter_compare_bad
)
566 ._M_iterator(__lhs
, "lhs")
567 ._M_iterator(__rhs
, "rhs"));
568 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
569 _M_message(__msg_compare_different
)
570 ._M_iterator(__lhs
, "lhs")
571 ._M_iterator(__rhs
, "rhs"));
572 return __lhs
.base() != __rhs
.base();
575 template<typename _Iterator
, typename _Sequence
>
577 operator!=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
578 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
581 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
582 _M_message(__msg_iter_compare_bad
)
583 ._M_iterator(__lhs
, "lhs")
584 ._M_iterator(__rhs
, "rhs"));
585 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
586 _M_message(__msg_compare_different
)
587 ._M_iterator(__lhs
, "lhs")
588 ._M_iterator(__rhs
, "rhs"));
589 return __lhs
.base() != __rhs
.base();
592 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
594 operator<(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
595 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
609 template<typename _Iterator
, typename _Sequence
>
611 operator<(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
612 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
615 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
616 _M_message(__msg_iter_order_bad
)
617 ._M_iterator(__lhs
, "lhs")
618 ._M_iterator(__rhs
, "rhs"));
619 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
620 _M_message(__msg_order_different
)
621 ._M_iterator(__lhs
, "lhs")
622 ._M_iterator(__rhs
, "rhs"));
623 return __lhs
.base() < __rhs
.base();
626 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
628 operator<=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
629 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
632 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
633 _M_message(__msg_iter_order_bad
)
634 ._M_iterator(__lhs
, "lhs")
635 ._M_iterator(__rhs
, "rhs"));
636 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
637 _M_message(__msg_order_different
)
638 ._M_iterator(__lhs
, "lhs")
639 ._M_iterator(__rhs
, "rhs"));
640 return __lhs
.base() <= __rhs
.base();
643 template<typename _Iterator
, typename _Sequence
>
645 operator<=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
646 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
649 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
650 _M_message(__msg_iter_order_bad
)
651 ._M_iterator(__lhs
, "lhs")
652 ._M_iterator(__rhs
, "rhs"));
653 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
654 _M_message(__msg_order_different
)
655 ._M_iterator(__lhs
, "lhs")
656 ._M_iterator(__rhs
, "rhs"));
657 return __lhs
.base() <= __rhs
.base();
660 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
662 operator>(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
663 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
666 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
667 _M_message(__msg_iter_order_bad
)
668 ._M_iterator(__lhs
, "lhs")
669 ._M_iterator(__rhs
, "rhs"));
670 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
671 _M_message(__msg_order_different
)
672 ._M_iterator(__lhs
, "lhs")
673 ._M_iterator(__rhs
, "rhs"));
674 return __lhs
.base() > __rhs
.base();
677 template<typename _Iterator
, typename _Sequence
>
679 operator>(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
680 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
683 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
684 _M_message(__msg_iter_order_bad
)
685 ._M_iterator(__lhs
, "lhs")
686 ._M_iterator(__rhs
, "rhs"));
687 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
688 _M_message(__msg_order_different
)
689 ._M_iterator(__lhs
, "lhs")
690 ._M_iterator(__rhs
, "rhs"));
691 return __lhs
.base() > __rhs
.base();
694 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
696 operator>=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
697 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
700 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
701 _M_message(__msg_iter_order_bad
)
702 ._M_iterator(__lhs
, "lhs")
703 ._M_iterator(__rhs
, "rhs"));
704 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
705 _M_message(__msg_order_different
)
706 ._M_iterator(__lhs
, "lhs")
707 ._M_iterator(__rhs
, "rhs"));
708 return __lhs
.base() >= __rhs
.base();
711 template<typename _Iterator
, typename _Sequence
>
713 operator>=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
714 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
717 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
718 _M_message(__msg_iter_order_bad
)
719 ._M_iterator(__lhs
, "lhs")
720 ._M_iterator(__rhs
, "rhs"));
721 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
722 _M_message(__msg_order_different
)
723 ._M_iterator(__lhs
, "lhs")
724 ._M_iterator(__rhs
, "rhs"));
725 return __lhs
.base() >= __rhs
.base();
728 // _GLIBCXX_RESOLVE_LIB_DEFECTS
729 // According to the resolution of DR179 not only the various comparison
730 // operators but also operator- must accept mixed iterator/const_iterator
732 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
733 inline typename _Safe_iterator
<_IteratorL
, _Sequence
>::difference_type
734 operator-(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
735 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
738 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
739 _M_message(__msg_distance_bad
)
740 ._M_iterator(__lhs
, "lhs")
741 ._M_iterator(__rhs
, "rhs"));
742 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
743 _M_message(__msg_distance_different
)
744 ._M_iterator(__lhs
, "lhs")
745 ._M_iterator(__rhs
, "rhs"));
746 return __lhs
.base() - __rhs
.base();
749 template<typename _Iterator
, typename _Sequence
>
750 inline typename _Safe_iterator
<_Iterator
, _Sequence
>::difference_type
751 operator-(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
752 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
755 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
756 _M_message(__msg_distance_bad
)
757 ._M_iterator(__lhs
, "lhs")
758 ._M_iterator(__rhs
, "rhs"));
759 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
760 _M_message(__msg_distance_different
)
761 ._M_iterator(__lhs
, "lhs")
762 ._M_iterator(__rhs
, "rhs"));
763 return __lhs
.base() - __rhs
.base();
766 template<typename _Iterator
, typename _Sequence
>
767 inline _Safe_iterator
<_Iterator
, _Sequence
>
768 operator+(typename _Safe_iterator
<_Iterator
,_Sequence
>::difference_type __n
,
769 const _Safe_iterator
<_Iterator
, _Sequence
>& __i
) _GLIBCXX_NOEXCEPT
770 { return __i
+ __n
; }
771 } // namespace __gnu_debug
773 #include <debug/safe_iterator.tcc>