1 // Safe iterator implementation -*- C++ -*-
3 // Copyright (C) 2003-2014 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 template<typename _Iterator
, typename _Sequence
>
114 class _Safe_iterator
: public _Safe_iterator_base
116 typedef _Safe_iterator _Self
;
117 typedef typename
_Sequence::const_iterator _Const_iterator
;
119 /// The underlying iterator
120 _Iterator _M_current
;
122 /// Determine if this is a constant iterator.
125 { return std::__are_same
<_Const_iterator
, _Safe_iterator
>::__value
; }
127 typedef std::iterator_traits
<_Iterator
> _Traits
;
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
;
137 /// @post the iterator is singular and unattached
138 _Safe_iterator() _GLIBCXX_NOEXCEPT
: _M_current() { }
141 * @brief Safe iterator construction from an unsafe iterator and
144 * @pre @p seq is not NULL
145 * @post this is not singular
147 _Safe_iterator(const _Iterator
& __i
, const _Sequence
* __seq
)
149 : _Safe_iterator_base(__seq
, _M_constant()), _M_current(__i
)
151 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
152 _M_message(__msg_init_singular
)
153 ._M_iterator(*this, "this"));
157 * @brief Copy construction.
159 _Safe_iterator(const _Safe_iterator
& __x
) _GLIBCXX_NOEXCEPT
160 : _Safe_iterator_base(__x
, _M_constant()), _M_current(__x
._M_current
)
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"));
171 #if __cplusplus >= 201103L
173 * @brief Move construction.
174 * @post __x is singular and unattached
176 _Safe_iterator(_Safe_iterator
&& __x
) noexcept
: _M_current()
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
);
190 * @brief Converting constructor from a mutable iterator to a
193 template<typename _MutableIterator
>
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())
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"));
211 * @brief Copy assignment.
214 operator=(const _Safe_iterator
& __x
) _GLIBCXX_NOEXCEPT
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
);
228 #if __cplusplus >= 201103L
230 * @brief Move assignment.
231 * @post __x is singular and unattached
234 operator=(_Safe_iterator
&& __x
) noexcept
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
);
247 __x
._M_current
= _Iterator();
253 * @brief Iterator dereference.
254 * @pre iterator is dereferenceable
257 operator*() const _GLIBCXX_NOEXCEPT
259 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
260 _M_message(__msg_bad_deref
)
261 ._M_iterator(*this, "this"));
266 * @brief Iterator dereference.
267 * @pre iterator is dereferenceable
268 * @todo Make this correct w.r.t. iterators that return proxies
271 operator->() const _GLIBCXX_NOEXCEPT
273 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
274 _M_message(__msg_bad_deref
)
275 ._M_iterator(*this, "this"));
276 return std::__addressof(*_M_current
);
279 // ------ Input iterator requirements ------
281 * @brief Iterator preincrement
282 * @pre iterator is incrementable
285 operator++() _GLIBCXX_NOEXCEPT
287 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
288 _M_message(__msg_bad_inc
)
289 ._M_iterator(*this, "this"));
295 * @brief Iterator postincrement
296 * @pre iterator is incrementable
299 operator++(int) _GLIBCXX_NOEXCEPT
301 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
302 _M_message(__msg_bad_inc
)
303 ._M_iterator(*this, "this"));
304 _Safe_iterator
__tmp(*this);
309 // ------ Bidirectional iterator requirements ------
311 * @brief Iterator predecrement
312 * @pre iterator is decrementable
315 operator--() _GLIBCXX_NOEXCEPT
317 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
318 _M_message(__msg_bad_dec
)
319 ._M_iterator(*this, "this"));
325 * @brief Iterator postdecrement
326 * @pre iterator is decrementable
329 operator--(int) _GLIBCXX_NOEXCEPT
331 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
332 _M_message(__msg_bad_dec
)
333 ._M_iterator(*this, "this"));
334 _Safe_iterator
__tmp(*this);
339 // ------ Random access iterator requirements ------
341 operator[](const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
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
));
348 return _M_current
[__n
];
352 operator+=(const difference_type
& __n
) _GLIBCXX_NOEXCEPT
354 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
),
355 _M_message(__msg_advance_oob
)
356 ._M_iterator(*this)._M_integer(__n
));
362 operator+(const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
364 _Safe_iterator
__tmp(*this);
370 operator-=(const difference_type
& __n
) _GLIBCXX_NOEXCEPT
372 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n
),
373 _M_message(__msg_retreat_oob
)
374 ._M_iterator(*this)._M_integer(__n
));
380 operator-(const difference_type
& __n
) const _GLIBCXX_NOEXCEPT
382 _Safe_iterator
__tmp(*this);
387 // ------ Utilities ------
389 * @brief Return the underlying iterator
392 base() const _GLIBCXX_NOEXCEPT
{ return _M_current
; }
395 * @brief Conversion to underlying non-debug iterator to allow
396 * better interaction with non-debug containers.
398 operator _Iterator() const _GLIBCXX_NOEXCEPT
{ return _M_current
; }
400 /** Attach iterator to the given sequence. */
402 _M_attach(_Safe_sequence_base
* __seq
)
404 _Safe_iterator_base::_M_attach(__seq
, _M_constant());
407 /** Likewise, but not thread-safe. */
409 _M_attach_single(_Safe_sequence_base
* __seq
)
411 _Safe_iterator_base::_M_attach_single(__seq
, _M_constant());
414 /// Is the iterator dereferenceable?
416 _M_dereferenceable() const
417 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
419 /// Is the iterator before a dereferenceable one?
421 _M_before_dereferenceable() const
423 if (this->_M_incrementable())
425 _Iterator __base
= base();
426 return ++__base
!= _M_get_sequence()->_M_base().end();
431 /// Is the iterator incrementable?
433 _M_incrementable() const
434 { return !this->_M_singular() && !_M_is_end(); }
436 // Is the iterator decrementable?
438 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
440 // Can we advance the iterator @p __n steps (@p __n may be negative)
442 _M_can_advance(const difference_type
& __n
) const;
444 // Is the iterator range [*this, __rhs) valid?
446 _M_valid_range(const _Safe_iterator
& __rhs
) const;
448 // The sequence this iterator references.
450 __gnu_cxx::__conditional_type
<std::__are_same
<_Const_iterator
,
451 _Safe_iterator
>::__value
,
454 _M_get_sequence() const
455 { return static_cast<_Sequence
*>(_M_sequence
); }
457 /// Is this iterator equal to the sequence's begin() iterator?
460 { return base() == _M_get_sequence()->_M_base().begin(); }
462 /// Is this iterator equal to the sequence's end() iterator?
465 { return base() == _M_get_sequence()->_M_base().end(); }
467 /// Is this iterator equal to the sequence's before_begin() iterator if
470 _M_is_before_begin() const
471 { return _BeforeBeginHelper
<_Sequence
>::_S_Is(*this); }
473 /// Is this iterator equal to the sequence's before_begin() iterator if
474 /// any or begin() otherwise?
476 _M_is_beginnest() const
477 { return _BeforeBeginHelper
<_Sequence
>::_S_Is_Beginnest(*this); }
480 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
482 operator==(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
483 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
497 template<typename _Iterator
, typename _Sequence
>
499 operator==(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
500 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
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();
514 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
516 operator!=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
517 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
531 template<typename _Iterator
, typename _Sequence
>
533 operator!=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
534 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
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();
548 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
550 operator<(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
551 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
565 template<typename _Iterator
, typename _Sequence
>
567 operator<(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
568 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
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();
582 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
584 operator<=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
585 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
599 template<typename _Iterator
, typename _Sequence
>
601 operator<=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
602 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
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();
616 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
618 operator>(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
619 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
633 template<typename _Iterator
, typename _Sequence
>
635 operator>(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
636 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
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();
650 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
652 operator>=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
653 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
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();
667 template<typename _Iterator
, typename _Sequence
>
669 operator>=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
670 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
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();
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
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
)
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();
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
)
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();
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
729 #include <debug/safe_iterator.tcc>