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 || (_Lhs._M_value_initialized() \
37 && _Rhs._M_value_initialized()), \
38 _M_message(__msg_iter_compare_bad) \
39 ._M_iterator(_Lhs, "lhs") \
40 ._M_iterator(_Rhs, "rhs")); \
41 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
42 _M_message(__msg_compare_different) \
43 ._M_iterator(_Lhs, "lhs") \
44 ._M_iterator(_Rhs, "rhs")); \
45 _GLIBCXX_DEBUG_VERIFY(_Lhs._M_in_same_bucket(_Rhs), \
46 _M_message(__msg_local_iter_compare_bad) \
47 ._M_iterator(_Lhs, "lhs") \
48 ._M_iterator(_Rhs, "rhs"))
63 template<
typename _Iterator,
typename _UContainer>
64 class _Safe_local_iterator
68 typedef typename _UContainer::size_type size_type;
72 using _IsConstant = std::__are_same<
73 typename _UContainer::_Base::const_local_iterator, _Iterator>;
75 using _OtherIterator = std::__conditional_t<
77 typename _UContainer::_Base::local_iterator,
78 typename _UContainer::_Base::const_local_iterator>;
80 typedef _Safe_local_iterator _Self;
81 typedef _Safe_local_iterator<_OtherIterator, _UContainer> _OtherSelf;
83 struct _Unchecked { };
90 typedef _Iterator iterator_type;
91 typedef typename _Traits::iterator_category iterator_category;
92 typedef typename _Traits::value_type value_type;
93 typedef typename _Traits::difference_type difference_type;
94 typedef typename _Traits::reference reference;
95 typedef typename _Traits::pointer pointer;
122 _M_message(__msg_init_copy_singular)
123 ._M_iterator(*
this,
"this")
124 ._M_iterator(__x,
"other"));
137 _M_message(__msg_init_copy_singular)
138 ._M_iterator(*
this,
"this")
139 ._M_iterator(__x,
"other"));
140 auto __cont = __x._M_safe_container();
150 template<
typename _MutableIterator>
152 const _Safe_local_iterator<_MutableIterator,
153 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
154 std::__are_same<_MutableIterator, _OtherIterator>::__value,
155 _UContainer>::__type>& __x) noexcept
156 : _Iterator(__x.
base())
162 _M_message(__msg_init_const_singular)
163 ._M_iterator(*
this,
"this")
164 ._M_iterator(__x,
"other"));
178 _M_message(__msg_copy_singular)
179 ._M_iterator(*
this,
"this")
180 ._M_iterator(__x,
"other"));
207 _M_message(__msg_copy_singular)
208 ._M_iterator(*
this,
"this")
209 ._M_iterator(__x,
"other"));
228 __x.
base() = _Iterator();
240 _M_message(__msg_bad_deref)
241 ._M_iterator(*
this,
"this"));
253 _M_message(__msg_bad_deref)
254 ._M_iterator(*
this,
"this"));
255 return base().operator->();
267 _M_message(__msg_bad_inc)
268 ._M_iterator(*
this,
"this"));
282 _M_message(__msg_bad_inc)
283 ._M_iterator(*
this,
"this"));
284 _Safe_local_iterator __ret(*
this, _Unchecked{});
292 static constexpr bool
294 {
return _IsConstant::__value; }
300 base() noexcept {
return *
this; }
303 base() const noexcept {
return *
this; }
315 operator _Iterator()
const {
return *
this; }
349 typename _Distance_traits<_Iterator>::__type
353 std::__conditional_t<
354 _IsConstant::__value,
const _UContainer*, _UContainer*>
355 _M_get_ucontainer()
const
360 return static_cast<_UContainer*
>
366 {
return base() == _M_get_ucontainer()->_M_base().begin(
bucket()); }
370 {
return base() == _M_get_ucontainer()->_M_base().end(
bucket()); }
373 template<
typename _Other>
376 _UContainer>& __other)
const
377 {
return bucket() == __other.bucket(); }
380 operator==(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
382 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
383 return __lhs.base() == __rhs.base();
387 operator==(
const _Self& __lhs,
const _Self& __rhs)
noexcept
389 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
390 return __lhs.base() == __rhs.base();
394 operator!=(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
396 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
397 return __lhs.base() != __rhs.base();
401 operator!=(
const _Self& __lhs,
const _Self& __rhs)
noexcept
403 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
404 return __lhs.base() != __rhs.base();
409 template<
typename _Iterator,
typename _UContainer>
413 typename _Distance_traits<_Iterator>::__type& __dist_info)
414 {
return __first._M_valid_range(__last, __dist_info); }
416 template<
typename _Iterator,
typename _UContainer>
418 __valid_range(
const _Safe_local_iterator<_Iterator, _UContainer>& __first,
419 const _Safe_local_iterator<_Iterator, _UContainer>& __last)
421 typename _Distance_traits<_Iterator>::__type __dist_info;
422 return __first._M_valid_range(__last, __dist_info);
425#if __cplusplus < 201103L
426 template<
typename _Iterator,
typename _UContainer>
428 {
typedef _Iterator _Type; };
431 template<
typename _Iterator,
typename _UContainer>
434 {
return __it.base(); }
438#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
GNU debug classes for public use.
Traits class for iterators.
Struct holding two objects (or references) of arbitrary type.
pointer operator->() const
Iterator dereference.
bool _M_is_end() const
Is this iterator equal to the container's end(bucket) iterator?
void _M_attach_single(const _Safe_unordered_container_base *__cont)
bool _M_in_same_bucket(const _Safe_local_iterator< _Other, _UContainer > &__other) const
Is this iterator part of the same bucket as the other one?
bool _M_dereferenceable() const
Is the iterator dereferenceable?
bool _M_value_initialized() const
Is the iterator value-initialized?
_Safe_local_iterator(const _Safe_local_iterator &__x) noexcept
Copy construction.
size_type bucket() const
Return the bucket.
reference operator*() const
Iterator dereference.
static constexpr bool _S_constant()
Determine if this is a constant iterator.
_Safe_local_iterator operator++(int)
Iterator postincrement.
bool _M_is_begin() const
Is this iterator equal to the container's begin(bucket) iterator?
_Iterator & base() noexcept
Return the underlying iterator.
void _M_attach(const _Safe_unordered_container_base *__cont)
_Safe_local_iterator(_Safe_local_iterator &&__x) noexcept
Move construction.
_Safe_local_iterator() noexcept
_Safe_local_iterator & operator++()
Iterator preincrement.
_Safe_local_iterator & operator=(_Safe_local_iterator &&__x) noexcept
Move assignment.
_Safe_local_iterator(_Iterator __i, const _Safe_unordered_container_base *__cont)
Safe iterator construction from an unsafe iterator and its unordered container.
_Safe_local_iterator(const _Safe_local_iterator< _MutableIterator, typename __gnu_cxx::__enable_if< _IsConstant::__value &&std::__are_same< _MutableIterator, _OtherIterator >::__value, _UContainer >::__type > &__x) noexcept
Converting constructor from a mutable iterator to a constant iterator.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_local_iterator & operator=(const _Safe_local_iterator &__x)
Copy assignment.
bool _M_singular() const noexcept
__gnu_cxx::__mutex & _M_get_mutex() noexcept
const _Safe_sequence_base * _M_sequence
unsigned int _M_version
The container version number. This number may never be 0.
void _M_attach_single(const _Safe_unordered_container_base *__cont, bool __constant) noexcept
_Safe_local_iterator_base()
void _M_attach(const _Safe_unordered_container_base *__cont, bool __constant)
Base class that supports tracking of local iterators that reference an unordered container.