29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 44 template <
typename _Sequence>
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(); }
80 template<
typename _Iterator1,
typename _Iterator2>
87 template<
typename _Iterator1,
typename _Iterator2>
94 template<
typename _Iterator1,
typename _Iterator2>
99 typedef typename std::iterator_traits<_Iterator1>::iterator_category
115 template<
typename _Iterator,
typename _Sequence>
121 _Iterator _M_current;
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;
154 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
155 _M_message(__msg_init_singular)
156 ._M_iterator(*
this,
"this"));
168 || __x._M_current == _Iterator(),
169 _M_message(__msg_init_copy_singular)
170 ._M_iterator(*
this,
"this")
171 ._M_iterator(__x,
"other"));
174 #if __cplusplus >= 201103L 181 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
182 || __x._M_current == _Iterator(),
183 _M_message(__msg_init_copy_singular)
184 ._M_iterator(*
this,
"this")
185 ._M_iterator(__x,
"other"));
187 this->_M_attach(__x._M_sequence);
196 template<
typename _MutableIterator>
199 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
200 typename _Sequence::iterator::iterator_type>::__value),
201 _Sequence>::__type>& __x)
206 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
207 || __x.base() == _Iterator(),
208 _M_message(__msg_init_const_singular)
209 ._M_iterator(*
this,
"this")
210 ._M_iterator(__x,
"other"));
222 || __x._M_current == _Iterator(),
223 _M_message(__msg_copy_singular)
224 ._M_iterator(*
this,
"this")
225 ._M_iterator(__x,
"other"));
226 _M_current = __x._M_current;
231 #if __cplusplus >= 201103L 239 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
240 _M_message(__msg_self_move_assign)
241 ._M_iterator(*
this,
"this"));
242 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
243 || __x._M_current == _Iterator(),
244 _M_message(__msg_copy_singular)
245 ._M_iterator(*
this,
"this")
246 ._M_iterator(__x,
"other"));
247 _M_current = __x._M_current;
248 _M_attach(__x._M_sequence);
250 __x._M_current = _Iterator();
262 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
263 _M_message(__msg_bad_deref)
264 ._M_iterator(*
this,
"this"));
277 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
278 _M_message(__msg_bad_deref)
279 ._M_iterator(*
this,
"this"));
291 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
292 _M_message(__msg_bad_inc)
293 ._M_iterator(*
this,
"this"));
305 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
306 _M_message(__msg_bad_inc)
307 ._M_iterator(*
this,
"this"));
321 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
322 _M_message(__msg_bad_dec)
323 ._M_iterator(*
this,
"this"));
335 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
336 _M_message(__msg_bad_dec)
337 ._M_iterator(*
this,
"this"));
345 operator[](
const difference_type& __n)
const 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)
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 374 operator-=(
const difference_type& __n)
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 396 base()
const {
return _M_current; }
402 operator _Iterator()
const {
return _M_current; }
421 {
return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
427 if (this->_M_incrementable())
429 _Iterator
__base = base();
430 return ++__base != _M_get_sequence()->_M_base().end();
438 {
return !this->_M_singular() && !_M_is_end(); }
442 _M_decrementable()
const {
return !_M_singular() && !_M_is_begin(); }
446 _M_can_advance(
const difference_type& __n)
const;
449 template<
typename _Other>
455 _M_get_sequence()
const 456 {
return static_cast<const _Sequence*
>(_M_sequence); }
460 {
return base() == _M_get_sequence()->_M_base().begin(); }
464 {
return base() == _M_get_sequence()->_M_base().end(); }
482 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
488 _M_message(__msg_iter_compare_bad)
489 ._M_iterator(__lhs,
"lhs")
490 ._M_iterator(__rhs,
"rhs"));
492 _M_message(__msg_compare_different)
493 ._M_iterator(__lhs,
"lhs")
494 ._M_iterator(__rhs,
"rhs"));
495 return __lhs.
base() == __rhs.
base();
498 template<
typename _Iterator,
typename _Sequence>
504 _M_message(__msg_iter_compare_bad)
505 ._M_iterator(__lhs,
"lhs")
506 ._M_iterator(__rhs,
"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>
520 _M_message(__msg_iter_compare_bad)
521 ._M_iterator(__lhs,
"lhs")
522 ._M_iterator(__rhs,
"rhs"));
524 _M_message(__msg_compare_different)
525 ._M_iterator(__lhs,
"lhs")
526 ._M_iterator(__rhs,
"rhs"));
527 return __lhs.
base() != __rhs.
base();
530 template<
typename _Iterator,
typename _Sequence>
536 _M_message(__msg_iter_compare_bad)
537 ._M_iterator(__lhs,
"lhs")
538 ._M_iterator(__rhs,
"rhs"));
540 _M_message(__msg_compare_different)
541 ._M_iterator(__lhs,
"lhs")
542 ._M_iterator(__rhs,
"rhs"));
543 return __lhs.
base() != __rhs.
base();
546 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
548 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
551 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs.
_M_singular(),
552 _M_message(__msg_iter_order_bad)
553 ._M_iterator(__lhs,
"lhs")
554 ._M_iterator(__rhs,
"rhs"));
555 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
556 _M_message(__msg_order_different)
557 ._M_iterator(__lhs,
"lhs")
558 ._M_iterator(__rhs,
"rhs"));
559 return __lhs.base() < __rhs.
base();
562 template<
typename _Iterator,
typename _Sequence>
564 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
567 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs.
_M_singular(),
568 _M_message(__msg_iter_order_bad)
569 ._M_iterator(__lhs,
"lhs")
570 ._M_iterator(__rhs,
"rhs"));
571 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
572 _M_message(__msg_order_different)
573 ._M_iterator(__lhs,
"lhs")
574 ._M_iterator(__rhs,
"rhs"));
575 return __lhs.base() < __rhs.
base();
578 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
580 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
583 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs.
_M_singular(),
584 _M_message(__msg_iter_order_bad)
585 ._M_iterator(__lhs,
"lhs")
586 ._M_iterator(__rhs,
"rhs"));
587 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
588 _M_message(__msg_order_different)
589 ._M_iterator(__lhs,
"lhs")
590 ._M_iterator(__rhs,
"rhs"));
591 return __lhs.base() <= __rhs.
base();
594 template<
typename _Iterator,
typename _Sequence>
596 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
599 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs.
_M_singular(),
600 _M_message(__msg_iter_order_bad)
601 ._M_iterator(__lhs,
"lhs")
602 ._M_iterator(__rhs,
"rhs"));
603 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
604 _M_message(__msg_order_different)
605 ._M_iterator(__lhs,
"lhs")
606 ._M_iterator(__rhs,
"rhs"));
607 return __lhs.base() <= __rhs.
base();
610 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
616 _M_message(__msg_iter_order_bad)
617 ._M_iterator(__lhs,
"lhs")
618 ._M_iterator(__rhs,
"rhs"));
620 _M_message(__msg_order_different)
621 ._M_iterator(__lhs,
"lhs")
622 ._M_iterator(__rhs,
"rhs"));
626 template<
typename _Iterator,
typename _Sequence>
632 _M_message(__msg_iter_order_bad)
633 ._M_iterator(__lhs,
"lhs")
634 ._M_iterator(__rhs,
"rhs"));
636 _M_message(__msg_order_different)
637 ._M_iterator(__lhs,
"lhs")
638 ._M_iterator(__rhs,
"rhs"));
642 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
648 _M_message(__msg_iter_order_bad)
649 ._M_iterator(__lhs,
"lhs")
650 ._M_iterator(__rhs,
"rhs"));
652 _M_message(__msg_order_different)
653 ._M_iterator(__lhs,
"lhs")
654 ._M_iterator(__rhs,
"rhs"));
655 return __lhs.
base() >= __rhs.
base();
658 template<
typename _Iterator,
typename _Sequence>
664 _M_message(__msg_iter_order_bad)
665 ._M_iterator(__lhs,
"lhs")
666 ._M_iterator(__rhs,
"rhs"));
668 _M_message(__msg_order_different)
669 ._M_iterator(__lhs,
"lhs")
670 ._M_iterator(__rhs,
"rhs"));
671 return __lhs.
base() >= __rhs.
base();
678 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
679 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
684 _M_message(__msg_distance_bad)
685 ._M_iterator(__lhs,
"lhs")
686 ._M_iterator(__rhs,
"rhs"));
688 _M_message(__msg_distance_different)
689 ._M_iterator(__lhs,
"lhs")
690 ._M_iterator(__rhs,
"rhs"));
694 template<
typename _Iterator,
typename _Sequence>
695 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
700 _M_message(__msg_distance_bad)
701 ._M_iterator(__lhs,
"lhs")
702 ._M_iterator(__rhs,
"rhs"));
704 _M_message(__msg_distance_different)
705 ._M_iterator(__lhs,
"lhs")
706 ._M_iterator(__rhs,
"rhs"));
710 template<
typename _Iterator,
typename _Sequence>
712 operator+(
typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
714 {
return __i + __n; }
717 #include <debug/safe_iterator.tcc> _Safe_iterator & operator=(_Safe_iterator &&__x)
Move assignment.
Basic functionality for a safe iterator.
reference operator*() const
Iterator dereference.
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
std::pair< typename std::iterator_traits< _Iterator1 >::difference_type, _Distance_precision > __get_distance(const _Iterator1 &__lhs, const _Iterator2 &__rhs, std::random_access_iterator_tag)
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise...
_Safe_iterator(const _Iterator &__i, const _Sequence *__seq)
Safe iterator construction from an unsafe iterator and its sequence.
void _M_attach_single(_Safe_sequence_base *__seq)
Forward iterators support a superset of input iterator operations.
void _M_attach(_Safe_sequence_base *__seq)
GNU debug classes for public use.
_Safe_iterator(const _Safe_iterator &__x)
Copy construction.
bool _M_can_compare(const _Safe_iterator_base &__x) const
_Safe_iterator & operator++()
Iterator preincrement.
bool _M_incrementable() const
Is the iterator incrementable?
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
_Safe_iterator & operator=(const _Safe_iterator &__x)
Copy assignment.
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
pointer operator->() const
Iterator dereference.
_Safe_iterator(_Safe_iterator &&__x)
Move construction.
Struct holding two objects of arbitrary type.
Random-access iterators support a superset of bidirectional iterator operations.
void swap(_Tp &, _Tp &) noexcept(__and_< is_nothrow_move_constructible< _Tp >, is_nothrow_move_assignable< _Tp >>::value)
Swaps two values.
_Safe_iterator operator++(int)
Iterator postincrement.
_Safe_iterator & operator--()
Iterator predecrement.
_Safe_iterator operator--(int)
Iterator postdecrement.
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Base class that supports tracking of iterators that reference a sequence.
_Safe_sequence_base * _M_sequence
bool _M_dereferenceable() const
Is the iterator dereferenceable?
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
_Iterator base() const
Return the underlying iterator.
_Safe_iterator(const _Safe_iterator< _MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same< _MutableIterator, typename _Sequence::iterator::iterator_type >::__value), _Sequence >::__type > &__x)
Converting constructor from a mutable iterator to a constant iterator.
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?