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
66 ,
public _Safe_local_iterator_base
68 typedef _Iterator _Iter_base;
71 typedef typename _UContainer::size_type size_type;
75 using _IsConstant = std::__are_same<
76 typename _UContainer::_Base::const_local_iterator, _Iterator>;
78 using _OtherIterator = std::__conditional_t<
80 typename _UContainer::_Base::local_iterator,
81 typename _UContainer::_Base::const_local_iterator>;
84 typedef _Safe_local_iterator<_OtherIterator, _UContainer> _OtherSelf;
86 struct _Unchecked { };
90 : _Iter_base(__x.base())
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;
113 : _Iter_base(__i), _Safe_base(__cont,
_S_constant())
120 : _Iter_base(__x.base())
124 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
125 || __x._M_value_initialized(),
126 _M_message(__msg_init_copy_singular)
127 ._M_iterator(*
this,
"this")
128 ._M_iterator(__x,
"other"));
139 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
140 || __x._M_value_initialized(),
141 _M_message(__msg_init_copy_singular)
142 ._M_iterator(*
this,
"this")
143 ._M_iterator(__x,
"other"));
144 auto __cont = __x._M_safe_container();
146 std::swap(
base(), __x.base());
154 template<
typename _MutableIterator>
157 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
158 std::__are_same<_MutableIterator, _OtherIterator>::__value,
159 _UContainer>::__type>& __x) noexcept
160 : _Iter_base(__x.base())
164 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
165 || __x._M_value_initialized(),
166 _M_message(__msg_init_const_singular)
167 ._M_iterator(*
this,
"this")
168 ._M_iterator(__x,
"other"));
180 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
181 || __x._M_value_initialized(),
182 _M_message(__msg_copy_singular)
183 ._M_iterator(*
this,
"this")
184 ._M_iterator(__x,
"other"));
209 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
210 || __x._M_value_initialized(),
211 _M_message(__msg_copy_singular)
212 ._M_iterator(*
this,
"this")
213 ._M_iterator(__x,
"other"));
232 __x.base() = _Iterator();
244 _M_message(__msg_bad_deref)
245 ._M_iterator(*
this,
"this"));
257 _M_message(__msg_bad_deref)
258 ._M_iterator(*
this,
"this"));
259 return base().operator->();
271 _M_message(__msg_bad_inc)
272 ._M_iterator(*
this,
"this"));
286 _M_message(__msg_bad_inc)
287 ._M_iterator(*
this,
"this"));
296 static constexpr
bool 298 {
return _IsConstant::__value; }
304 base() noexcept {
return *
this; }
307 base()
const noexcept {
return *
this; }
319 operator _Iterator()
const {
return *
this; }
357 std::__conditional_t<
358 _IsConstant::__value,
const _UContainer*, _UContainer*>
359 _M_get_ucontainer()
const 364 return static_cast<_UContainer*
> 370 {
return base() == _M_get_ucontainer()->_M_base().begin(
bucket()); }
374 {
return base() == _M_get_ucontainer()->_M_base().end(
bucket()); }
377 template<
typename _Other>
380 _UContainer>& __other)
const 381 {
return bucket() == __other.bucket(); }
384 operator==(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
386 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
387 return __lhs.
base() == __rhs.
base();
391 operator==(
const _Self& __lhs,
const _Self& __rhs) noexcept
393 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
394 return __lhs.
base() == __rhs.
base();
398 operator!=(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
400 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
401 return __lhs.
base() != __rhs.
base();
405 operator!=(
const _Self& __lhs,
const _Self& __rhs) noexcept
407 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
408 return __lhs.
base() != __rhs.
base();
413 template<
typename _Iterator,
typename _UContainer>
418 {
return __first._M_valid_range(__last, __dist_info); }
420 template<
typename _Iterator,
typename _UContainer>
426 return __first._M_valid_range(__last, __dist_info);
429 #if __cplusplus < 201103L 430 template<
typename _Iterator,
typename _UContainer>
431 struct _Unsafe_type<_Safe_local_iterator<_Iterator, _UContainer> >
432 {
typedef _Iterator _Type; };
435 template<
typename _Iterator,
typename _UContainer>
438 {
return __it.base(); }
442 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS void _M_attach(const _Safe_unordered_container_base *__cont)
_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.
size_type bucket() const
Return the bucket.
void _M_attach(const _Safe_unordered_container_base *__cont, bool __constant)
_Safe_local_iterator(_Iterator __i, const _Safe_unordered_container_base *__cont)
Safe iterator construction from an unsafe iterator and its unordered container.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_local_iterator() noexcept
_Safe_local_iterator & operator++()
Iterator preincrement.
bool _M_singular() const noexcept
const _Safe_sequence_base * _M_sequence
bool _M_is_begin() const
Is this iterator equal to the container's begin(bucket) iterator?
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)
_Safe_local_iterator(_Safe_local_iterator &&__x) noexcept
Move construction.
void _M_attach_single(const _Safe_unordered_container_base *__cont, bool __constant) noexcept
_Safe_local_iterator & operator=(const _Safe_local_iterator &__x)
Copy assignment.
ISO C++ entities toplevel namespace is std.
_Safe_local_iterator_base()
GNU debug classes for public use.
_Safe_local_iterator & operator=(_Safe_local_iterator &&__x) noexcept
Move assignment.
Struct holding two objects of arbitrary type.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
reference operator*() const
Iterator dereference.
_Iterator & base() noexcept
Return the underlying iterator.
bool _M_value_initialized() const
Is the iterator value-initialized?
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
__gnu_cxx::__mutex & _M_get_mutex() noexcept
static constexpr bool _S_constant()
Determine if this is a constant iterator.
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?
_Safe_local_iterator(const _Safe_local_iterator &__x) noexcept
Copy construction.
Base class that supports tracking of local iterators that reference an unordered container.
Traits class for iterators.
_Safe_local_iterator operator++(int)
Iterator postincrement.
pointer operator->() const
Iterator dereference.