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.base() == _Iterator{} \
37 && _Rhs.base() == _Iterator{}), \
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>
64 class _Safe_local_iterator
66 ,
public _Safe_local_iterator_base
68 typedef _Iterator _Iter_base;
69 typedef _Safe_local_iterator_base _Safe_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
85 typedef _Safe_local_iterator<_OtherIterator, _Sequence> _OtherSelf;
91 _Attach_single) noexcept
96 typedef _Iterator iterator_type;
97 typedef typename _Traits::iterator_category iterator_category;
98 typedef typename _Traits::value_type value_type;
99 typedef typename _Traits::difference_type difference_type;
100 typedef typename _Traits::reference reference;
101 typedef typename _Traits::pointer pointer;
116 _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
117 _M_message(__msg_init_singular)
118 ._M_iterator(*
this,
"this"));
125 : _Iter_base(__x.base())
129 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
130 || __x.base() == _Iterator(),
131 _M_message(__msg_init_copy_singular)
132 ._M_iterator(*
this,
"this")
133 ._M_iterator(__x,
"other"));
144 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
145 || __x.base() == _Iterator(),
146 _M_message(__msg_init_copy_singular)
147 ._M_iterator(*
this,
"this")
148 ._M_iterator(__x,
"other"));
149 auto __cont = __x._M_sequence;
151 std::swap(
base(), __x.base());
159 template<
typename _MutableIterator>
162 typename __gnu_cxx::__enable_if<_IsConstant::__value &&
163 std::__are_same<_MutableIterator, _OtherIterator>::__value,
164 _Sequence>::__type>& __x) noexcept
165 : _Iter_base(__x.base())
169 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
170 || __x.base() == _MutableIterator(),
171 _M_message(__msg_init_const_singular)
172 ._M_iterator(*
this,
"this")
173 ._M_iterator(__x,
"other"));
185 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
186 || __x.base() == _Iterator(),
187 _M_message(__msg_copy_singular)
188 ._M_iterator(*
this,
"this")
189 ._M_iterator(__x,
"other"));
191 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
195 _M_version = __x._M_sequence->_M_version;
214 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
215 || __x.base() == _Iterator(),
216 _M_message(__msg_copy_singular)
217 ._M_iterator(*
this,
"this")
218 ._M_iterator(__x,
"other"));
223 if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
227 _M_version = __x._M_sequence->_M_version;
237 __x.base() = _Iterator();
249 _M_message(__msg_bad_deref)
250 ._M_iterator(*
this,
"this"));
262 _M_message(__msg_bad_deref)
263 ._M_iterator(*
this,
"this"));
264 return base().operator->();
276 _M_message(__msg_bad_inc)
277 ._M_iterator(*
this,
"this"));
291 _M_message(__msg_bad_inc)
292 ._M_iterator(*
this,
"this"));
301 static constexpr
bool
303 {
return _IsConstant::__value; }
309 base() noexcept {
return *
this; }
312 base() const noexcept {
return *
this; }
324 operator _Iterator()
const {
return *
this; }
339 {
return !this->_M_singular() && !
_M_is_end(); }
344 {
return !this->_M_singular() && !
_M_is_end(); }
357 typename __gnu_cxx::__conditional_type<
358 _IsConstant::__value,
const _Sequence*, _Sequence*>::__type
359 _M_get_sequence()
const
360 {
return static_cast<_Sequence*
>(_M_sequence); }
364 {
return base() == _M_get_sequence()->_M_base().begin(
bucket()); }
368 {
return base() == _M_get_sequence()->_M_base().end(
bucket()); }
371 template<
typename _Other>
374 _Sequence>& __other)
const
375 {
return bucket() == __other.bucket(); }
378 operator==(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
380 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
381 return __lhs.base() == __rhs.base();
385 operator==(
const _Self& __lhs,
const _Self& __rhs) noexcept
387 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
388 return __lhs.base() == __rhs.base();
392 operator!=(
const _Self& __lhs,
const _OtherSelf& __rhs) noexcept
394 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
395 return __lhs.base() != __rhs.base();
399 operator!=(
const _Self& __lhs,
const _Self& __rhs) noexcept
401 _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
402 return __lhs.base() != __rhs.base();
407 template<
typename _Iterator,
typename _Sequence>
412 {
return __first._M_valid_range(__last, __dist_info); }
414 template<
typename _Iterator,
typename _Sequence>
416 __valid_range(
const _Safe_local_iterator<_Iterator, _Sequence>& __first,
417 const _Safe_local_iterator<_Iterator, _Sequence>& __last)
419 typename _Distance_traits<_Iterator>::__type __dist_info;
420 return __first._M_valid_range(__last, __dist_info);
423 #if __cplusplus < 201103L
424 template<
typename _Iterator,
typename _Sequence>
425 struct _Unsafe_type<_Safe_local_iterator<_Iterator, _Sequence> >
426 {
typedef _Iterator _Type; };
429 template<
typename _Iterator,
typename _Sequence>
431 __unsafe(
const _Safe_local_iterator<_Iterator, _Sequence>& __it)
432 {
return __it.base(); }
436 #undef _GLIBCXX_DEBUG_VERIFY_OPERANDS