1 // Safe iterator implementation -*- C++ -*-
3 // Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
26 /** @file debug/safe_iterator.h
27 * This file is a GNU debug extension to the Standard C++ Library.
30 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
31 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
33 #include <debug/debug.h>
34 #include <debug/macros.h>
35 #include <debug/functions.h>
36 #include <debug/safe_base.h>
37 #include <bits/stl_pair.h>
38 #include <ext/type_traits.h>
42 /** Helper struct to deal with sequence offering a before_begin
45 template <typename _Sequence
>
46 struct _BeforeBeginHelper
48 typedef typename
_Sequence::const_iterator _It
;
49 typedef typename
_It::iterator_type _BaseIt
;
52 _S_Is(_BaseIt
, const _Sequence
*)
56 _S_Is_Beginnest(_BaseIt __it
, const _Sequence
* __seq
)
57 { return __it
== __seq
->_M_base().begin(); }
60 /** Iterators that derive from _Safe_iterator_base but that aren't
61 * _Safe_iterators can be determined singular or non-singular via
62 * _Safe_iterator_base.
65 __check_singular_aux(const _Safe_iterator_base
* __x
)
66 { return __x
->_M_singular(); }
68 /** The precision to which we can calculate the distance between
71 enum _Distance_precision
73 __dp_equality
, //< Can compare iterator equality, only
74 __dp_sign
, //< Can determine equality and ordering
75 __dp_exact
//< Can determine distance precisely
78 /** Determine the distance between two iterators with some known
81 template<typename _Iterator1
, typename _Iterator2
>
82 inline std::pair
<typename
std::iterator_traits
<_Iterator1
>::difference_type
,
84 __get_distance(const _Iterator1
& __lhs
, const _Iterator2
& __rhs
,
85 std::random_access_iterator_tag
)
86 { return std::make_pair(__rhs
- __lhs
, __dp_exact
); }
88 template<typename _Iterator1
, typename _Iterator2
>
89 inline std::pair
<typename
std::iterator_traits
<_Iterator1
>::difference_type
,
91 __get_distance(const _Iterator1
& __lhs
, const _Iterator2
& __rhs
,
92 std::forward_iterator_tag
)
93 { return std::make_pair(__lhs
== __rhs
? 0 : 1, __dp_equality
); }
95 template<typename _Iterator1
, typename _Iterator2
>
96 inline std::pair
<typename
std::iterator_traits
<_Iterator1
>::difference_type
,
98 __get_distance(const _Iterator1
& __lhs
, const _Iterator2
& __rhs
)
100 typedef typename
std::iterator_traits
<_Iterator1
>::iterator_category
102 return __get_distance(__lhs
, __rhs
, _Category());
105 /** \brief Safe iterator wrapper.
107 * The class template %_Safe_iterator is a wrapper around an
108 * iterator that tracks the iterator's movement among sequences and
109 * checks that operations performed on the "safe" iterator are
110 * legal. In additional to the basic iterator operations (which are
111 * validated, and then passed to the underlying iterator),
112 * %_Safe_iterator has member functions for iterator invalidation,
113 * attaching/detaching the iterator from sequences, and querying
114 * the iterator's state.
116 template<typename _Iterator
, typename _Sequence
>
117 class _Safe_iterator
: public _Safe_iterator_base
119 typedef _Safe_iterator _Self
;
121 /// The underlying iterator
122 _Iterator _M_current
;
124 /// Determine if this is a constant iterator.
128 typedef typename
_Sequence::const_iterator const_iterator
;
129 return std::__are_same
<const_iterator
, _Safe_iterator
>::__value
;
132 typedef std::iterator_traits
<_Iterator
> _Traits
;
135 typedef _Iterator iterator_type
;
136 typedef typename
_Traits::iterator_category iterator_category
;
137 typedef typename
_Traits::value_type value_type
;
138 typedef typename
_Traits::difference_type difference_type
;
139 typedef typename
_Traits::reference reference
;
140 typedef typename
_Traits::pointer pointer
;
142 /// @post the iterator is singular and unattached
143 _Safe_iterator() : _M_current() { }
146 * @brief Safe iterator construction from an unsafe iterator and
149 * @pre @p seq is not NULL
150 * @post this is not singular
152 _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
)
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
177 * @brief Move construction.
178 * @post __x is singular and unattached
180 _Safe_iterator(_Safe_iterator
&& __x
) : _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
)
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
)
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
234 * @brief Move assignment.
235 * @post __x is singular and unattached
238 operator=(_Safe_iterator
&& __x
)
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
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
273 * @todo Use addressof() instead of & operator
278 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
279 _M_message(__msg_bad_deref
)
280 ._M_iterator(*this, "this"));
284 // ------ Input iterator requirements ------
286 * @brief Iterator preincrement
287 * @pre iterator is incrementable
292 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
293 _M_message(__msg_bad_inc
)
294 ._M_iterator(*this, "this"));
300 * @brief Iterator postincrement
301 * @pre iterator is incrementable
306 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
307 _M_message(__msg_bad_inc
)
308 ._M_iterator(*this, "this"));
309 _Safe_iterator
__tmp(*this);
314 // ------ Bidirectional iterator requirements ------
316 * @brief Iterator predecrement
317 * @pre iterator is decrementable
322 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
323 _M_message(__msg_bad_dec
)
324 ._M_iterator(*this, "this"));
330 * @brief Iterator postdecrement
331 * @pre iterator is decrementable
336 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
337 _M_message(__msg_bad_dec
)
338 ._M_iterator(*this, "this"));
339 _Safe_iterator
__tmp(*this);
344 // ------ Random access iterator requirements ------
346 operator[](const difference_type
& __n
) const
348 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
)
349 && this->_M_can_advance(__n
+1),
350 _M_message(__msg_iter_subscript_oob
)
351 ._M_iterator(*this)._M_integer(__n
));
353 return _M_current
[__n
];
357 operator+=(const difference_type
& __n
)
359 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n
),
360 _M_message(__msg_advance_oob
)
361 ._M_iterator(*this)._M_integer(__n
));
367 operator+(const difference_type
& __n
) const
369 _Safe_iterator
__tmp(*this);
375 operator-=(const difference_type
& __n
)
377 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n
),
378 _M_message(__msg_retreat_oob
)
379 ._M_iterator(*this)._M_integer(__n
));
385 operator-(const difference_type
& __n
) const
387 _Safe_iterator
__tmp(*this);
392 // ------ Utilities ------
394 * @brief Return the underlying iterator
397 base() const { return _M_current
; }
400 * @brief Conversion to underlying non-debug iterator to allow
401 * better interaction with non-debug containers.
403 operator _Iterator() const { return _M_current
; }
405 /** Attach iterator to the given sequence. */
407 _M_attach(_Safe_sequence_base
* __seq
)
409 _Safe_iterator_base::_M_attach(__seq
, _M_constant());
412 /** Likewise, but not thread-safe. */
414 _M_attach_single(_Safe_sequence_base
* __seq
)
416 _Safe_iterator_base::_M_attach_single(__seq
, _M_constant());
419 /// Is the iterator dereferenceable?
421 _M_dereferenceable() const
422 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
424 /// Is the iterator before a dereferenceable one?
426 _M_before_dereferenceable() const
428 if (this->_M_incrementable())
430 _Iterator __base
= base();
431 return ++__base
!= _M_get_sequence()->_M_base().end();
436 /// Is the iterator incrementable?
438 _M_incrementable() const
439 { return !this->_M_singular() && !_M_is_end(); }
441 // Is the iterator decrementable?
443 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
445 // Can we advance the iterator @p __n steps (@p __n may be negative)
447 _M_can_advance(const difference_type
& __n
) const;
449 // Is the iterator range [*this, __rhs) valid?
450 template<typename _Other
>
452 _M_valid_range(const _Safe_iterator
<_Other
, _Sequence
>& __rhs
) const;
454 // The sequence this iterator references.
456 _M_get_sequence() const
457 { return static_cast<const _Sequence
*>(_M_sequence
); }
459 /// Is this iterator equal to the sequence's begin() iterator?
460 bool _M_is_begin() const
461 { return base() == _M_get_sequence()->_M_base().begin(); }
463 /// Is this iterator equal to the sequence's end() iterator?
464 bool _M_is_end() const
465 { return base() == _M_get_sequence()->_M_base().end(); }
467 /// Is this iterator equal to the sequence's before_begin() iterator if
469 bool _M_is_before_begin() const
471 return _BeforeBeginHelper
<_Sequence
>::_S_Is(base(), _M_get_sequence());
474 /// Is this iterator equal to the sequence's before_begin() iterator if
475 /// any or begin() otherwise?
476 bool _M_is_beginnest() const
478 return _BeforeBeginHelper
<_Sequence
>::_S_Is_Beginnest(base(),
483 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
485 operator==(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
486 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
)
504 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
505 _M_message(__msg_iter_compare_bad
)
506 ._M_iterator(__lhs
, "lhs")
507 ._M_iterator(__rhs
, "rhs"));
508 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
509 _M_message(__msg_compare_different
)
510 ._M_iterator(__lhs
, "lhs")
511 ._M_iterator(__rhs
, "rhs"));
512 return __lhs
.base() == __rhs
.base();
515 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
517 operator!=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
518 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
)
536 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
537 _M_message(__msg_iter_compare_bad
)
538 ._M_iterator(__lhs
, "lhs")
539 ._M_iterator(__rhs
, "rhs"));
540 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
541 _M_message(__msg_compare_different
)
542 ._M_iterator(__lhs
, "lhs")
543 ._M_iterator(__rhs
, "rhs"));
544 return __lhs
.base() != __rhs
.base();
547 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
549 operator<(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
550 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
552 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
553 _M_message(__msg_iter_order_bad
)
554 ._M_iterator(__lhs
, "lhs")
555 ._M_iterator(__rhs
, "rhs"));
556 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
557 _M_message(__msg_order_different
)
558 ._M_iterator(__lhs
, "lhs")
559 ._M_iterator(__rhs
, "rhs"));
560 return __lhs
.base() < __rhs
.base();
563 template<typename _Iterator
, typename _Sequence
>
565 operator<(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
566 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
568 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
569 _M_message(__msg_iter_order_bad
)
570 ._M_iterator(__lhs
, "lhs")
571 ._M_iterator(__rhs
, "rhs"));
572 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
573 _M_message(__msg_order_different
)
574 ._M_iterator(__lhs
, "lhs")
575 ._M_iterator(__rhs
, "rhs"));
576 return __lhs
.base() < __rhs
.base();
579 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
581 operator<=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
582 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
584 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
585 _M_message(__msg_iter_order_bad
)
586 ._M_iterator(__lhs
, "lhs")
587 ._M_iterator(__rhs
, "rhs"));
588 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
589 _M_message(__msg_order_different
)
590 ._M_iterator(__lhs
, "lhs")
591 ._M_iterator(__rhs
, "rhs"));
592 return __lhs
.base() <= __rhs
.base();
595 template<typename _Iterator
, typename _Sequence
>
597 operator<=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
598 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
600 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
601 _M_message(__msg_iter_order_bad
)
602 ._M_iterator(__lhs
, "lhs")
603 ._M_iterator(__rhs
, "rhs"));
604 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
605 _M_message(__msg_order_different
)
606 ._M_iterator(__lhs
, "lhs")
607 ._M_iterator(__rhs
, "rhs"));
608 return __lhs
.base() <= __rhs
.base();
611 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
613 operator>(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
614 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
616 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
617 _M_message(__msg_iter_order_bad
)
618 ._M_iterator(__lhs
, "lhs")
619 ._M_iterator(__rhs
, "rhs"));
620 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
621 _M_message(__msg_order_different
)
622 ._M_iterator(__lhs
, "lhs")
623 ._M_iterator(__rhs
, "rhs"));
624 return __lhs
.base() > __rhs
.base();
627 template<typename _Iterator
, typename _Sequence
>
629 operator>(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
630 const _Safe_iterator
<_Iterator
, _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 _IteratorL
, typename _IteratorR
, typename _Sequence
>
645 operator>=(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
646 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
648 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
649 _M_message(__msg_iter_order_bad
)
650 ._M_iterator(__lhs
, "lhs")
651 ._M_iterator(__rhs
, "rhs"));
652 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
653 _M_message(__msg_order_different
)
654 ._M_iterator(__lhs
, "lhs")
655 ._M_iterator(__rhs
, "rhs"));
656 return __lhs
.base() >= __rhs
.base();
659 template<typename _Iterator
, typename _Sequence
>
661 operator>=(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
662 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
664 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
665 _M_message(__msg_iter_order_bad
)
666 ._M_iterator(__lhs
, "lhs")
667 ._M_iterator(__rhs
, "rhs"));
668 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
669 _M_message(__msg_order_different
)
670 ._M_iterator(__lhs
, "lhs")
671 ._M_iterator(__rhs
, "rhs"));
672 return __lhs
.base() >= __rhs
.base();
675 // _GLIBCXX_RESOLVE_LIB_DEFECTS
676 // According to the resolution of DR179 not only the various comparison
677 // operators but also operator- must accept mixed iterator/const_iterator
679 template<typename _IteratorL
, typename _IteratorR
, typename _Sequence
>
680 inline typename _Safe_iterator
<_IteratorL
, _Sequence
>::difference_type
681 operator-(const _Safe_iterator
<_IteratorL
, _Sequence
>& __lhs
,
682 const _Safe_iterator
<_IteratorR
, _Sequence
>& __rhs
)
684 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
685 _M_message(__msg_distance_bad
)
686 ._M_iterator(__lhs
, "lhs")
687 ._M_iterator(__rhs
, "rhs"));
688 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
689 _M_message(__msg_distance_different
)
690 ._M_iterator(__lhs
, "lhs")
691 ._M_iterator(__rhs
, "rhs"));
692 return __lhs
.base() - __rhs
.base();
695 template<typename _Iterator
, typename _Sequence
>
696 inline typename _Safe_iterator
<_Iterator
, _Sequence
>::difference_type
697 operator-(const _Safe_iterator
<_Iterator
, _Sequence
>& __lhs
,
698 const _Safe_iterator
<_Iterator
, _Sequence
>& __rhs
)
700 _GLIBCXX_DEBUG_VERIFY(! __lhs
._M_singular() && ! __rhs
._M_singular(),
701 _M_message(__msg_distance_bad
)
702 ._M_iterator(__lhs
, "lhs")
703 ._M_iterator(__rhs
, "rhs"));
704 _GLIBCXX_DEBUG_VERIFY(__lhs
._M_can_compare(__rhs
),
705 _M_message(__msg_distance_different
)
706 ._M_iterator(__lhs
, "lhs")
707 ._M_iterator(__rhs
, "rhs"));
708 return __lhs
.base() - __rhs
.base();
711 template<typename _Iterator
, typename _Sequence
>
712 inline _Safe_iterator
<_Iterator
, _Sequence
>
713 operator+(typename _Safe_iterator
<_Iterator
,_Sequence
>::difference_type __n
,
714 const _Safe_iterator
<_Iterator
, _Sequence
>& __i
)
715 { return __i
+ __n
; }
716 } // namespace __gnu_debug
718 #include <debug/safe_iterator.tcc>