29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 39 #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \ 40 _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \ 41 _M_message(_BadMsgId) \ 42 ._M_iterator(_Lhs, #_Lhs) \ 43 ._M_iterator(_Rhs, #_Rhs)); \ 44 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \ 45 _M_message(_DiffMsgId) \ 46 ._M_iterator(_Lhs, #_Lhs) \ 47 ._M_iterator(_Rhs, #_Rhs)) 49 #define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \ 50 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \ 51 __msg_compare_different) 53 #define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \ 54 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \ 55 __msg_order_different) 57 #define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \ 58 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \ 59 __msg_distance_different) 66 template<
typename _Sequence>
69 template<
typename _Iterator,
typename _Category>
74 template<
typename _Iterator,
typename _Category>
77 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
81 template<
typename _Sequence>
84 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
87 _S_size(
const _Sequence& __seq)
107 template<
typename _Iterator,
typename _Sequence,
typename _Category
108 =
typename std::iterator_traits<_Iterator>::iterator_category>
113 typedef _Iterator _Iter_base;
116 typedef std::iterator_traits<_Iterator> _Traits;
119 typedef std::__are_same<
typename _Sequence::_Base::const_iterator,
120 _Iterator> _IsConstant;
122 typedef typename __gnu_cxx::__conditional_type<
123 _IsConstant::__value,
124 typename _Sequence::_Base::iterator,
125 typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
127 struct _Attach_single
130 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
136 typedef _Iterator iterator_type;
137 typedef typename _Traits::iterator_category iterator_category;
138 typedef typename _Traits::value_type value_type;
139 typedef typename _Traits::difference_type difference_type;
140 typedef typename _Traits::reference reference;
141 typedef typename _Traits::pointer pointer;
158 _M_message(__msg_init_singular)
159 ._M_iterator(*
this,
"this"));
166 : _Iter_base(__x.base())
170 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
171 || __x.base() == _Iterator(),
172 _M_message(__msg_init_copy_singular)
173 ._M_iterator(*
this,
"this")
174 ._M_iterator(__x,
"other"));
178 #if __cplusplus >= 201103L 186 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
187 || __x.base() == _Iterator(),
188 _M_message(__msg_init_copy_singular)
189 ._M_iterator(*
this,
"this")
190 ._M_iterator(__x,
"other"));
193 std::swap(
base(), __x.base());
202 template<
typename _MutableIterator>
205 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
206 std::__are_same<_MutableIterator, _OtherIterator>::__value,
207 _Category>::__type>& __x)
209 : _Iter_base(__x.base())
213 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
214 || __x.base() == _MutableIterator(),
215 _M_message(__msg_init_const_singular)
216 ._M_iterator(*
this,
"this")
217 ._M_iterator(__x,
"other"));
229 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
230 || __x.base() == _Iterator(),
231 _M_message(__msg_copy_singular)
232 ._M_iterator(*
this,
"this")
233 ._M_iterator(__x,
"other"));
251 #if __cplusplus >= 201103L 259 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
260 _M_message(__msg_self_move_assign)
261 ._M_iterator(*
this,
"this"));
262 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
263 || __x.base() == _Iterator(),
264 _M_message(__msg_copy_singular)
265 ._M_iterator(*
this,
"this")
266 ._M_iterator(__x,
"other"));
282 __x.base() = _Iterator();
295 _M_message(__msg_bad_deref)
296 ._M_iterator(*
this,
"this"));
308 _M_message(__msg_bad_deref)
309 ._M_iterator(*
this,
"this"));
310 return base().operator->();
322 _M_message(__msg_bad_inc)
323 ._M_iterator(*
this,
"this"));
337 _M_message(__msg_bad_inc)
338 ._M_iterator(*
this,
"this"));
346 static _GLIBCXX_CONSTEXPR
bool 348 {
return _IsConstant::__value; }
354 base() _GLIBCXX_NOEXCEPT {
return *
this; }
357 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
363 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
387 return ++
__base != _M_get_sequence()->_M_base().end();
399 _M_can_advance(difference_type __n)
const;
405 bool __check_dereferenceable =
true)
const;
408 typename __gnu_cxx::__conditional_type<
409 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
410 _M_get_sequence()
const 414 typename _Distance_traits<_Iterator>::__type
418 typename _Distance_traits<_Iterator>::__type
419 _M_get_distance_from_begin()
const;
422 typename _Distance_traits<_Iterator>::__type
423 _M_get_distance_to_end()
const;
428 {
return base() == _M_get_sequence()->_M_base().begin(); }
433 {
return base() == _M_get_sequence()->_M_base().end(); }
452 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
454 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
455 return __lhs.base() == __rhs.base();
458 template<
typename _IteR>
460 operator==(
const _Self& __lhs,
461 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
464 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
465 return __lhs.base() == __rhs.base();
469 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
471 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
472 return __lhs.base() != __rhs.base();
475 template<
typename _IteR>
477 operator!=(
const _Self& __lhs,
478 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
481 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
482 return __lhs.base() != __rhs.base();
486 template<
typename _Iterator,
typename _Sequence>
487 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
488 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
494 typedef typename _Safe_base::_OtherIterator _OtherIterator;
495 typedef typename _Safe_base::_Attach_single _Attach_single;
497 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
499 : _Safe_base(__i, __seq, _Attach_single())
515 : _Safe_base(__i, __seq)
525 #if __cplusplus >= 201103L 534 template<
typename _MutableIterator>
537 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
538 std::__are_same<_MutableIterator, _OtherIterator>::__value,
544 #if __cplusplus >= 201103L 557 _Safe_base::operator=(__x);
570 _Safe_base::operator++();
582 _M_message(__msg_bad_inc)
583 ._M_iterator(*
this,
"this"));
595 operator--() _GLIBCXX_NOEXCEPT
597 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
598 _M_message(__msg_bad_dec)
599 ._M_iterator(*
this,
"this"));
610 operator--(
int) _GLIBCXX_NOEXCEPT
612 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
613 _M_message(__msg_bad_dec)
614 ._M_iterator(*
this,
"this"));
624 _M_decrementable()
const 628 template<
typename _Iterator,
typename _Sequence>
629 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
630 :
public _Safe_iterator<_Iterator, _Sequence,
631 std::bidirectional_iterator_tag>
635 typedef typename _Safe_base::_OtherIterator _OtherIterator;
637 typedef typename _Safe_base::_Self _Self;
641 typedef typename _Safe_base::_Attach_single _Attach_single;
643 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
645 : _Safe_base(__i, __seq, _Attach_single())
649 typedef typename _Safe_base::difference_type difference_type;
650 typedef typename _Safe_base::reference reference;
664 : _Safe_base(__i, __seq)
674 #if __cplusplus >= 201103L 683 template<
typename _MutableIterator>
686 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
687 std::__are_same<_MutableIterator, _OtherIterator>::__value,
693 #if __cplusplus >= 201103L 706 _Safe_base::operator=(__x);
725 _Safe_base::operator++();
737 _M_message(__msg_bad_inc)
738 ._M_iterator(*
this,
"this"));
750 operator--() _GLIBCXX_NOEXCEPT
752 _Safe_base::operator--();
761 operator--(
int) _GLIBCXX_NOEXCEPT
763 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
764 _M_message(__msg_bad_dec)
765 ._M_iterator(*
this,
"this"));
773 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
775 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
776 && this->_M_can_advance(__n + 1),
777 _M_message(__msg_iter_subscript_oob)
778 ._M_iterator(*this)._M_integer(__n));
779 return this->
base()[__n];
783 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
785 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
786 _M_message(__msg_advance_oob)
787 ._M_iterator(*this)._M_integer(__n));
794 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
796 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
797 _M_message(__msg_retreat_oob)
798 ._M_iterator(*this)._M_integer(__n));
805 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
807 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
808 return __lhs.base() < __rhs.base();
812 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
814 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
815 return __lhs.base() < __rhs.base();
819 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
821 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
822 return __lhs.base() <= __rhs.base();
826 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
828 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
829 return __lhs.base() <= __rhs.base();
833 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
835 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
836 return __lhs.base() > __rhs.base();
840 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
842 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
843 return __lhs.base() > __rhs.base();
847 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
849 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
850 return __lhs.base() >= __rhs.base();
854 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
856 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
857 return __lhs.base() >= __rhs.base();
864 friend difference_type
865 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
867 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
868 return __lhs.base() - __rhs.base();
871 friend difference_type
872 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
874 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
875 return __lhs.base() - __rhs.base();
879 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
881 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
882 _M_message(__msg_advance_oob)
883 ._M_iterator(__x)._M_integer(__n));
888 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
890 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
891 _M_message(__msg_advance_oob)
892 ._M_iterator(__x)._M_integer(__n));
897 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
899 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
900 _M_message(__msg_retreat_oob)
901 ._M_iterator(__x)._M_integer(__n));
907 template<
typename _Iterator,
typename _Sequence,
typename _Category>
914 {
return __first._M_valid_range(__last, __dist); }
916 template<
typename _Iterator,
typename _Sequence,
typename _Category>
920 const _Safe_iterator<_Iterator, _Sequence,
923 typename _Distance_traits<_Iterator>::__type __dist;
924 return __first._M_valid_range(__last, __dist);
927 template<
typename _Iterator,
typename _Sequence,
typename _Category,
930 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
932 {
return __it._M_can_advance(__n); }
934 template<
typename _Iterator,
typename _Sequence>
936 __base(
const _Safe_iterator<_Iterator, _Sequence,
938 {
return __it.base(); }
940 #if __cplusplus < 201103L 941 template<
typename _Iterator,
typename _Sequence>
942 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
943 {
typedef _Iterator _Type; };
946 template<
typename _Iterator,
typename _Sequence>
948 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
949 {
return __it.base(); }
953 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS 954 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS 955 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS 956 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise...
ISO C++ entities toplevel namespace is std.
Base class that supports tracking of iterators that reference a sequence.
Forward iterators support a superset of input iterator operations.
_Safe_iterator operator++(int) noexcept
Iterator postincrement.
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
bool _M_dereferenceable() const
Is the iterator dereferenceable?
reference operator*() const noexcept
Iterator dereference.
_Safe_iterator() noexcept
_Safe_iterator & operator=(_Safe_iterator &&__x) noexcept
Move assignment.
_Safe_iterator(const _Safe_iterator &__x) noexcept
Copy construction.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_iterator(const _Safe_iterator< _MutableIterator, _Sequence, typename __gnu_cxx::__enable_if< _IsConstant::__value &&std::__are_same< _MutableIterator, _OtherIterator >::__value, _Category >::__type > &__x) noexcept
Converting constructor from a mutable iterator to a constant iterator.
void _M_attach(_Safe_sequence_base *__seq)
__gnu_cxx::__mutex & _M_get_mutex()
_Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
_Safe_iterator(_Safe_iterator &&__x) noexcept
Move construction.
GNU debug classes for public use.
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
Random-access iterators support a superset of bidirectional iterator operations.
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
_Safe_iterator & operator++() noexcept
Iterator preincrement.
_Safe_sequence_base * _M_sequence
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.
Basic functionality for a safe iterator.
pointer operator->() const noexcept
Iterator dereference.
_Safe_iterator(_Iterator __i, const _Safe_sequence_base *__seq) noexcept
Safe iterator construction from an unsafe iterator and its sequence.
Struct holding two objects of arbitrary type.
Bidirectional iterators support a superset of forward iterator operations.
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?
_Iterator & base() noexcept
Return the underlying iterator.
_Iterator __base(_Iterator __it)
void _M_attach_single(_Safe_sequence_base *__seq)
bool __valid_range(_InputIterator __first, _InputIterator __last, typename _Distance_traits< _InputIterator >::__type &__dist)
static constexpr bool _S_constant()
Determine if this is a constant iterator.
void _M_attach(_Safe_sequence_base *__seq, bool __constant)