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>
66 typedef _Iterator _Iter_base;
69 typedef typename _Sequence::size_type size_type;
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
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"));
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
GNU debug classes for public use.
constexpr bool __valid_range(_InputIterator __first, _InputIterator __last, typename _Distance_traits< _InputIterator >::__type &__dist)
Traits class for iterators.
Struct holding two objects of arbitrary type.
_Safe_local_iterator(const _Safe_local_iterator &__x) noexcept
Copy construction.
bool _M_is_end() const
Is this iterator equal to the sequence's end(bucket) iterator?
size_type bucket() const
Return the bucket.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_local_iterator(_Safe_local_iterator &&__x) noexcept
Move construction.
_Iterator & base() noexcept
Return the underlying iterator.
_Safe_local_iterator(_Iterator __i, const _Safe_sequence_base *__cont)
Safe iterator construction from an unsafe iterator and its sequence.
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?
pointer operator->() const
Iterator dereference.
_Safe_local_iterator & operator=(_Safe_local_iterator &&__x) noexcept
Move assignment.
static constexpr bool _S_constant()
Determine if this is a constant iterator.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
void _M_attach_single(_Safe_sequence_base *__seq)
reference operator*() const
Iterator dereference.
_Safe_local_iterator operator++(int)
Iterator postincrement.
_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() noexcept
void _M_attach(_Safe_sequence_base *__seq)
_Safe_local_iterator & operator++()
Iterator preincrement.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin(bucket) iterator?
_Safe_sequence_base * _M_sequence
__gnu_cxx::__mutex & _M_get_mutex()
Base class that supports tracking of iterators that reference a sequence.
unsigned int _M_version
The container version number. This number may never be 0.
Basic functionality for a safe iterator.
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)