29 #ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1 34 #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \ 35 _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \ 36 _M_message(__msg_iter_compare_bad) \ 37 ._M_iterator(_Lhs, "lhs") \ 38 ._M_iterator(_Rhs, "rhs")); \ 39 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \ 40 _M_message(__msg_compare_different) \ 41 ._M_iterator(_Lhs, "lhs") \ 42 ._M_iterator(_Rhs, "rhs")); \ 43 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_in_same_bucket(_Rhs), \ 44 _M_message(__msg_local_iter_compare_bad) \ 45 ._M_iterator(_Lhs, "lhs") \ 46 ._M_iterator(_Rhs, "rhs")) 61 template<
typename _Iterator,
typename _Sequence>
62 class _Safe_local_iterator
64 ,
public _Safe_local_iterator_base
66 typedef _Iterator _Iter_base;
69 typedef typename _Sequence::size_type size_type;
71 typedef std::iterator_traits<_Iterator> _Traits;
73 typedef std::__are_same<
74 typename _Sequence::_Base::const_local_iterator,
75 _Iterator> _IsConstant;
77 typedef typename __gnu_cxx::__conditional_type<_IsConstant::__value,
78 typename _Sequence::_Base::local_iterator,
79 typename _Sequence::_Base::const_local_iterator>::__type
83 typedef _Safe_local_iterator<_OtherIterator, _Sequence> _OtherSelf;
89 _Attach_single) noexcept
94 typedef _Iterator iterator_type;
95 typedef typename _Traits::iterator_category iterator_category;
96 typedef typename _Traits::value_type value_type;
97 typedef typename _Traits::difference_type difference_type;
98 typedef typename _Traits::reference reference;
99 typedef typename _Traits::pointer pointer;
115 _M_message(__msg_init_singular)
116 ._M_iterator(*
this,
"this"));
123 : _Iter_base(__x.base())
127 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
128 || __x.base() == _Iterator(),
129 _M_message(__msg_init_copy_singular)
130 ._M_iterator(*
this,
"this")
131 ._M_iterator(__x,
"other"));
142 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
143 || __x.base() == _Iterator(),
144 _M_message(__msg_init_copy_singular)
145 ._M_iterator(*
this,
"this")
146 ._M_iterator(__x,
"other"));
147 auto __cont = __x._M_sequence;
149 std::swap(
base(), __x.base());
157 template<
typename _MutableIterator>
160 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
161 std::__are_same<_MutableIterator, _OtherIterator>::__value,
162 _Sequence>::__type>& __x) noexcept
163 : _Iter_base(__x.base())
167 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
168 || __x.base() == _MutableIterator(),
169 _M_message(__msg_init_const_singular)
170 ._M_iterator(*
this,
"this")
171 ._M_iterator(__x,
"other"));
183 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
184 || __x.base() == _Iterator(),
185 _M_message(__msg_copy_singular)
186 ._M_iterator(*
this,
"this")
187 ._M_iterator(__x,
"other"));
212 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
213 _M_message(__msg_self_move_assign)
214 ._M_iterator(*
this,
"this"));
215 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
216 || __x.base() == _Iterator(),
217 _M_message(__msg_copy_singular)
218 ._M_iterator(*
this,
"this")
219 ._M_iterator(__x,
"other"));
235 __x.base() = _Iterator();
247 _M_message(__msg_bad_deref)
248 ._M_iterator(*
this,
"this"));
260 _M_message(__msg_bad_deref)
261 ._M_iterator(*
this,
"this"));
262 return base().operator->();
274 _M_message(__msg_bad_inc)
275 ._M_iterator(*
this,
"this"));
289 _M_message(__msg_bad_inc)
290 ._M_iterator(*
this,
"this"));
299 static constexpr
bool 301 {
return _IsConstant::__value; }
307 base() noexcept {
return *
this; }
310 base() const noexcept {
return *
this; }
322 operator _Iterator()
const {
return *
this; }
355 typename __gnu_cxx::__conditional_type<
356 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
357 _M_get_sequence()
const 362 {
return base() == _M_get_sequence()->_M_base().begin(
bucket()); }
366 {
return base() == _M_get_sequence()->_M_base().end(
bucket()); }
369 template<
typename _Other>
372 _Sequence>& __other)
const 373 {
return bucket() == __other.bucket(); }
376 operator==(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
378 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
379 return __lhs.base() == __rhs.base();
383 operator==(
const _Self& __lhs,
const _Self& __rhs) noexcept
385 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
386 return __lhs.base() == __rhs.base();
390 operator!=(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
392 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
393 return __lhs.base() != __rhs.base();
397 operator!=(
const _Self& __lhs,
const _Self& __rhs) noexcept
399 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
400 return __lhs.base() != __rhs.base();
405 template<
typename _Iterator,
typename _Sequence>
410 {
return __first._M_valid_range(__last, __dist_info); }
412 template<
typename _Iterator,
typename _Sequence>
414 __valid_range(
const _Safe_local_iterator<_Iterator, _Sequence>& __first,
415 const _Safe_local_iterator<_Iterator, _Sequence>& __last)
417 typename _Distance_traits<_Iterator>::__type __dist_info;
418 return __first._M_valid_range(__last, __dist_info);
421 #if __cplusplus < 201103L 422 template<
typename _Iterator,
typename _Sequence>
423 struct _Unsafe_type<_Safe_local_iterator<_Iterator, _Sequence> >
424 {
typedef _Iterator _Type; };
427 template<
typename _Iterator,
typename _Sequence>
429 __unsafe(
const _Safe_local_iterator<_Iterator, _Sequence>& __it)
430 {
return __it.base(); }
434 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS void _M_attach(_Safe_sequence_base *__seq, bool __constant)
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_local_iterator & operator++()
Iterator preincrement.
_Safe_local_iterator() noexcept
Base class that supports tracking of iterators that reference a sequence.
bool _M_is_end() const
Is this iterator equal to the sequence's end(bucket) iterator?
_Iterator & base() noexcept
Return the underlying iterator.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin(bucket) iterator?
void _M_attach_single(_Safe_sequence_base *__seq)
bool _M_in_same_bucket(const _Safe_local_iterator< _Other, _Sequence > &__other) const
Is this iterator part of the same bucket as the other one?
static constexpr bool _S_constant()
Determine if this is a constant iterator.
_Safe_local_iterator & operator=(const _Safe_local_iterator &__x)
Copy assignment.
_Safe_local_iterator(const _Safe_local_iterator< _MutableIterator, typename __gnu_cxx::__enable_if< _IsConstant::__value &&std::__are_same< _MutableIterator, _OtherIterator >::__value, _Sequence >::__type > &__x) noexcept
Converting constructor from a mutable iterator to a constant iterator.
_Safe_local_iterator & operator=(_Safe_local_iterator &&__x) noexcept
Move assignment.
pointer operator->() const
Iterator dereference.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
_Safe_local_iterator operator++(int)
Iterator postincrement.
_Safe_local_iterator(const _Safe_local_iterator &__x) noexcept
Copy construction.
__gnu_cxx::__mutex & _M_get_mutex()
size_type bucket() const
Return the bucket.
GNU debug classes for public use.
reference operator*() const
Iterator dereference.
void _M_attach(_Safe_sequence_base *__seq)
_Safe_local_iterator(_Iterator __i, const _Safe_sequence_base *__cont)
Safe iterator construction from an unsafe iterator and its sequence.
_Safe_sequence_base * _M_sequence
_Safe_local_iterator_base()
Basic functionality for a safe iterator.
Struct holding two objects of arbitrary type.
_Safe_local_iterator(_Safe_local_iterator &&__x) noexcept
Move construction.
bool __valid_range(_InputIterator __first, _InputIterator __last, typename _Distance_traits< _InputIterator >::__type &__dist)