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 _Sequence>
68 typedef _Iterator _Iter_base;
71 typedef typename _Sequence::size_type size_type;
75 typedef std::__are_same<
76 typename _Sequence::_Base::const_local_iterator,
77 _Iterator> _IsConstant;
79 typedef typename __gnu_cxx::__conditional_type<_IsConstant::__value,
80 typename _Sequence::_Base::local_iterator,
81 typename _Sequence::_Base::const_local_iterator>::__type
88 typedef _Iterator iterator_type;
89 typedef typename _Traits::iterator_category iterator_category;
90 typedef typename _Traits::value_type value_type;
91 typedef typename _Traits::difference_type difference_type;
92 typedef typename _Traits::reference reference;
93 typedef typename _Traits::pointer pointer;
109 _M_message(__msg_init_singular)
110 ._M_iterator(*
this,
"this"));
117 : _Iter_base(__x.base())
121 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
122 || __x._M_value_initialized(),
123 _M_message(__msg_init_copy_singular)
124 ._M_iterator(*
this,
"this")
125 ._M_iterator(__x,
"other"));
136 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
137 || __x._M_value_initialized(),
138 _M_message(__msg_init_copy_singular)
139 ._M_iterator(*
this,
"this")
140 ._M_iterator(__x,
"other"));
141 auto __cont = __x._M_sequence;
143 std::swap(
base(), __x.base());
151 template<
typename _MutableIterator>
154 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
155 std::__are_same<_MutableIterator, _OtherIterator>::__value,
156 _Sequence>::__type>& __x) noexcept
157 : _Iter_base(__x.base())
161 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
162 || __x._M_value_initialized(),
163 _M_message(__msg_init_const_singular)
164 ._M_iterator(*
this,
"this")
165 ._M_iterator(__x,
"other"));
179 _M_message(__msg_copy_singular)
180 ._M_iterator(*
this,
"this")
181 ._M_iterator(__x,
"other"));
206 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
207 || __x._M_value_initialized(),
208 _M_message(__msg_copy_singular)
209 ._M_iterator(*
this,
"this")
210 ._M_iterator(__x,
"other"));
229 __x.base() = _Iterator();
241 _M_message(__msg_bad_deref)
242 ._M_iterator(*
this,
"this"));
254 _M_message(__msg_bad_deref)
255 ._M_iterator(*
this,
"this"));
256 return base().operator->();
268 _M_message(__msg_bad_inc)
269 ._M_iterator(*
this,
"this"));
283 _M_message(__msg_bad_inc)
284 ._M_iterator(*
this,
"this"));
293 static constexpr bool
295 {
return _IsConstant::__value; }
301 base() noexcept {
return *
this; }
304 base() const noexcept {
return *
this; }
316 operator _Iterator()
const {
return *
this; }
354 typename __gnu_cxx::__conditional_type<
355 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
356 _M_get_sequence()
const
361 {
return base() == _M_get_sequence()->_M_base().begin(
bucket()); }
365 {
return base() == _M_get_sequence()->_M_base().end(
bucket()); }
368 template<
typename _Other>
371 _Sequence>& __other)
const
372 {
return bucket() == __other.bucket(); }
375 operator==(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
377 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
378 return __lhs.base() == __rhs.base();
382 operator==(
const _Self& __lhs,
const _Self& __rhs)
noexcept
384 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
385 return __lhs.base() == __rhs.base();
389 operator!=(
const _Self& __lhs,
const _OtherSelf& __rhs)
noexcept
391 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
392 return __lhs.base() != __rhs.base();
396 operator!=(
const _Self& __lhs,
const _Self& __rhs)
noexcept
398 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
399 return __lhs.base() != __rhs.base();
404 template<
typename _Iterator,
typename _Sequence>
409 {
return __first._M_valid_range(__last, __dist_info); }
411 template<
typename _Iterator,
typename _Sequence>
413 __valid_range(
const _Safe_local_iterator<_Iterator, _Sequence>& __first,
414 const _Safe_local_iterator<_Iterator, _Sequence>& __last)
416 typename _Distance_traits<_Iterator>::__type __dist_info;
417 return __first._M_valid_range(__last, __dist_info);
420#if __cplusplus < 201103L
421 template<
typename _Iterator,
typename _Sequence>
422 struct _Unsafe_type<_Safe_local_iterator<_Iterator, _Sequence> >
423 {
typedef _Iterator _Type; };
426 template<
typename _Iterator,
typename _Sequence>
428 __unsafe(
const _Safe_local_iterator<_Iterator, _Sequence>& __it)
429 {
return __it.base(); }
433#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
ISO C++ entities toplevel namespace is std.
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.
_Safe_local_iterator & operator=(_Safe_local_iterator &&__x) noexcept
Move assignment.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_local_iterator(_Safe_local_iterator &&__x) noexcept
Move construction.
bool _M_value_initialized() const
Is the iterator value-initialized?
_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?
_Safe_local_iterator & operator++()
Iterator preincrement.
_Safe_local_iterator & operator=(const _Safe_local_iterator &__x)
Copy assignment.
pointer operator->() const
Iterator dereference.
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.
_Iterator & base() noexcept
Return the underlying iterator.
_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)
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)