29 #ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1 47 template<
typename _Iterator,
typename _Sequence>
48 class _Safe_local_iterator
50 ,
public _Safe_local_iterator_base
52 typedef _Iterator _Iter_base;
54 typedef typename _Sequence::const_local_iterator _Const_local_iterator;
55 typedef typename _Sequence::size_type size_type;
61 return std::__are_same<_Const_local_iterator,
65 typedef std::iterator_traits<_Iterator> _Traits;
71 _Attach_single) noexcept
76 typedef _Iterator iterator_type;
77 typedef typename _Traits::iterator_category iterator_category;
78 typedef typename _Traits::value_type value_type;
79 typedef typename _Traits::difference_type difference_type;
80 typedef typename _Traits::reference reference;
81 typedef typename _Traits::pointer pointer;
95 : _Iter_base(__i),
_Safe_base(__cont, _M_constant())
98 _M_message(__msg_init_singular)
99 ._M_iterator(*
this,
"this"));
106 : _Iter_base(__x.base())
110 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
111 || __x.base() == _Iterator(),
112 _M_message(__msg_init_copy_singular)
113 ._M_iterator(*
this,
"this")
114 ._M_iterator(__x,
"other"));
125 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
126 || __x.base() == _Iterator(),
127 _M_message(__msg_init_copy_singular)
128 ._M_iterator(*
this,
"this")
129 ._M_iterator(__x,
"other"));
130 auto __cont = __x._M_sequence;
132 std::swap(
base(), __x.base());
140 template<
typename _MutableIterator>
143 typename __gnu_cxx::__enable_if<std::__are_same<
145 typename _Sequence::local_iterator::iterator_type>::__value,
146 _Sequence>::__type>& __x)
147 : _Iter_base(__x.
base())
151 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
152 || __x.base() == _Iterator(),
153 _M_message(__msg_init_const_singular)
154 ._M_iterator(*
this,
"this")
155 ._M_iterator(__x,
"other"));
167 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
168 || __x.base() == _Iterator(),
169 _M_message(__msg_copy_singular)
170 ._M_iterator(*
this,
"this")
171 ._M_iterator(__x,
"other"));
196 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
197 _M_message(__msg_self_move_assign)
198 ._M_iterator(*
this,
"this"));
199 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
200 || __x.base() == _Iterator(),
201 _M_message(__msg_copy_singular)
202 ._M_iterator(*
this,
"this")
203 ._M_iterator(__x,
"other"));
219 __x.base() = _Iterator();
231 _M_message(__msg_bad_deref)
232 ._M_iterator(*
this,
"this"));
244 _M_message(__msg_bad_deref)
245 ._M_iterator(*
this,
"this"));
246 return base().operator->();
258 _M_message(__msg_bad_inc)
259 ._M_iterator(*
this,
"this"));
273 _M_message(__msg_bad_inc)
274 ._M_iterator(*
this,
"this"));
285 base() noexcept {
return *
this; }
288 base() const noexcept {
return *
this; }
300 operator _Iterator()
const {
return *
this; }
330 __gnu_cxx::__conditional_type<std::__are_same<_Const_local_iterator,
334 _M_get_sequence()
const 339 {
return base() == _M_get_sequence()->_M_base().begin(
bucket()); }
343 {
return base() == _M_get_sequence()->_M_base().end(
bucket()); }
346 template<
typename _Other>
349 _Sequence>& __other)
const 350 {
return bucket() == __other.bucket(); }
353 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
355 operator==(
const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
356 const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
358 _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
359 _M_message(__msg_iter_compare_bad)
360 ._M_iterator(__lhs,
"lhs")
361 ._M_iterator(__rhs,
"rhs"));
362 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
363 _M_message(__msg_compare_different)
364 ._M_iterator(__lhs,
"lhs")
365 ._M_iterator(__rhs,
"rhs"));
366 _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
367 _M_message(__msg_local_iter_compare_bad)
368 ._M_iterator(__lhs,
"lhs")
369 ._M_iterator(__rhs,
"rhs"));
370 return __lhs.base() == __rhs.base();
373 template<
typename _Iterator,
typename _Sequence>
375 operator==(
const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
376 const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
378 _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
379 _M_message(__msg_iter_compare_bad)
380 ._M_iterator(__lhs,
"lhs")
381 ._M_iterator(__rhs,
"rhs"));
382 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
383 _M_message(__msg_compare_different)
384 ._M_iterator(__lhs,
"lhs")
385 ._M_iterator(__rhs,
"rhs"));
386 _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
387 _M_message(__msg_local_iter_compare_bad)
388 ._M_iterator(__lhs,
"lhs")
389 ._M_iterator(__rhs,
"rhs"));
390 return __lhs.base() == __rhs.base();
393 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
395 operator!=(
const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
396 const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
398 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
399 _M_message(__msg_iter_compare_bad)
400 ._M_iterator(__lhs,
"lhs")
401 ._M_iterator(__rhs,
"rhs"));
402 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
403 _M_message(__msg_compare_different)
404 ._M_iterator(__lhs,
"lhs")
405 ._M_iterator(__rhs,
"rhs"));
406 _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
407 _M_message(__msg_local_iter_compare_bad)
408 ._M_iterator(__lhs,
"lhs")
409 ._M_iterator(__rhs,
"rhs"));
410 return __lhs.base() != __rhs.base();
413 template<
typename _Iterator,
typename _Sequence>
415 operator!=(
const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
416 const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
418 _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
419 _M_message(__msg_iter_compare_bad)
420 ._M_iterator(__lhs,
"lhs")
421 ._M_iterator(__rhs,
"rhs"));
422 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
423 _M_message(__msg_compare_different)
424 ._M_iterator(__lhs,
"lhs")
425 ._M_iterator(__rhs,
"rhs"));
426 _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
427 _M_message(__msg_local_iter_compare_bad)
428 ._M_iterator(__lhs,
"lhs")
429 ._M_iterator(__rhs,
"rhs"));
430 return __lhs.base() != __rhs.base();
434 template<
typename _Iterator,
typename _Sequence>
438 {
return __x._M_dereferenceable(); }
441 template<
typename _Iterator,
typename _Sequence>
446 {
return __first._M_valid_range(__last, __dist_info); }
450 template<
typename _Iterator,
typename _Sequence>
457 if (__first.base() == __last.base())
458 return { 0, __dp_exact };
460 if (__first._M_is_begin())
462 if (__last._M_is_end())
465 __first._M_get_sequence()->bucket_size(__first.bucket()),
469 return { 1, __dp_sign };
472 if (__first._M_is_end())
474 if (__last._M_is_begin())
477 -__first._M_get_sequence()->bucket_size(__first.bucket()),
481 return { -1, __dp_sign };
484 if (__last._M_is_begin())
485 return { -1, __dp_sign };
487 if (__last._M_is_end())
488 return { 1, __dp_sign };
490 return { 1, __dp_equality };
493 #if __cplusplus < 201103L 494 template<
typename _Iterator,
typename _Sequence>
495 struct _Unsafe_type<_Safe_local_iterator<_Iterator, _Sequence> >
496 {
typedef _Iterator _Type; };
499 template<
typename _Iterator,
typename _Sequence>
501 __unsafe(
const _Safe_local_iterator<_Iterator, _Sequence>& __it)
502 {
return __it.base(); }
bool _M_dereferenceable() const
Is the iterator dereferenceable?
_Safe_local_iterator & operator=(_Safe_local_iterator &&__x) noexcept
Move assignment.
Struct holding two objects of arbitrary type.
_Iterator & base() noexcept
Return the underlying iterator.
pointer operator->() const
Iterator dereference.
_Safe_local_iterator(_Safe_local_iterator &&__x) noexcept
Move construction.
_Safe_local_iterator operator++(int)
Iterator postincrement.
GNU debug classes for public use.
_Safe_local_iterator() noexcept
Base class that supports tracking of iterators that reference a 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?
void _M_attach(_Safe_sequence_base *__seq)
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_local_iterator & operator=(const _Safe_local_iterator &__x)
Copy assignment.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin(bucket) iterator?
_Safe_local_iterator_base()
reference operator*() const
Iterator dereference.
_Distance_traits< _Iterator >::__type __get_distance(const _Iterator &__lhs, const _Iterator &__rhs, std::random_access_iterator_tag)
void _M_attach_single(_Safe_sequence_base *__seq)
_Safe_local_iterator(const _Safe_local_iterator &__x) noexcept
Copy construction.
_Safe_sequence_base * _M_sequence
bool __valid_range(const _InputIterator &__first, const _InputIterator &__last, typename _Distance_traits< _InputIterator >::__type &__dist)
_Safe_local_iterator(const _Iterator &__i, const _Safe_sequence_base *__cont)
Safe iterator construction from an unsafe iterator and its sequence.
bool __check_dereferenceable(const _Iterator &)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
_Safe_local_iterator(const _Safe_local_iterator< _MutableIterator, typename __gnu_cxx::__enable_if< std::__are_same< _MutableIterator, typename _Sequence::local_iterator::iterator_type >::__value, _Sequence >::__type > &__x)
Converting constructor from a mutable iterator to a constant iterator.
size_type bucket() const
Return the bucket.
_Safe_local_iterator & operator++()
Iterator preincrement.
Basic functionality for a safe iterator.
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
__gnu_cxx::__mutex & _M_get_mutex()
bool _M_is_end() const
Is this iterator equal to the sequence's end(bucket) iterator?