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)
74 #if __cplusplus >= 202002L && __cpp_constexpr < 202110L
75 # define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN [&]() -> void
76 # define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END ();
78 # define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN
79 # define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
87 template<
typename _Sequence>
90 template<
typename _Iterator,
typename _Category>
95 template<
typename _Iterator,
typename _Category>
98 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
102 template<
typename _Sequence>
105 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
108 _S_size(
const _Sequence& __seq)
109 {
return std::make_pair(__seq.size(), __dp_exact); }
128 template<
typename _Iterator,
typename _Sequence,
typename _Category
134 typedef _Iterator _Iter_base;
140 typedef std::__are_same<
typename _Sequence::_Base::const_iterator,
141 _Iterator> _IsConstant;
143 typedef typename __gnu_cxx::__conditional_type<
144 _IsConstant::__value,
145 typename _Sequence::_Base::iterator,
146 typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
148 struct _Unchecked { };
152 : _Iter_base(__x.base()), _Safe_base()
154 if (!std::__is_constant_evaluated())
159 typedef _Iterator iterator_type;
160 typedef typename _Traits::iterator_category iterator_category;
161 typedef typename _Traits::value_type value_type;
162 typedef typename _Traits::difference_type difference_type;
163 typedef typename _Traits::reference reference;
164 typedef typename _Traits::pointer pointer;
166 #if __cplusplus > 201703L && __cpp_lib_concepts
167 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
194 if (std::__is_constant_evaluated())
199 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
200 || __x._M_value_initialized(),
201 _M_message(__msg_init_copy_singular)
202 ._M_iterator(*
this,
"this")
203 ._M_iterator(__x,
"other"));
207 #if __cplusplus >= 201103L
216 if (std::__is_constant_evaluated())
222 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
223 || __x._M_value_initialized(),
224 _M_message(__msg_init_copy_singular)
225 ._M_iterator(*
this,
"this")
226 ._M_iterator(__x,
"other"));
229 std::swap(
base(), __x.base());
238 template<
typename _MutableIterator>
242 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
243 std::__are_same<_MutableIterator, _OtherIterator>::__value,
244 _Category>::__type>& __x)
246 : _Iter_base(__x.base())
248 if (std::__is_constant_evaluated())
253 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
254 || __x._M_value_initialized(),
255 _M_message(__msg_init_const_singular)
256 ._M_iterator(*
this,
"this")
257 ._M_iterator(__x,
"other"));
268 if (std::__is_constant_evaluated())
276 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
277 || __x._M_value_initialized(),
278 _M_message(__msg_copy_singular)
279 ._M_iterator(*
this,
"this")
280 ._M_iterator(__x,
"other"));
282 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
283 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
286 _M_version = __x._M_sequence->_M_version;
287 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
298 #if __cplusplus >= 201103L
307 if (std::__is_constant_evaluated())
313 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
314 || __x._M_value_initialized(),
315 _M_message(__msg_copy_singular)
316 ._M_iterator(*
this,
"this")
317 ._M_iterator(__x,
"other"));
322 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
323 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
326 _M_version = __x._M_sequence->_M_version;
327 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
336 __x.base() = _Iterator();
350 if (!std::__is_constant_evaluated())
353 _M_message(__msg_bad_deref)
354 ._M_iterator(*
this,
"this"));
368 if (!std::__is_constant_evaluated())
371 _M_message(__msg_bad_deref)
372 ._M_iterator(*
this,
"this"));
374 return base().operator->();
386 if (std::__is_constant_evaluated())
393 _M_message(__msg_bad_inc)
394 ._M_iterator(*
this,
"this"));
395 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
398 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
410 if (!std::__is_constant_evaluated())
413 _M_message(__msg_bad_inc)
414 ._M_iterator(*
this,
"this"));
424 static _GLIBCXX_CONSTEXPR
bool
426 {
return _IsConstant::__value; }
433 base() _GLIBCXX_NOEXCEPT {
return *
this; }
437 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
444 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
468 return ++
__base != _M_get_sequence()->_M_base().end();
476 {
return !this->_M_singular() && !
_M_is_end(); }
481 {
return _M_version == 0 &&
base() == _Iter_base(); }
485 _M_can_advance(difference_type __n,
bool __strict =
false)
const;
488 template<
typename _Diff>
497 bool __check_dereferenceable =
true)
const;
500 typename __gnu_cxx::__conditional_type<
501 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
502 _M_get_sequence()
const
507 return static_cast<_Sequence*
>
512 typename _Distance_traits<_Iterator>::__type
516 typename _Distance_traits<_Iterator>::__type
517 _M_get_distance_from_begin()
const;
520 typename _Distance_traits<_Iterator>::__type
521 _M_get_distance_to_end()
const;
527 {
return base() == _M_get_sequence()->_M_base().begin(); }
532 {
return base() == _M_get_sequence()->_M_base().end(); }
553 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
555 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
556 return __lhs.base() == __rhs.base();
559 template<
typename _IteR>
563 operator==(
const _Self& __lhs,
564 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
567 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
568 return __lhs.base() == __rhs.base();
571 #if ! __cpp_lib_three_way_comparison
574 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
576 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
577 return __lhs.base() != __rhs.base();
580 template<
typename _IteR>
583 operator!=(
const _Self& __lhs,
584 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
587 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
588 return __lhs.base() != __rhs.base();
590 #endif // three-way comparison
593 template<
typename _Iterator,
typename _Sequence>
594 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
595 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
601 typedef typename _Safe_base::_OtherIterator _OtherIterator;
603 typedef typename _Safe_base::_Unchecked _Unchecked;
607 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
608 : _Safe_base(__x, __unchecked)
626 : _Safe_base(__i, __seq)
637 #if __cplusplus >= 201103L
647 template<
typename _MutableIterator>
651 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
652 std::__are_same<_MutableIterator, _OtherIterator>::__value,
658 #if __cplusplus >= 201103L
671 _Safe_base::operator=(__x);
685 _Safe_base::operator++();
697 _M_message(__msg_bad_inc)
698 ._M_iterator(*
this,
"this"));
711 operator--() _GLIBCXX_NOEXCEPT
713 if (std::__is_constant_evaluated())
719 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
720 _M_message(__msg_bad_dec)
721 ._M_iterator(*
this,
"this"));
722 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
725 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
734 operator--(
int) _GLIBCXX_NOEXCEPT
736 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
737 _M_message(__msg_bad_dec)
738 ._M_iterator(*
this,
"this"));
748 _M_decrementable()
const
749 {
return !this->_M_singular() && !this->
_M_is_begin(); }
752 template<
typename _Iterator,
typename _Sequence>
753 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
754 :
public _Safe_iterator<_Iterator, _Sequence,
755 std::bidirectional_iterator_tag>
759 typedef typename _Safe_base::_OtherIterator _OtherIterator;
761 typedef typename _Safe_base::_Self _Self;
765 typedef typename _Safe_base::_Unchecked _Unchecked;
769 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
770 : _Safe_base(__x, __unchecked)
774 typedef typename _Safe_base::difference_type difference_type;
775 typedef typename _Safe_base::reference reference;
791 : _Safe_base(__i, __seq)
802 #if __cplusplus >= 201103L
811 template<
typename _MutableIterator>
815 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
816 std::__are_same<_MutableIterator, _OtherIterator>::__value,
822 #if __cplusplus >= 201103L
835 _Safe_base::operator=(__x);
855 _Safe_base::operator++();
867 if (!std::__is_constant_evaluated())
870 _M_message(__msg_bad_inc)
871 ._M_iterator(*
this,
"this"));
885 operator--() _GLIBCXX_NOEXCEPT
887 _Safe_base::operator--();
897 operator--(
int) _GLIBCXX_NOEXCEPT
899 if (!std::__is_constant_evaluated())
901 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
902 _M_message(__msg_bad_dec)
903 ._M_iterator(*
this,
"this"));
914 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
916 if (!std::__is_constant_evaluated())
918 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
919 && this->_M_can_advance(__n + 1),
920 _M_message(__msg_iter_subscript_oob)
921 ._M_iterator(*this)._M_integer(__n));
923 return this->
base()[__n];
928 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
930 if (std::__is_constant_evaluated())
936 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
937 _M_message(__msg_advance_oob)
938 ._M_iterator(*this)._M_integer(__n));
939 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
942 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
948 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
950 if (std::__is_constant_evaluated())
956 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
957 _M_message(__msg_retreat_oob)
958 ._M_iterator(*this)._M_integer(__n));
959 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
962 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
966 #if __cpp_lib_three_way_comparison
970 operator<=>(
const _Self& __lhs,
const _Self& __rhs) noexcept
972 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
973 return __lhs.base() <=> __rhs.base();
979 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
981 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
982 return __lhs.base() <=> __rhs.base();
987 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
989 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
990 return __lhs.base() < __rhs.base();
995 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
997 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
998 return __lhs.base() < __rhs.base();
1003 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1005 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1006 return __lhs.base() <= __rhs.base();
1011 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1013 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1014 return __lhs.base() <= __rhs.base();
1019 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1021 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1022 return __lhs.base() > __rhs.base();
1027 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1029 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1030 return __lhs.base() > __rhs.base();
1035 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1037 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1038 return __lhs.base() >= __rhs.base();
1043 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1045 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1046 return __lhs.base() >= __rhs.base();
1048 #endif // three-way comparison
1055 _GLIBCXX20_CONSTEXPR
1056 friend difference_type
1057 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1059 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
1060 return __lhs.base() - __rhs.base();
1064 _GLIBCXX20_CONSTEXPR
1065 friend difference_type
1066 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1068 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
1069 return __lhs.base() - __rhs.base();
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_advance_oob)
1081 ._M_iterator(__x)._M_integer(__n));
1087 _GLIBCXX20_CONSTEXPR
1089 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
1091 if (!std::__is_constant_evaluated())
1093 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
1094 _M_message(__msg_advance_oob)
1095 ._M_iterator(__x)._M_integer(__n));
1101 _GLIBCXX20_CONSTEXPR
1103 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
1105 if (!std::__is_constant_evaluated())
1107 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
1108 _M_message(__msg_retreat_oob)
1109 ._M_iterator(__x)._M_integer(__n));
1116 template<
typename _Iterator,
typename _Sequence,
typename _Category>
1117 _GLIBCXX20_CONSTEXPR
1120 _Category>& __first,
1125 if (std::__is_constant_evaluated())
1128 return __first._M_valid_range(__last, __dist);
1131 template<
typename _Iterator,
typename _Sequence,
typename _Category>
1132 _GLIBCXX20_CONSTEXPR
1134 __valid_range(
const _Safe_iterator<_Iterator, _Sequence,
1135 _Category>& __first,
1136 const _Safe_iterator<_Iterator, _Sequence,
1139 if (std::__is_constant_evaluated())
1142 typename _Distance_traits<_Iterator>::__type __dist;
1143 return __first._M_valid_range(__last, __dist);
1146 template<
typename _Iterator,
typename _Sequence,
typename _Category,
1148 _GLIBCXX20_CONSTEXPR
1150 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
1153 if (std::__is_constant_evaluated())
1156 return __it._M_can_advance(__n);
1159 template<
typename _Iterator,
typename _Sequence,
typename _Category,
1161 _GLIBCXX20_CONSTEXPR
1163 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
1167 if (std::__is_constant_evaluated())
1170 return __it._M_can_advance(__dist, __way);
1173 template<
typename _Iterator,
typename _Sequence>
1174 _GLIBCXX20_CONSTEXPR _Iterator
1175 __base(
const _Safe_iterator<_Iterator, _Sequence,
1177 {
return __it.base(); }
1179 #if __cplusplus < 201103L
1180 template<
typename _Iterator,
typename _Sequence>
1181 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
1182 {
typedef _Iterator _Type; };
1185 template<
typename _Iterator,
typename _Sequence>
1187 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
1188 {
return __it.base(); }
1192 #undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
1193 #undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN
1194 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
1195 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
1196 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
1197 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS