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
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>;
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"));
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"));
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();
406 _M_can_advance(difference_type __n,
bool __strict =
false)
const;
409 template<
typename _Diff>
418 bool __check_dereferenceable =
true)
const;
421 typename __gnu_cxx::__conditional_type<
422 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
423 _M_get_sequence()
const
427 typename _Distance_traits<_Iterator>::__type
431 typename _Distance_traits<_Iterator>::__type
432 _M_get_distance_from_begin()
const;
435 typename _Distance_traits<_Iterator>::__type
436 _M_get_distance_to_end()
const;
441 {
return base() == _M_get_sequence()->_M_base().begin(); }
446 {
return base() == _M_get_sequence()->_M_base().end(); }
465 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
467 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
468 return __lhs.base() == __rhs.base();
471 template<
typename _IteR>
473 operator==(
const _Self& __lhs,
474 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
477 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
478 return __lhs.base() == __rhs.base();
481 #if ! __cpp_lib_three_way_comparison
483 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
485 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
486 return __lhs.base() != __rhs.base();
489 template<
typename _IteR>
491 operator!=(
const _Self& __lhs,
492 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
495 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
496 return __lhs.base() != __rhs.base();
501 template<
typename _Iterator,
typename _Sequence>
502 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
503 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
509 typedef typename _Safe_base::_OtherIterator _OtherIterator;
510 typedef typename _Safe_base::_Attach_single _Attach_single;
512 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
514 : _Safe_base(__i, __seq, _Attach_single())
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;
656 typedef typename _Safe_base::_Attach_single _Attach_single;
658 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
660 : _Safe_base(__i, __seq, _Attach_single())
664 typedef typename _Safe_base::difference_type difference_type;
665 typedef typename _Safe_base::reference reference;
679 : _Safe_base(__i, __seq)
689 #if __cplusplus >= 201103L
698 template<
typename _MutableIterator>
701 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
702 std::__are_same<_MutableIterator, _OtherIterator>::__value,
708 #if __cplusplus >= 201103L
721 _Safe_base::operator=(__x);
740 _Safe_base::operator++();
752 _M_message(__msg_bad_inc)
753 ._M_iterator(*
this,
"this"));
765 operator--() _GLIBCXX_NOEXCEPT
767 _Safe_base::operator--();
776 operator--(
int) _GLIBCXX_NOEXCEPT
778 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
779 _M_message(__msg_bad_dec)
780 ._M_iterator(*
this,
"this"));
788 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
790 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
791 && this->_M_can_advance(__n + 1),
792 _M_message(__msg_iter_subscript_oob)
793 ._M_iterator(*this)._M_integer(__n));
794 return this->
base()[__n];
798 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
800 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
801 _M_message(__msg_advance_oob)
802 ._M_iterator(*this)._M_integer(__n));
809 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
811 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
812 _M_message(__msg_retreat_oob)
813 ._M_iterator(*this)._M_integer(__n));
819 #if __cpp_lib_three_way_comparison
821 operator<=>(
const _Self& __lhs,
const _Self& __rhs) noexcept
823 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
824 return __lhs.base() <=> __rhs.base();
828 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
830 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
831 return __lhs.base() <=> __rhs.base();
835 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
837 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
838 return __lhs.base() < __rhs.base();
842 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
844 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
845 return __lhs.base() < __rhs.base();
849 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
851 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
852 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();
863 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
865 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
866 return __lhs.base() > __rhs.base();
870 operator>(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
872 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
873 return __lhs.base() > __rhs.base();
877 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
879 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
880 return __lhs.base() >= __rhs.base();
884 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
886 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
887 return __lhs.base() >= __rhs.base();
895 friend difference_type
896 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
898 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
899 return __lhs.base() - __rhs.base();
902 friend difference_type
903 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
905 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
906 return __lhs.base() - __rhs.base();
910 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
912 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
913 _M_message(__msg_advance_oob)
914 ._M_iterator(__x)._M_integer(__n));
919 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
921 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
922 _M_message(__msg_advance_oob)
923 ._M_iterator(__x)._M_integer(__n));
928 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
930 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
931 _M_message(__msg_retreat_oob)
932 ._M_iterator(__x)._M_integer(__n));
938 template<
typename _Iterator,
typename _Sequence,
typename _Category>
945 {
return __first._M_valid_range(__last, __dist); }
947 template<
typename _Iterator,
typename _Sequence,
typename _Category>
951 const _Safe_iterator<_Iterator, _Sequence,
954 typename _Distance_traits<_Iterator>::__type __dist;
955 return __first._M_valid_range(__last, __dist);
958 template<
typename _Iterator,
typename _Sequence,
typename _Category,
961 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
963 {
return __it._M_can_advance(__n); }
965 template<
typename _Iterator,
typename _Sequence,
typename _Category,
968 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
971 {
return __it._M_can_advance(__dist, __way); }
973 template<
typename _Iterator,
typename _Sequence>
975 __base(
const _Safe_iterator<_Iterator, _Sequence,
977 {
return __it.base(); }
979 #if __cplusplus < 201103L
980 template<
typename _Iterator,
typename _Sequence>
981 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
982 {
typedef _Iterator _Type; };
985 template<
typename _Iterator,
typename _Sequence>
987 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
988 {
return __it.base(); }
992 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
993 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
994 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
995 #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.
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)
Traits class for iterators.
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.
Struct holding two objects of arbitrary type.
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)
_Iterator & base() noexcept
Return the underlying iterator.
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
_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=(_Safe_iterator &&__x) noexcept
Move assignment.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() 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)
_Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
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.
_Safe_iterator & operator++() noexcept
Iterator preincrement.
pointer operator->() const noexcept
Iterator dereference.
Basic functionality for a safe iterator.
_Safe_sequence_base * _M_sequence
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
__gnu_cxx::__mutex & _M_get_mutex()
Base class that supports tracking of iterators that reference a sequence.