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 || (_Lhs._M_value_initialized() \
45 && _Rhs._M_value_initialized()), \
46 _M_message(_BadMsgId) \
47 ._M_iterator(_Lhs, #_Lhs) \
48 ._M_iterator(_Rhs, #_Rhs)); \
49 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
50 _M_message(_DiffMsgId) \
51 ._M_iterator(_Lhs, #_Lhs) \
52 ._M_iterator(_Rhs, #_Rhs))
54#define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \
55 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \
56 __msg_compare_different)
58#define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \
59 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \
60 __msg_order_different)
62#define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \
63 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \
64 __msg_distance_different)
71 template<
typename _Sequence>
74 template<
typename _Iterator,
typename _Category>
79 template<
typename _Iterator,
typename _Category>
82 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
86 template<
typename _Sequence>
89 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
92 _S_size(
const _Sequence& __seq)
93 {
return std::make_pair(__seq.size(), __dp_exact); }
112 template<
typename _Iterator,
typename _Sequence,
typename _Category
118 typedef _Iterator _Iter_base;
124 typedef std::__are_same<
typename _Sequence::_Base::const_iterator,
125 _Iterator> _IsConstant;
127 typedef typename __gnu_cxx::__conditional_type<
128 _IsConstant::__value,
129 typename _Sequence::_Base::iterator,
130 typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
133 typedef _Iterator iterator_type;
134 typedef typename _Traits::iterator_category iterator_category;
135 typedef typename _Traits::value_type value_type;
136 typedef typename _Traits::difference_type difference_type;
137 typedef typename _Traits::reference reference;
138 typedef typename _Traits::pointer pointer;
140#if __cplusplus > 201703L && __cpp_lib_concepts
141 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
159 _M_message(__msg_init_singular)
160 ._M_iterator(*
this,
"this"));
171 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
172 || __x._M_value_initialized(),
173 _M_message(__msg_init_copy_singular)
174 ._M_iterator(*
this,
"this")
175 ._M_iterator(__x,
"other"));
179#if __cplusplus >= 201103L
187 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
188 || __x._M_value_initialized(),
189 _M_message(__msg_init_copy_singular)
190 ._M_iterator(*
this,
"this")
191 ._M_iterator(__x,
"other"));
194 std::swap(
base(), __x.base());
203 template<
typename _MutableIterator>
206 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
207 std::__are_same<_MutableIterator, _OtherIterator>::__value,
208 _Category>::__type>& __x)
210 : _Iter_base(__x.base())
214 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
215 || __x._M_value_initialized(),
216 _M_message(__msg_init_const_singular)
217 ._M_iterator(*
this,
"this")
218 ._M_iterator(__x,
"other"));
230 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
231 || __x._M_value_initialized(),
232 _M_message(__msg_copy_singular)
233 ._M_iterator(*
this,
"this")
234 ._M_iterator(__x,
"other"));
252#if __cplusplus >= 201103L
260 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
261 || __x._M_value_initialized(),
262 _M_message(__msg_copy_singular)
263 ._M_iterator(*
this,
"this")
264 ._M_iterator(__x,
"other"));
283 __x.base() = _Iterator();
297 _M_message(__msg_bad_deref)
298 ._M_iterator(*
this,
"this"));
311 _M_message(__msg_bad_deref)
312 ._M_iterator(*
this,
"this"));
313 return base().operator->();
325 _M_message(__msg_bad_inc)
326 ._M_iterator(*
this,
"this"));
340 _M_message(__msg_bad_inc)
341 ._M_iterator(*
this,
"this"));
350 static _GLIBCXX_CONSTEXPR
bool
352 {
return _IsConstant::__value; }
358 base() _GLIBCXX_NOEXCEPT {
return *
this; }
361 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
367 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
391 return ++
__base != _M_get_sequence()->_M_base().end();
408 _M_can_advance(difference_type __n,
bool __strict =
false)
const;
411 template<
typename _Diff>
420 bool __check_dereferenceable =
true)
const;
423 typename __gnu_cxx::__conditional_type<
424 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
425 _M_get_sequence()
const
429 typename _Distance_traits<_Iterator>::__type
433 typename _Distance_traits<_Iterator>::__type
434 _M_get_distance_from_begin()
const;
437 typename _Distance_traits<_Iterator>::__type
438 _M_get_distance_to_end()
const;
443 {
return base() == _M_get_sequence()->_M_base().begin(); }
448 {
return base() == _M_get_sequence()->_M_base().end(); }
468 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
470 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
471 return __lhs.base() == __rhs.base();
474 template<
typename _IteR>
477 operator==(
const _Self& __lhs,
478 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
481 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
482 return __lhs.base() == __rhs.base();
485#if ! __cpp_lib_three_way_comparison
488 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
490 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
491 return __lhs.base() != __rhs.base();
494 template<
typename _IteR>
497 operator!=(
const _Self& __lhs,
498 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
501 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
502 return __lhs.base() != __rhs.base();
507 template<
typename _Iterator,
typename _Sequence>
508 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
509 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
515 typedef typename _Safe_base::_OtherIterator _OtherIterator;
530 : _Safe_base(__i, __seq)
540#if __cplusplus >= 201103L
549 template<
typename _MutableIterator>
552 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
553 std::__are_same<_MutableIterator, _OtherIterator>::__value,
559#if __cplusplus >= 201103L
572 _Safe_base::operator=(__x);
585 _Safe_base::operator++();
597 _M_message(__msg_bad_inc)
598 ._M_iterator(*
this,
"this"));
610 operator--() _GLIBCXX_NOEXCEPT
612 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
613 _M_message(__msg_bad_dec)
614 ._M_iterator(*
this,
"this"));
625 operator--(
int) _GLIBCXX_NOEXCEPT
627 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
628 _M_message(__msg_bad_dec)
629 ._M_iterator(*
this,
"this"));
639 _M_decrementable()
const
643 template<
typename _Iterator,
typename _Sequence>
644 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
645 :
public _Safe_iterator<_Iterator, _Sequence,
646 std::bidirectional_iterator_tag>
650 typedef typename _Safe_base::_OtherIterator _OtherIterator;
652 typedef typename _Safe_base::_Self _Self;
657 typedef typename _Safe_base::difference_type difference_type;
658 typedef typename _Safe_base::reference reference;
672 : _Safe_base(__i, __seq)
682#if __cplusplus >= 201103L
691 template<
typename _MutableIterator>
694 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
695 std::__are_same<_MutableIterator, _OtherIterator>::__value,
701#if __cplusplus >= 201103L
714 _Safe_base::operator=(__x);
733 _Safe_base::operator++();
745 _M_message(__msg_bad_inc)
746 ._M_iterator(*
this,
"this"));
758 operator--() _GLIBCXX_NOEXCEPT
760 _Safe_base::operator--();
769 operator--(
int) _GLIBCXX_NOEXCEPT
771 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
772 _M_message(__msg_bad_dec)
773 ._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
816 operator<=>(
const _Self& __lhs,
const _Self& __rhs)
noexcept
818 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
819 return __lhs.base() <=> __rhs.base();
824 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
826 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
827 return __lhs.base() <=> __rhs.base();
832 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
834 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
835 return __lhs.base() < __rhs.base();
840 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
842 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
843 return __lhs.base() < __rhs.base();
848 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
850 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
851 return __lhs.base() <= __rhs.base();
856 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
858 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
859 return __lhs.base() <= __rhs.base();
864 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
866 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
867 return __lhs.base() > __rhs.base();
872 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
874 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
875 return __lhs.base() > __rhs.base();
880 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
882 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
883 return __lhs.base() >= __rhs.base();
888 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
890 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
891 return __lhs.base() >= __rhs.base();
900 friend difference_type
901 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
903 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
904 return __lhs.base() - __rhs.base();
908 friend difference_type
909 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
911 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
912 return __lhs.base() - __rhs.base();
917 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
919 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
920 _M_message(__msg_advance_oob)
921 ._M_iterator(__x)._M_integer(__n));
927 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
929 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
930 _M_message(__msg_advance_oob)
931 ._M_iterator(__x)._M_integer(__n));
937 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
939 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
940 _M_message(__msg_retreat_oob)
941 ._M_iterator(__x)._M_integer(__n));
947 template<
typename _Iterator,
typename _Sequence,
typename _Category>
954 {
return __first._M_valid_range(__last, __dist); }
956 template<
typename _Iterator,
typename _Sequence,
typename _Category>
960 const _Safe_iterator<_Iterator, _Sequence,
963 typename _Distance_traits<_Iterator>::__type __dist;
964 return __first._M_valid_range(__last, __dist);
967 template<
typename _Iterator,
typename _Sequence,
typename _Category,
970 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
972 {
return __it._M_can_advance(__n); }
974 template<
typename _Iterator,
typename _Sequence,
typename _Category,
977 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
980 {
return __it._M_can_advance(__dist, __way); }
982 template<
typename _Iterator,
typename _Sequence>
984 __base(
const _Safe_iterator<_Iterator, _Sequence,
986 {
return __it.base(); }
988#if __cplusplus < 201103L
989 template<
typename _Iterator,
typename _Sequence>
990 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
991 {
typedef _Iterator _Type; };
994 template<
typename _Iterator,
typename _Sequence>
996 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
997 {
return __it.base(); }
1001#if __cplusplus >= 201103L && __cplusplus <= 201703L
1002namespace std _GLIBCXX_VISIBILITY(default)
1004_GLIBCXX_BEGIN_NAMESPACE_VERSION
1006 template<
typename _Iterator,
typename _Container,
typename _Sequence>
1009 __gnu_cxx::__normal_iterator<_Iterator, _Container>,
1010 _Sequence>& __it)
noexcept
1011 ->
decltype(std::__to_address(__it.base().base()))
1012 {
return std::__to_address(__it.base().base()); }
1014_GLIBCXX_END_NAMESPACE_VERSION
1018#undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
1019#undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
1020#undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
1021#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
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?
reference operator*() const noexcept
Iterator dereference.
_Safe_iterator operator++(int) noexcept
Iterator postincrement.
_Safe_iterator(const _Safe_iterator &__x) noexcept
Copy construction.
_Safe_iterator(_Safe_iterator &&__x) noexcept
Move construction.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
void _M_attach_single(_Safe_sequence_base *__seq)
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
_Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
_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.
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise?
_Safe_iterator & operator++() noexcept
Iterator preincrement.
_Safe_iterator & operator=(_Safe_iterator &&__x) noexcept
Move assignment.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
bool _M_value_initialized() const
Is the iterator value-initialized?
_Iterator & base() noexcept
Return the underlying iterator.
_Safe_iterator() noexcept
_Safe_iterator(_Iterator __i, const _Safe_sequence_base *__seq) noexcept
Safe iterator construction from an unsafe iterator and its sequence.
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
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?
static constexpr bool _S_constant()
Determine if this is a constant iterator.
pointer operator->() const noexcept
Iterator dereference.
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.