29#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
30#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
38#if __cplusplus > 201703L
42#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
43 if (!std::__is_constant_evaluated()) { \
44 _GLIBCXX_DEBUG_VERIFY((!_Lhs._M_singular() && !_Rhs._M_singular()) \
45 || (_Lhs._M_value_initialized() \
46 && _Rhs._M_value_initialized()), \
47 _M_message(_BadMsgId) \
48 ._M_iterator(_Lhs, #_Lhs) \
49 ._M_iterator(_Rhs, #_Rhs)); \
50 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
51 _M_message(_DiffMsgId) \
52 ._M_iterator(_Lhs, #_Lhs) \
53 ._M_iterator(_Rhs, #_Rhs)); \
56#define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \
57 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \
58 __msg_compare_different)
60#define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \
61 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \
62 __msg_order_different)
64#define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \
65 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \
66 __msg_distance_different)
73 template<
typename _Sequence>
76 template<
typename _Iterator,
typename _Category>
81 template<
typename _Iterator,
typename _Category>
84 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
88 template<
typename _Sequence>
91 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
94 _S_size(
const _Sequence& __seq)
95 {
return std::make_pair(__seq.size(), __dp_exact); }
114 template<
typename _Iterator,
typename _Sequence,
typename _Category
120 typedef _Iterator _Iter_base;
126 typedef std::__are_same<
typename _Sequence::_Base::const_iterator,
129 typedef typename __gnu_cxx::__conditional_type<
130 _IsConstant::__value,
131 typename _Sequence::_Base::iterator,
132 typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
134 struct _Unchecked { };
140 if (!std::__is_constant_evaluated())
145 typedef _Iterator iterator_type;
146 typedef typename _Traits::iterator_category iterator_category;
147 typedef typename _Traits::value_type value_type;
148 typedef typename _Traits::difference_type difference_type;
149 typedef typename _Traits::reference reference;
150 typedef typename _Traits::pointer pointer;
152#if __cplusplus > 201703L && __cpp_lib_concepts
153 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
180 if (std::__is_constant_evaluated())
187 _M_message(__msg_init_copy_singular)
188 ._M_iterator(*
this,
"this")
189 ._M_iterator(__x,
"other"));
193#if __cplusplus >= 201103L
202 if (std::__is_constant_evaluated())
210 _M_message(__msg_init_copy_singular)
211 ._M_iterator(*
this,
"this")
212 ._M_iterator(__x,
"other"));
224 template<
typename _MutableIterator>
228 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
229 std::__are_same<_MutableIterator, _OtherIterator>::__value,
230 _Category>::__type>& __x)
232 : _Iter_base(__x.
base())
234 if (std::__is_constant_evaluated())
241 _M_message(__msg_init_const_singular)
242 ._M_iterator(*
this,
"this")
243 ._M_iterator(__x,
"other"));
254 if (std::__is_constant_evaluated())
264 _M_message(__msg_copy_singular)
265 ._M_iterator(*
this,
"this")
266 ._M_iterator(__x,
"other"));
284#if __cplusplus >= 201103L
293 if (std::__is_constant_evaluated())
301 _M_message(__msg_copy_singular)
302 ._M_iterator(*
this,
"this")
303 ._M_iterator(__x,
"other"));
322 __x.
base() = _Iterator();
336 if (!std::__is_constant_evaluated())
339 _M_message(__msg_bad_deref)
340 ._M_iterator(*
this,
"this"));
354 if (!std::__is_constant_evaluated())
357 _M_message(__msg_bad_deref)
358 ._M_iterator(*
this,
"this"));
360 return base().operator->();
372 if (std::__is_constant_evaluated())
379 _M_message(__msg_bad_inc)
380 ._M_iterator(*
this,
"this"));
394 if (!std::__is_constant_evaluated())
397 _M_message(__msg_bad_inc)
398 ._M_iterator(*
this,
"this"));
408 static _GLIBCXX_CONSTEXPR
bool
410 {
return _IsConstant::__value; }
417 base() _GLIBCXX_NOEXCEPT {
return *
this; }
421 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
428 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
452 return ++
__base != _M_get_sequence()->_M_base().end();
469 _M_can_advance(difference_type __n,
bool __strict =
false)
const;
472 template<
typename _Diff>
481 bool __check_dereferenceable =
true)
const;
484 typename __gnu_cxx::__conditional_type<
485 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
486 _M_get_sequence()
const
490 typename _Distance_traits<_Iterator>::__type
494 typename _Distance_traits<_Iterator>::__type
495 _M_get_distance_from_begin()
const;
498 typename _Distance_traits<_Iterator>::__type
499 _M_get_distance_to_end()
const;
505 {
return base() == _M_get_sequence()->_M_base().begin(); }
510 {
return base() == _M_get_sequence()->_M_base().end(); }
531 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
533 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
534 return __lhs.base() == __rhs.base();
537 template<
typename _IteR>
541 operator==(
const _Self& __lhs,
542 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
545 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
546 return __lhs.base() == __rhs.base();
549#if ! __cpp_lib_three_way_comparison
552 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
554 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
555 return __lhs.base() != __rhs.base();
558 template<
typename _IteR>
561 operator!=(
const _Self& __lhs,
562 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
565 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
566 return __lhs.base() != __rhs.base();
571 template<
typename _Iterator,
typename _Sequence>
572 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
573 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
579 typedef typename _Safe_base::_OtherIterator _OtherIterator;
581 typedef typename _Safe_base::_Unchecked _Unchecked;
585 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
586 : _Safe_base(__x, __unchecked)
604 : _Safe_base(__i, __seq)
615#if __cplusplus >= 201103L
625 template<
typename _MutableIterator>
629 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
630 std::__are_same<_MutableIterator, _OtherIterator>::__value,
636#if __cplusplus >= 201103L
649 _Safe_base::operator=(__x);
663 _Safe_base::operator++();
675 _M_message(__msg_bad_inc)
676 ._M_iterator(*
this,
"this"));
689 operator--() _GLIBCXX_NOEXCEPT
691 if (std::__is_constant_evaluated())
697 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
698 _M_message(__msg_bad_dec)
699 ._M_iterator(*
this,
"this"));
710 operator--(
int) _GLIBCXX_NOEXCEPT
712 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
713 _M_message(__msg_bad_dec)
714 ._M_iterator(*
this,
"this"));
724 _M_decrementable()
const
728 template<
typename _Iterator,
typename _Sequence>
729 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
730 :
public _Safe_iterator<_Iterator, _Sequence,
731 std::bidirectional_iterator_tag>
735 typedef typename _Safe_base::_OtherIterator _OtherIterator;
737 typedef typename _Safe_base::_Self _Self;
741 typedef typename _Safe_base::_Unchecked _Unchecked;
745 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
746 : _Safe_base(__x, __unchecked)
750 typedef typename _Safe_base::difference_type difference_type;
751 typedef typename _Safe_base::reference reference;
767 : _Safe_base(__i, __seq)
778#if __cplusplus >= 201103L
787 template<
typename _MutableIterator>
791 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
792 std::__are_same<_MutableIterator, _OtherIterator>::__value,
798#if __cplusplus >= 201103L
811 _Safe_base::operator=(__x);
831 _Safe_base::operator++();
843 if (!std::__is_constant_evaluated())
846 _M_message(__msg_bad_inc)
847 ._M_iterator(*
this,
"this"));
861 operator--() _GLIBCXX_NOEXCEPT
863 _Safe_base::operator--();
873 operator--(
int) _GLIBCXX_NOEXCEPT
875 if (!std::__is_constant_evaluated())
877 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
878 _M_message(__msg_bad_dec)
879 ._M_iterator(*
this,
"this"));
890 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
892 if (!std::__is_constant_evaluated())
894 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
895 && this->_M_can_advance(__n + 1),
896 _M_message(__msg_iter_subscript_oob)
897 ._M_iterator(*this)._M_integer(__n));
899 return this->
base()[__n];
904 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
906 if (std::__is_constant_evaluated())
912 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
913 _M_message(__msg_advance_oob)
914 ._M_iterator(*this)._M_integer(__n));
922 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
924 if (std::__is_constant_evaluated())
930 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
931 _M_message(__msg_retreat_oob)
932 ._M_iterator(*this)._M_integer(__n));
938#if __cpp_lib_three_way_comparison
942 operator<=>(
const _Self& __lhs,
const _Self& __rhs)
noexcept
944 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
945 return __lhs.base() <=> __rhs.base();
951 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
953 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
954 return __lhs.base() <=> __rhs.base();
959 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
961 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
962 return __lhs.base() < __rhs.base();
967 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
969 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
970 return __lhs.base() < __rhs.base();
975 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
977 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
978 return __lhs.base() <= __rhs.base();
983 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
985 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
986 return __lhs.base() <= __rhs.base();
991 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
993 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
994 return __lhs.base() > __rhs.base();
999 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1001 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1002 return __lhs.base() > __rhs.base();
1007 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1009 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1010 return __lhs.base() >= __rhs.base();
1015 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1017 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1018 return __lhs.base() >= __rhs.base();
1027 _GLIBCXX20_CONSTEXPR
1028 friend difference_type
1029 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1031 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
1032 return __lhs.base() - __rhs.base();
1036 _GLIBCXX20_CONSTEXPR
1037 friend difference_type
1038 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1040 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
1041 return __lhs.base() - __rhs.base();
1045 _GLIBCXX20_CONSTEXPR
1047 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
1049 if (!std::__is_constant_evaluated())
1051 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
1052 _M_message(__msg_advance_oob)
1053 ._M_iterator(__x)._M_integer(__n));
1059 _GLIBCXX20_CONSTEXPR
1061 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
1063 if (!std::__is_constant_evaluated())
1065 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
1066 _M_message(__msg_advance_oob)
1067 ._M_iterator(__x)._M_integer(__n));
1073 _GLIBCXX20_CONSTEXPR
1075 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
1077 if (!std::__is_constant_evaluated())
1079 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
1080 _M_message(__msg_retreat_oob)
1081 ._M_iterator(__x)._M_integer(__n));
1088 template<
typename _Iterator,
typename _Sequence,
typename _Category>
1091 _Category>& __first,
1095 {
return __first._M_valid_range(__last, __dist); }
1097 template<
typename _Iterator,
typename _Sequence,
typename _Category>
1100 _Category>& __first,
1101 const _Safe_iterator<_Iterator, _Sequence,
1104 typename _Distance_traits<_Iterator>::__type __dist;
1105 return __first._M_valid_range(__last, __dist);
1108 template<
typename _Iterator,
typename _Sequence,
typename _Category,
1111 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
1113 {
return __it._M_can_advance(__n); }
1115 template<
typename _Iterator,
typename _Sequence,
typename _Category,
1118 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
1121 {
return __it._M_can_advance(__dist, __way); }
1123 template<
typename _Iterator,
typename _Sequence>
1125 __base(
const _Safe_iterator<_Iterator, _Sequence,
1127 {
return __it.base(); }
1129#if __cplusplus < 201103L
1130 template<
typename _Iterator,
typename _Sequence>
1131 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
1132 {
typedef _Iterator _Type; };
1135 template<
typename _Iterator,
typename _Sequence>
1137 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
1138 {
return __it.base(); }
1142#if __cplusplus >= 201103L && __cplusplus <= 201703L
1143namespace std _GLIBCXX_VISIBILITY(default)
1145_GLIBCXX_BEGIN_NAMESPACE_VERSION
1147 template<
typename _Iterator,
typename _Container,
typename _Sequence>
1150 __gnu_cxx::__normal_iterator<_Iterator, _Container>,
1151 _Sequence>& __it)
noexcept
1152 ->
decltype(std::__to_address(__it.base().base()))
1153 {
return std::__to_address(__it.base().base()); }
1155_GLIBCXX_END_NAMESPACE_VERSION
1159#undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
1160#undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
1161#undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
1162#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
ISO C++ entities toplevel namespace is std.
GNU debug classes for public use.
constexpr bool __valid_range(_InputIterator __first, _InputIterator __last, typename _Distance_traits< _InputIterator >::__type &__dist)
constexpr _Iterator __base(_Iterator __it)
bool _M_incrementable() const
Is the iterator incrementable?
constexpr _Iterator & base() noexcept
Return the underlying iterator.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
constexpr bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
constexpr _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_single(_Safe_sequence_base *__seq)
constexpr _Safe_iterator & operator++() noexcept
Iterator preincrement.
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
constexpr _Safe_iterator & operator=(_Safe_iterator &&__x) noexcept
Move assignment.
constexpr _Safe_iterator(_Iterator __i, const _Safe_sequence_base *__seq) noexcept
Safe iterator construction from an unsafe iterator and its sequence.
constexpr pointer operator->() const noexcept
Iterator dereference.
constexpr _Safe_iterator(const _Safe_iterator &__x) noexcept
Copy construction.
constexpr reference operator*() const noexcept
Iterator dereference.
constexpr _Safe_iterator() noexcept
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise?
bool _M_value_initialized() const
Is the iterator value-initialized?
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
constexpr _Safe_iterator operator++(int) noexcept
Iterator postincrement.
void _M_attach(_Safe_sequence_base *__seq)
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?
constexpr _Safe_iterator(_Safe_iterator &&__x) noexcept
Move construction.
static constexpr bool _S_constant()
Determine if this is a constant iterator.
constexpr _Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
Traits class for iterators.
Struct holding two objects of arbitrary type.
Forward iterators support a superset of input iterator operations.
Bidirectional iterators support a superset of forward iterator operations.
Random-access iterators support a superset of bidirectional iterator operations.
Basic functionality for a safe iterator.
_Safe_sequence_base * _M_sequence
__gnu_cxx::__mutex & _M_get_mutex()
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
Base class that supports tracking of iterators that reference a sequence.
unsigned int _M_version
The container version number. This number may never be 0.