29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 39 #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \ 40 _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \ 41 _M_message(_BadMsgId) \ 42 ._M_iterator(_Lhs, #_Lhs) \ 43 ._M_iterator(_Rhs, #_Rhs)); \ 44 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \ 45 _M_message(_DiffMsgId) \ 46 ._M_iterator(_Lhs, #_Lhs) \ 47 ._M_iterator(_Rhs, #_Rhs)) 49 #define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \ 50 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \ 51 __msg_compare_different) 53 #define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \ 54 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \ 55 __msg_order_different) 57 #define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \ 58 _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \ 59 __msg_distance_different) 66 template<
typename _Sequence>
69 template<
typename _Iterator,
typename _Category>
74 template<
typename _Iterator,
typename _Category>
77 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
81 template<
typename _Sequence>
84 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
87 _S_size(
const _Sequence& __seq)
88 {
return std::make_pair(__seq.size(), __dp_exact); }
107 template<
typename _Iterator,
typename _Sequence,
typename _Category
113 typedef _Iterator _Iter_base;
119 typedef std::__are_same<
typename _Sequence::_Base::const_iterator,
120 _Iterator> _IsConstant;
122 typedef typename __gnu_cxx::__conditional_type<
123 _IsConstant::__value,
124 typename _Sequence::_Base::iterator,
125 typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
127 struct _Attach_single
133 { _M_attach_single(__seq); }
136 typedef _Iterator iterator_type;
137 typedef typename _Traits::iterator_category iterator_category;
138 typedef typename _Traits::value_type value_type;
139 typedef typename _Traits::difference_type difference_type;
140 typedef typename _Traits::reference reference;
141 typedef typename _Traits::pointer pointer;
143 #if __cplusplus > 201703L && __cpp_lib_concepts 144 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
159 : _Iter_base(__i), _Safe_base(__seq, _S_constant())
161 _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
162 _M_message(__msg_init_singular)
163 ._M_iterator(*
this,
"this"));
170 : _Iter_base(__x.base())
174 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
175 || __x.base() == _Iterator(),
176 _M_message(__msg_init_copy_singular)
177 ._M_iterator(*
this,
"this")
178 ._M_iterator(__x,
"other"));
179 _M_attach(__x._M_sequence);
182 #if __cplusplus >= 201103L 190 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
191 || __x.base() == _Iterator(),
192 _M_message(__msg_init_copy_singular)
193 ._M_iterator(*
this,
"this")
194 ._M_iterator(__x,
"other"));
197 std::swap(base(), __x.base());
206 template<
typename _MutableIterator>
209 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
210 std::__are_same<_MutableIterator, _OtherIterator>::__value,
211 _Category>::__type>& __x)
213 : _Iter_base(__x.base())
217 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
218 || __x.base() == _MutableIterator(),
219 _M_message(__msg_init_const_singular)
220 ._M_iterator(*
this,
"this")
221 ._M_iterator(__x,
"other"));
222 _M_attach(__x._M_sequence);
233 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
234 || __x.base() == _Iterator(),
235 _M_message(__msg_copy_singular)
236 ._M_iterator(*
this,
"this")
237 ._M_iterator(__x,
"other"));
239 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
243 _M_version = __x._M_sequence->_M_version;
249 _M_attach(__x._M_sequence);
255 #if __cplusplus >= 201103L 263 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
264 _M_message(__msg_self_move_assign)
265 ._M_iterator(*
this,
"this"));
266 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
267 || __x.base() == _Iterator(),
268 _M_message(__msg_copy_singular)
269 ._M_iterator(*
this,
"this")
270 ._M_iterator(__x,
"other"));
272 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
276 _M_version = __x._M_sequence->_M_version;
282 _M_attach(__x._M_sequence);
286 __x.base() = _Iterator();
298 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
299 _M_message(__msg_bad_deref)
300 ._M_iterator(*
this,
"this"));
311 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
312 _M_message(__msg_bad_deref)
313 ._M_iterator(*
this,
"this"));
314 return base().operator->();
325 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
326 _M_message(__msg_bad_inc)
327 ._M_iterator(*
this,
"this"));
340 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
341 _M_message(__msg_bad_inc)
342 ._M_iterator(*
this,
"this"));
344 return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
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; }
372 { _Safe_base::_M_attach(__seq, _S_constant()); }
377 { _Safe_base::_M_attach_single(__seq, _S_constant()); }
382 {
return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
388 if (this->_M_incrementable())
390 _Iterator
__base = base();
391 return ++__base != _M_get_sequence()->_M_base().end();
399 {
return !this->_M_singular() && !_M_is_end(); }
403 _M_can_advance(difference_type __n,
bool __strict =
false)
const;
409 bool __check_dereferenceable =
true)
const;
412 typename __gnu_cxx::__conditional_type<
413 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
414 _M_get_sequence()
const 415 {
return static_cast<_Sequence*
>(_M_sequence); }
423 _M_get_distance_from_begin()
const;
427 _M_get_distance_to_end()
const;
432 {
return base() == _M_get_sequence()->_M_base().begin(); }
437 {
return base() == _M_get_sequence()->_M_base().end(); }
456 operator==(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
458 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
459 return __lhs.
base() == __rhs.
base();
462 template<
typename _IteR>
464 operator==(
const _Self& __lhs,
468 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
469 return __lhs.
base() == __rhs.
base();
473 operator!=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
475 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
476 return __lhs.
base() != __rhs.
base();
479 template<
typename _IteR>
481 operator!=(
const _Self& __lhs,
485 _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
486 return __lhs.
base() != __rhs.
base();
490 template<
typename _Iterator,
typename _Sequence>
491 class _Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>
492 :
public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
498 typedef typename _Safe_base::_OtherIterator _OtherIterator;
499 typedef typename _Safe_base::_Attach_single _Attach_single;
503 : _Safe_base(__i, __seq, _Attach_single())
519 : _Safe_base(__i, __seq)
529 #if __cplusplus >= 201103L 538 template<
typename _MutableIterator>
541 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
542 std::__are_same<_MutableIterator, _OtherIterator>::__value,
548 #if __cplusplus >= 201103L 561 _Safe_base::operator=(__x);
572 operator++() _GLIBCXX_NOEXCEPT
574 _Safe_base::operator++();
583 operator++(
int) _GLIBCXX_NOEXCEPT
585 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
586 _M_message(__msg_bad_inc)
587 ._M_iterator(*
this,
"this"));
599 operator--() _GLIBCXX_NOEXCEPT
601 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
602 _M_message(__msg_bad_dec)
603 ._M_iterator(*
this,
"this"));
614 operator--(
int) _GLIBCXX_NOEXCEPT
616 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
617 _M_message(__msg_bad_dec)
618 ._M_iterator(*
this,
"this"));
628 _M_decrementable()
const 629 {
return !this->_M_singular() && !this->_M_is_begin(); }
632 template<
typename _Iterator,
typename _Sequence>
633 class _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>
635 std::bidirectional_iterator_tag>
639 typedef typename _Safe_base::_OtherIterator _OtherIterator;
641 typedef typename _Safe_base::_Self
_Self;
645 typedef typename _Safe_base::_Attach_single _Attach_single;
649 : _Safe_base(__i, __seq, _Attach_single())
653 typedef typename _Safe_base::difference_type difference_type;
654 typedef typename _Safe_base::reference reference;
668 : _Safe_base(__i, __seq)
678 #if __cplusplus >= 201103L 687 template<
typename _MutableIterator>
690 typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
691 std::__are_same<_MutableIterator, _OtherIterator>::__value,
697 #if __cplusplus >= 201103L 710 _Safe_base::operator=(__x);
727 operator++() _GLIBCXX_NOEXCEPT
729 _Safe_base::operator++();
738 operator++(
int) _GLIBCXX_NOEXCEPT
740 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
741 _M_message(__msg_bad_inc)
742 ._M_iterator(*
this,
"this"));
754 operator--() _GLIBCXX_NOEXCEPT
756 _Safe_base::operator--();
765 operator--(
int) _GLIBCXX_NOEXCEPT
767 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
768 _M_message(__msg_bad_dec)
769 ._M_iterator(*
this,
"this"));
777 operator[](difference_type __n)
const _GLIBCXX_NOEXCEPT
779 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
780 && this->_M_can_advance(__n + 1),
781 _M_message(__msg_iter_subscript_oob)
782 ._M_iterator(*this)._M_integer(__n));
783 return this->base()[__n];
787 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
789 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
790 _M_message(__msg_advance_oob)
791 ._M_iterator(*this)._M_integer(__n));
798 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
800 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
801 _M_message(__msg_retreat_oob)
802 ._M_iterator(*this)._M_integer(__n));
809 operator<(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
811 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
816 operator<(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
818 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
819 return __lhs.
base() < __rhs.base();
823 operator<=(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
825 _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
826 return __lhs.
base() <= __rhs.
base();
830 operator<=(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_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);
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();
868 friend difference_type
869 operator-(
const _Self& __lhs,
const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
871 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
872 return __lhs.
base() - __rhs.base();
875 friend difference_type
876 operator-(
const _Self& __lhs,
const _Self& __rhs) _GLIBCXX_NOEXCEPT
878 _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
883 operator+(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
885 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
886 _M_message(__msg_advance_oob)
887 ._M_iterator(__x)._M_integer(__n));
892 operator+(difference_type __n,
const _Self& __x) _GLIBCXX_NOEXCEPT
894 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
895 _M_message(__msg_advance_oob)
896 ._M_iterator(__x)._M_integer(__n));
901 operator-(
const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
903 _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
904 _M_message(__msg_retreat_oob)
905 ._M_iterator(__x)._M_integer(__n));
911 template<
typename _Iterator,
typename _Sequence,
typename _Category>
915 const _Safe_iterator<_Iterator, _Sequence,
918 {
return __first._M_valid_range(__last, __dist); }
920 template<
typename _Iterator,
typename _Sequence,
typename _Category>
924 const _Safe_iterator<_Iterator, _Sequence,
928 return __first._M_valid_range(__last, __dist);
931 template<
typename _Iterator,
typename _Sequence,
typename _Category,
936 {
return __it._M_can_advance(__n); }
938 template<
typename _Iterator,
typename _Sequence>
940 __base(
const _Safe_iterator<_Iterator, _Sequence,
942 {
return __it.
base(); }
944 #if __cplusplus < 201103L 945 template<
typename _Iterator,
typename _Sequence>
946 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
947 {
typedef _Iterator _Type; };
950 template<
typename _Iterator,
typename _Sequence>
953 {
return __it.
base(); }
957 #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS 958 #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS 959 #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS 960 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
pointer operator->() const noexcept
Iterator dereference.
Base class that supports tracking of iterators that reference a sequence.
_Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
void _M_attach_single(_Safe_sequence_base *__seq)
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?
Forward iterators support a superset of input iterator operations.
_Safe_iterator operator++(int) noexcept
Iterator postincrement.
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise...
constexpr bool __valid_range(_InputIterator __first, _InputIterator __last, typename _Distance_traits< _InputIterator >::__type &__dist)
_Safe_sequence_base * _M_sequence
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Random-access iterators support a superset of bidirectional iterator operations.
Basic functionality for a safe iterator.
bool _M_incrementable() const
Is the iterator incrementable?
_Iterator & base() noexcept
Return the underlying iterator.
_Safe_iterator(const _Safe_iterator &__x) noexcept
Copy construction.
_Safe_iterator & operator++() noexcept
Iterator preincrement.
GNU debug classes for public use.
_Safe_iterator() noexcept
Struct holding two objects of arbitrary type.
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
bool _M_dereferenceable() const
Is the iterator dereferenceable?
_Safe_iterator & operator=(_Safe_iterator &&__x) noexcept
Move 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_before_dereferenceable() const
Is the iterator before a dereferenceable one?
reference operator*() const noexcept
Iterator dereference.
Traits class for iterators.
constexpr _Iterator __base(_Iterator __it)
Bidirectional iterators support a superset of forward iterator operations.
void _M_attach(_Safe_sequence_base *__seq)
_Safe_iterator(_Safe_iterator &&__x) noexcept
Move construction.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
static constexpr bool _S_constant()
Determine if this is a constant iterator.
_Safe_iterator(_Iterator __i, const _Safe_sequence_base *__seq) noexcept
Safe iterator construction from an unsafe iterator and its sequence.