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 _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \
44 _M_message(_BadMsgId) \
45 ._M_iterator(_Lhs, #_Lhs) \
46 ._M_iterator(_Rhs, #_Rhs)); \
47 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
48 _M_message(_DiffMsgId) \
49 ._M_iterator(_Lhs, #_Lhs) \
50 ._M_iterator(_Rhs, #_Rhs))
52 #define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \
53 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \
54 __msg_compare_different)
56 #define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \
57 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \
58 __msg_order_different)
60 #define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \
61 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \
62 __msg_distance_different)
69 template<
typename _Sequence>
72 template<
typename _Iterator,
typename _Category>
77 template<
typename _Iterator,
typename _Category>
80 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
84 template<
typename _Sequence>
87 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
90 _S_size(
const _Sequence& __seq)
91 {
return std::make_pair(__seq.size(), __dp_exact); }
110 template<
typename _Iterator,
typename _Sequence,
typename _Category
116 typedef _Iterator _Iter_base;
122 typedef std::__are_same<
typename _Sequence::_Base::const_iterator,
123 _Iterator> _IsConstant;
125 typedef typename __gnu_cxx::__conditional_type<
126 _IsConstant::__value,
127 typename _Sequence::_Base::iterator,
128 typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
130 struct _Attach_single
133 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
139 typedef _Iterator iterator_type;
140 typedef typename _Traits::iterator_category iterator_category;
141 typedef typename _Traits::value_type value_type;
142 typedef typename _Traits::difference_type difference_type;
143 typedef typename _Traits::reference reference;
144 typedef typename _Traits::pointer pointer;
146 #if __cplusplus > 201703L && __cpp_lib_concepts
147 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
164 _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
165 _M_message(__msg_init_singular)
166 ._M_iterator(*
this,
"this"));
173 : _Iter_base(__x.base())
177 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
178 || __x.base() == _Iterator(),
179 _M_message(__msg_init_copy_singular)
180 ._M_iterator(*
this,
"this")
181 ._M_iterator(__x,
"other"));
185 #if __cplusplus >= 201103L
193 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
194 || __x.base() == _Iterator(),
195 _M_message(__msg_init_copy_singular)
196 ._M_iterator(*
this,
"this")
197 ._M_iterator(__x,
"other"));
200 std::swap(
base(), __x.base());
209 template<
typename _MutableIterator>
212 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
213 std::__are_same<_MutableIterator, _OtherIterator>::__value,
214 _Category>::__type>& __x)
216 : _Iter_base(__x.base())
220 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
221 || __x.base() == _MutableIterator(),
222 _M_message(__msg_init_const_singular)
223 ._M_iterator(*
this,
"this")
224 ._M_iterator(__x,
"other"));
236 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
237 || __x.base() == _Iterator(),
238 _M_message(__msg_copy_singular)
239 ._M_iterator(*
this,
"this")
240 ._M_iterator(__x,
"other"));
242 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
246 _M_version = __x._M_sequence->_M_version;
258 #if __cplusplus >= 201103L
266 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
267 _M_message(__msg_self_move_assign)
268 ._M_iterator(*
this,
"this"));
269 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
270 || __x.base() == _Iterator(),
271 _M_message(__msg_copy_singular)
272 ._M_iterator(*
this,
"this")
273 ._M_iterator(__x,
"other"));
275 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
279 _M_version = __x._M_sequence->_M_version;
289 __x.base() = _Iterator();
302 _M_message(__msg_bad_deref)
303 ._M_iterator(*
this,
"this"));
315 _M_message(__msg_bad_deref)
316 ._M_iterator(*
this,
"this"));
317 return base().operator->();
329 _M_message(__msg_bad_inc)
330 ._M_iterator(*
this,
"this"));
344 _M_message(__msg_bad_inc)
345 ._M_iterator(*
this,
"this"));
353 static _GLIBCXX_CONSTEXPR
bool
355 {
return _IsConstant::__value; }
361 base() _GLIBCXX_NOEXCEPT {
return *
this; }
364 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
370 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
394 return ++
__base != _M_get_sequence()->_M_base().end();
402 {
return !this->_M_singular() && !
_M_is_end(); }
406 _M_can_advance(difference_type __n,
bool __strict =
false)
const;
412 bool __check_dereferenceable =
true)
const;
415 typename __gnu_cxx::__conditional_type<
416 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
417 _M_get_sequence()
const
418 {
return static_cast<_Sequence*
>(_M_sequence); }
421 typename _Distance_traits<_Iterator>::__type
425 typename _Distance_traits<_Iterator>::__type
426 _M_get_distance_from_begin()
const;
429 typename _Distance_traits<_Iterator>::__type
430 _M_get_distance_to_end()
const;
435 {
return base() == _M_get_sequence()->_M_base().begin(); }
440 {
return base() == _M_get_sequence()->_M_base().end(); }
459 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
461 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
462 return __lhs.base() == __rhs.base();
465 template<
typename _IteR>
467 operator==(
const _Self& __lhs,
468 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
471 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
472 return __lhs.base() == __rhs.base();
475 #if ! __cpp_lib_three_way_comparison
477 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
479 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
480 return __lhs.base() != __rhs.base();
483 template<
typename _IteR>
485 operator!=(
const _Self& __lhs,
486 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
489 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
490 return __lhs.base() != __rhs.base();
492 #endif // three-way comparison
495 template<
typename _Iterator,
typename _Sequence>
496 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
497 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
503 typedef typename _Safe_base::_OtherIterator _OtherIterator;
504 typedef typename _Safe_base::_Attach_single _Attach_single;
506 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
508 : _Safe_base(__i, __seq, _Attach_single())
524 : _Safe_base(__i, __seq)
534 #if __cplusplus >= 201103L
543 template<
typename _MutableIterator>
546 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
547 std::__are_same<_MutableIterator, _OtherIterator>::__value,
553 #if __cplusplus >= 201103L
566 _Safe_base::operator=(__x);
579 _Safe_base::operator++();
591 _M_message(__msg_bad_inc)
592 ._M_iterator(*
this,
"this"));
604 operator--() _GLIBCXX_NOEXCEPT
606 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
607 _M_message(__msg_bad_dec)
608 ._M_iterator(*
this,
"this"));
619 operator--(
int) _GLIBCXX_NOEXCEPT
621 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
622 _M_message(__msg_bad_dec)
623 ._M_iterator(*
this,
"this"));
633 _M_decrementable()
const
634 {
return !this->_M_singular() && !this->
_M_is_begin(); }
637 template<
typename _Iterator,
typename _Sequence>
638 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
639 :
public _Safe_iterator<_Iterator, _Sequence,
640 std::bidirectional_iterator_tag>
644 typedef typename _Safe_base::_OtherIterator _OtherIterator;
646 typedef typename _Safe_base::_Self _Self;
650 typedef typename _Safe_base::_Attach_single _Attach_single;
652 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
654 : _Safe_base(__i, __seq, _Attach_single())
658 typedef typename _Safe_base::difference_type difference_type;
659 typedef typename _Safe_base::reference reference;
673 : _Safe_base(__i, __seq)
683 #if __cplusplus >= 201103L
692 template<
typename _MutableIterator>
695 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
696 std::__are_same<_MutableIterator, _OtherIterator>::__value,
702 #if __cplusplus >= 201103L
715 _Safe_base::operator=(__x);
734 _Safe_base::operator++();
746 _M_message(__msg_bad_inc)
747 ._M_iterator(*
this,
"this"));
759 operator--() _GLIBCXX_NOEXCEPT
761 _Safe_base::operator--();
770 operator--(
int) _GLIBCXX_NOEXCEPT
772 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
773 _M_message(__msg_bad_dec)
774 ._M_iterator(*
this,
"this"));
782 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
784 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
785 && this->_M_can_advance(__n + 1),
786 _M_message(__msg_iter_subscript_oob)
787 ._M_iterator(*this)._M_integer(__n));
788 return this->
base()[__n];
792 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
794 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
795 _M_message(__msg_advance_oob)
796 ._M_iterator(*this)._M_integer(__n));
803 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
805 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
806 _M_message(__msg_retreat_oob)
807 ._M_iterator(*this)._M_integer(__n));
813 #if __cpp_lib_three_way_comparison
815 operator<=>(
const _Self& __lhs,
const _Self& __rhs) noexcept
817 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
818 return __lhs.base() <=> __rhs.base();
822 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
824 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
825 return __lhs.base() <=> __rhs.base();
829 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
831 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
832 return __lhs.base() < __rhs.base();
836 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
838 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
839 return __lhs.base() < __rhs.base();
843 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
845 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
846 return __lhs.base() <= __rhs.base();
850 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
852 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
853 return __lhs.base() <= __rhs.base();
857 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
859 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
860 return __lhs.base() > __rhs.base();
864 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
866 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
867 return __lhs.base() > __rhs.base();
871 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
873 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
874 return __lhs.base() >= __rhs.base();
878 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
880 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
881 return __lhs.base() >= __rhs.base();
883 #endif // three-way comparison
889 friend difference_type
890 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
892 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
893 return __lhs.base() - __rhs.base();
896 friend difference_type
897 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
899 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
900 return __lhs.base() - __rhs.base();
904 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
906 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
907 _M_message(__msg_advance_oob)
908 ._M_iterator(__x)._M_integer(__n));
913 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
915 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
916 _M_message(__msg_advance_oob)
917 ._M_iterator(__x)._M_integer(__n));
922 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
924 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
925 _M_message(__msg_retreat_oob)
926 ._M_iterator(__x)._M_integer(__n));
932 template<
typename _Iterator,
typename _Sequence,
typename _Category>
939 {
return __first._M_valid_range(__last, __dist); }
941 template<
typename _Iterator,
typename _Sequence,
typename _Category>
945 const _Safe_iterator<_Iterator, _Sequence,
948 typename _Distance_traits<_Iterator>::__type __dist;
949 return __first._M_valid_range(__last, __dist);
952 template<
typename _Iterator,
typename _Sequence,
typename _Category,
955 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
957 {
return __it._M_can_advance(__n); }
959 template<
typename _Iterator,
typename _Sequence>
961 __base(
const _Safe_iterator<_Iterator, _Sequence,
963 {
return __it.base(); }
965 #if __cplusplus < 201103L
966 template<
typename _Iterator,
typename _Sequence>
967 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
968 {
typedef _Iterator _Type; };
971 template<
typename _Iterator,
typename _Sequence>
973 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
974 {
return __it.base(); }
978 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
979 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
980 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
981 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS