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
503 {
return static_cast<_Sequence*
>(_M_sequence); }
506 typename _Distance_traits<_Iterator>::__type
510 typename _Distance_traits<_Iterator>::__type
511 _M_get_distance_from_begin()
const;
514 typename _Distance_traits<_Iterator>::__type
515 _M_get_distance_to_end()
const;
521 {
return base() == _M_get_sequence()->_M_base().begin(); }
526 {
return base() == _M_get_sequence()->_M_base().end(); }
547 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
549 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
550 return __lhs.base() == __rhs.base();
553 template<
typename _IteR>
557 operator==(
const _Self& __lhs,
558 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
561 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
562 return __lhs.base() == __rhs.base();
565 #if ! __cpp_lib_three_way_comparison
568 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
570 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
571 return __lhs.base() != __rhs.base();
574 template<
typename _IteR>
577 operator!=(
const _Self& __lhs,
578 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
581 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
582 return __lhs.base() != __rhs.base();
584 #endif // three-way comparison
587 template<
typename _Iterator,
typename _Sequence>
588 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
589 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
595 typedef typename _Safe_base::_OtherIterator _OtherIterator;
597 typedef typename _Safe_base::_Unchecked _Unchecked;
601 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
602 : _Safe_base(__x, __unchecked)
620 : _Safe_base(__i, __seq)
631 #if __cplusplus >= 201103L
641 template<
typename _MutableIterator>
645 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
646 std::__are_same<_MutableIterator, _OtherIterator>::__value,
652 #if __cplusplus >= 201103L
665 _Safe_base::operator=(__x);
679 _Safe_base::operator++();
691 _M_message(__msg_bad_inc)
692 ._M_iterator(*
this,
"this"));
705 operator--() _GLIBCXX_NOEXCEPT
707 if (std::__is_constant_evaluated())
713 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
714 _M_message(__msg_bad_dec)
715 ._M_iterator(*
this,
"this"));
716 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
719 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
728 operator--(
int) _GLIBCXX_NOEXCEPT
730 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
731 _M_message(__msg_bad_dec)
732 ._M_iterator(*
this,
"this"));
742 _M_decrementable()
const
743 {
return !this->_M_singular() && !this->
_M_is_begin(); }
746 template<
typename _Iterator,
typename _Sequence>
747 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
748 :
public _Safe_iterator<_Iterator, _Sequence,
749 std::bidirectional_iterator_tag>
753 typedef typename _Safe_base::_OtherIterator _OtherIterator;
755 typedef typename _Safe_base::_Self _Self;
759 typedef typename _Safe_base::_Unchecked _Unchecked;
763 _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
764 : _Safe_base(__x, __unchecked)
768 typedef typename _Safe_base::difference_type difference_type;
769 typedef typename _Safe_base::reference reference;
785 : _Safe_base(__i, __seq)
796 #if __cplusplus >= 201103L
805 template<
typename _MutableIterator>
809 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
810 std::__are_same<_MutableIterator, _OtherIterator>::__value,
816 #if __cplusplus >= 201103L
829 _Safe_base::operator=(__x);
849 _Safe_base::operator++();
861 if (!std::__is_constant_evaluated())
864 _M_message(__msg_bad_inc)
865 ._M_iterator(*
this,
"this"));
879 operator--() _GLIBCXX_NOEXCEPT
881 _Safe_base::operator--();
891 operator--(
int) _GLIBCXX_NOEXCEPT
893 if (!std::__is_constant_evaluated())
895 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
896 _M_message(__msg_bad_dec)
897 ._M_iterator(*
this,
"this"));
908 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
910 if (!std::__is_constant_evaluated())
912 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
913 && this->_M_can_advance(__n + 1),
914 _M_message(__msg_iter_subscript_oob)
915 ._M_iterator(*this)._M_integer(__n));
917 return this->
base()[__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_advance_oob)
932 ._M_iterator(*this)._M_integer(__n));
933 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
936 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
942 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
944 if (std::__is_constant_evaluated())
950 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
951 _M_message(__msg_retreat_oob)
952 ._M_iterator(*this)._M_integer(__n));
953 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
956 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
960 #if __cpp_lib_three_way_comparison
964 operator<=>(
const _Self& __lhs,
const _Self& __rhs) noexcept
966 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
967 return __lhs.base() <=> __rhs.base();
973 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
975 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
976 return __lhs.base() <=> __rhs.base();
981 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
983 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
984 return __lhs.base() < __rhs.base();
989 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
991 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
992 return __lhs.base() < __rhs.base();
997 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
999 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1000 return __lhs.base() <= __rhs.base();
1005 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1007 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1008 return __lhs.base() <= __rhs.base();
1013 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1015 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1016 return __lhs.base() > __rhs.base();
1021 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1023 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1024 return __lhs.base() > __rhs.base();
1029 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1031 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1032 return __lhs.base() >= __rhs.base();
1037 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1039 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
1040 return __lhs.base() >= __rhs.base();
1042 #endif // three-way comparison
1049 _GLIBCXX20_CONSTEXPR
1050 friend difference_type
1051 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
1053 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
1054 return __lhs.base() - __rhs.base();
1058 _GLIBCXX20_CONSTEXPR
1059 friend difference_type
1060 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
1062 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
1063 return __lhs.base() - __rhs.base();
1067 _GLIBCXX20_CONSTEXPR
1069 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
1071 if (!std::__is_constant_evaluated())
1073 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
1074 _M_message(__msg_advance_oob)
1075 ._M_iterator(__x)._M_integer(__n));
1081 _GLIBCXX20_CONSTEXPR
1083 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
1085 if (!std::__is_constant_evaluated())
1087 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
1088 _M_message(__msg_advance_oob)
1089 ._M_iterator(__x)._M_integer(__n));
1095 _GLIBCXX20_CONSTEXPR
1097 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
1099 if (!std::__is_constant_evaluated())
1101 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
1102 _M_message(__msg_retreat_oob)
1103 ._M_iterator(__x)._M_integer(__n));
1110 template<
typename _Iterator,
typename _Sequence,
typename _Category>
1113 _Category>& __first,
1117 {
return __first._M_valid_range(__last, __dist); }
1119 template<
typename _Iterator,
typename _Sequence,
typename _Category>
1122 _Category>& __first,
1123 const _Safe_iterator<_Iterator, _Sequence,
1126 typename _Distance_traits<_Iterator>::__type __dist;
1127 return __first._M_valid_range(__last, __dist);
1130 template<
typename _Iterator,
typename _Sequence,
typename _Category,
1133 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
1135 {
return __it._M_can_advance(__n); }
1137 template<
typename _Iterator,
typename _Sequence,
typename _Category,
1140 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
1143 {
return __it._M_can_advance(__dist, __way); }
1145 template<
typename _Iterator,
typename _Sequence>
1147 __base(
const _Safe_iterator<_Iterator, _Sequence,
1149 {
return __it.base(); }
1151 #if __cplusplus < 201103L
1152 template<
typename _Iterator,
typename _Sequence>
1153 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
1154 {
typedef _Iterator _Type; };
1157 template<
typename _Iterator,
typename _Sequence>
1159 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
1160 {
return __it.base(); }
1164 #undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
1165 #undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN
1166 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
1167 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
1168 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
1169 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS