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.base() == _Iterator() \
45 && _Rhs.base() == _Iterator()), \
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;
132 struct _Attach_single
141 typedef _Iterator iterator_type;
142 typedef typename _Traits::iterator_category iterator_category;
143 typedef typename _Traits::value_type value_type;
144 typedef typename _Traits::difference_type difference_type;
145 typedef typename _Traits::reference reference;
146 typedef typename _Traits::pointer pointer;
148#if __cplusplus > 201703L && __cpp_lib_concepts
149 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
167 _M_message(__msg_init_singular)
168 ._M_iterator(*
this,
"this"));
179 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
180 || __x.base() == _Iterator(),
181 _M_message(__msg_init_copy_singular)
182 ._M_iterator(*
this,
"this")
183 ._M_iterator(__x,
"other"));
187#if __cplusplus >= 201103L
195 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
196 || __x.base() == _Iterator(),
197 _M_message(__msg_init_copy_singular)
198 ._M_iterator(*
this,
"this")
199 ._M_iterator(__x,
"other"));
211 template<
typename _MutableIterator>
214 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
215 std::__are_same<_MutableIterator, _OtherIterator>::__value,
216 _Category>::__type>& __x)
218 : _Iter_base(__x.base())
222 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
223 || __x.base() == _MutableIterator(),
224 _M_message(__msg_init_const_singular)
225 ._M_iterator(*
this,
"this")
226 ._M_iterator(__x,
"other"));
238 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
239 || __x.base() == _Iterator(),
240 _M_message(__msg_copy_singular)
241 ._M_iterator(*
this,
"this")
242 ._M_iterator(__x,
"other"));
260#if __cplusplus >= 201103L
268 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
269 || __x.base() == _Iterator(),
270 _M_message(__msg_copy_singular)
271 ._M_iterator(*
this,
"this")
272 ._M_iterator(__x,
"other"));
291 __x.base() = _Iterator();
304 _M_message(__msg_bad_deref)
305 ._M_iterator(*
this,
"this"));
317 _M_message(__msg_bad_deref)
318 ._M_iterator(*
this,
"this"));
319 return base().operator->();
331 _M_message(__msg_bad_inc)
332 ._M_iterator(*
this,
"this"));
346 _M_message(__msg_bad_inc)
347 ._M_iterator(*
this,
"this"));
355 static _GLIBCXX_CONSTEXPR
bool
357 {
return _IsConstant::__value; }
363 base() _GLIBCXX_NOEXCEPT {
return *
this; }
366 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
372 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
396 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(); }
467 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
469 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
470 return __lhs.base() == __rhs.base();
473 template<
typename _IteR>
475 operator==(
const _Self& __lhs,
476 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
479 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
480 return __lhs.base() == __rhs.base();
483#if ! __cpp_lib_three_way_comparison
485 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
487 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
488 return __lhs.base() != __rhs.base();
491 template<
typename _IteR>
493 operator!=(
const _Self& __lhs,
494 const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
497 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
498 return __lhs.base() != __rhs.base();
503 template<
typename _Iterator,
typename _Sequence>
504 class _Safe_iterator<_Iterator, _Sequence,
std::bidirectional_iterator_tag>
505 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
511 typedef typename _Safe_base::_OtherIterator _OtherIterator;
512 typedef typename _Safe_base::_Attach_single _Attach_single;
514 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
516 : _Safe_base(__i, __seq, _Attach_single())
532 : _Safe_base(__i, __seq)
542#if __cplusplus >= 201103L
551 template<
typename _MutableIterator>
554 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
555 std::__are_same<_MutableIterator, _OtherIterator>::__value,
561#if __cplusplus >= 201103L
574 _Safe_base::operator=(__x);
587 _Safe_base::operator++();
599 _M_message(__msg_bad_inc)
600 ._M_iterator(*
this,
"this"));
612 operator--() _GLIBCXX_NOEXCEPT
614 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
615 _M_message(__msg_bad_dec)
616 ._M_iterator(*
this,
"this"));
627 operator--(
int) _GLIBCXX_NOEXCEPT
629 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
630 _M_message(__msg_bad_dec)
631 ._M_iterator(*
this,
"this"));
641 _M_decrementable()
const
645 template<
typename _Iterator,
typename _Sequence>
646 class _Safe_iterator<_Iterator, _Sequence,
std::random_access_iterator_tag>
647 :
public _Safe_iterator<_Iterator, _Sequence,
648 std::bidirectional_iterator_tag>
652 typedef typename _Safe_base::_OtherIterator _OtherIterator;
654 typedef typename _Safe_base::_Self _Self;
658 typedef typename _Safe_base::_Attach_single _Attach_single;
660 _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
662 : _Safe_base(__i, __seq, _Attach_single())
666 typedef typename _Safe_base::difference_type difference_type;
667 typedef typename _Safe_base::reference reference;
681 : _Safe_base(__i, __seq)
691#if __cplusplus >= 201103L
700 template<
typename _MutableIterator>
703 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
704 std::__are_same<_MutableIterator, _OtherIterator>::__value,
710#if __cplusplus >= 201103L
723 _Safe_base::operator=(__x);
742 _Safe_base::operator++();
754 _M_message(__msg_bad_inc)
755 ._M_iterator(*
this,
"this"));
767 operator--() _GLIBCXX_NOEXCEPT
769 _Safe_base::operator--();
778 operator--(
int) _GLIBCXX_NOEXCEPT
780 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
781 _M_message(__msg_bad_dec)
782 ._M_iterator(*
this,
"this"));
790 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
792 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
793 && this->_M_can_advance(__n + 1),
794 _M_message(__msg_iter_subscript_oob)
795 ._M_iterator(*this)._M_integer(__n));
796 return this->
base()[__n];
800 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
802 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
803 _M_message(__msg_advance_oob)
804 ._M_iterator(*this)._M_integer(__n));
811 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
813 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
814 _M_message(__msg_retreat_oob)
815 ._M_iterator(*this)._M_integer(__n));
821#if __cpp_lib_three_way_comparison
823 operator<=>(
const _Self& __lhs,
const _Self& __rhs)
noexcept
825 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
826 return __lhs.base() <=> __rhs.base();
830 operator<=>(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
832 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
833 return __lhs.base() <=> __rhs.base();
837 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
839 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
840 return __lhs.base() < __rhs.base();
844 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
846 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
847 return __lhs.base() < __rhs.base();
851 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
853 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
854 return __lhs.base() <= __rhs.base();
858 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
860 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
861 return __lhs.base() <= __rhs.base();
865 operator>(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
867 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
868 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();
879 operator>=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
881 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
882 return __lhs.base() >= __rhs.base();
886 operator>=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
888 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
889 return __lhs.base() >= __rhs.base();
897 friend difference_type
898 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
900 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
901 return __lhs.base() - __rhs.base();
904 friend difference_type
905 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
907 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
908 return __lhs.base() - __rhs.base();
912 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
914 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
915 _M_message(__msg_advance_oob)
916 ._M_iterator(__x)._M_integer(__n));
921 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
923 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
924 _M_message(__msg_advance_oob)
925 ._M_iterator(__x)._M_integer(__n));
930 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
932 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
933 _M_message(__msg_retreat_oob)
934 ._M_iterator(__x)._M_integer(__n));
940 template<
typename _Iterator,
typename _Sequence,
typename _Category>
947 {
return __first._M_valid_range(__last, __dist); }
949 template<
typename _Iterator,
typename _Sequence,
typename _Category>
953 const _Safe_iterator<_Iterator, _Sequence,
956 typename _Distance_traits<_Iterator>::__type __dist;
957 return __first._M_valid_range(__last, __dist);
960 template<
typename _Iterator,
typename _Sequence,
typename _Category,
963 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
965 {
return __it._M_can_advance(__n); }
967 template<
typename _Iterator,
typename _Sequence,
typename _Category,
970 __can_advance(
const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
973 {
return __it._M_can_advance(__dist, __way); }
975 template<
typename _Iterator,
typename _Sequence>
977 __base(
const _Safe_iterator<_Iterator, _Sequence,
979 {
return __it.base(); }
981#if __cplusplus < 201103L
982 template<
typename _Iterator,
typename _Sequence>
983 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
984 {
typedef _Iterator _Type; };
987 template<
typename _Iterator,
typename _Sequence>
989 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
990 {
return __it.base(); }
994#undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
995#undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
996#undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
997#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
constexpr time_point< _Clock, typename common_type< duration< _Rep1, _Period1 >, _Dur2 >::type > operator+(const duration< _Rep1, _Period1 > &__lhs, const time_point< _Clock, _Dur2 > &__rhs)
Adjust a time point forwards by the given duration.
constexpr common_type< duration< _Rep1, _Period1 >, duration< _Rep2, _Period2 > >::type operator-(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
The difference between two durations.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any 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)
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)
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?
_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.
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.