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)
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 { };
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())
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())
224 _M_message(__msg_init_copy_singular)
225 ._M_iterator(*
this,
"this")
226 ._M_iterator(__x,
"other"));
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())
255 _M_message(__msg_init_const_singular)
256 ._M_iterator(*
this,
"this")
257 ._M_iterator(__x,
"other"));
268 if (std::__is_constant_evaluated())
278 _M_message(__msg_copy_singular)
279 ._M_iterator(*
this,
"this")
280 ._M_iterator(__x,
"other"));
283 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
287 } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
298#if __cplusplus >= 201103L
307 if (std::__is_constant_evaluated())
315 _M_message(__msg_copy_singular)
316 ._M_iterator(*
this,
"this")
317 ._M_iterator(__x,
"other"));
323 _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
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();
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
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,
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,
581 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
582 return __lhs.base() != __rhs.base();
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
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();
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#if __cplusplus >= 201103L && __cplusplus <= 201703L
1165namespace std _GLIBCXX_VISIBILITY(default)
1167_GLIBCXX_BEGIN_NAMESPACE_VERSION
1169 template<
typename _Iterator,
typename _Container,
typename _Sequence>
1172 __gnu_cxx::__normal_iterator<_Iterator, _Container>,
1173 _Sequence>& __it)
noexcept
1174 ->
decltype(std::__to_address(__it.base().base()))
1175 {
return std::__to_address(__it.base().base()); }
1177_GLIBCXX_END_NAMESPACE_VERSION
1181#undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
1182#undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN
1183#undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
1184#undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
1185#undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
1186#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 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.
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.