._M_iterator(_First, #_First) \
._M_integer(_Size, #_Size))
+#define __glibcxx_check_can_increment_dist(_First,_Dist,_Way) \
+ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__can_advance(_First, _Dist, _Way), \
+ _M_message(__gnu_debug::__msg_iter_subscript_oob) \
+ ._M_iterator(_First, #_First) \
+ ._M_integer(_Way * _Dist.first, #_Dist))
+
#define __glibcxx_check_can_increment_range(_First1,_Last1,_First2) \
do \
{ \
._M_iterator(_Last1, #_Last1), \
__FILE__,__LINE__,__PRETTY_FUNCTION__); \
_GLIBCXX_DEBUG_VERIFY_AT_F( \
- __gnu_debug::__can_advance(_First2, __dist.first),\
+ __gnu_debug::__can_advance(_First2, __dist, 1), \
_M_message(__gnu_debug::__msg_iter_subscript_oob)\
._M_iterator(_First2, #_First2) \
._M_integer(__dist.first), \
._M_iterator(_Last1, #_Last1), \
__FILE__,__LINE__,__PRETTY_FUNCTION__); \
_GLIBCXX_DEBUG_VERIFY_AT_F( \
- __gnu_debug::__can_advance(_First2, -__dist.first),\
+ __gnu_debug::__can_advance(_First2, __dist, -1), \
_M_message(__gnu_debug::__msg_iter_subscript_oob)\
._M_iterator(_First2, #_First2) \
._M_integer(-__dist.first), \
if (__n == 0)
return true;
+ std::pair<difference_type, _Distance_precision> __dist = __n < 0
+ ? _M_get_distance_from_begin()
+ : _M_get_distance_to_end();
+
if (__n < 0)
- {
- std::pair<difference_type, _Distance_precision> __dist =
- _M_get_distance_from_begin();
- return __dist.second == __dp_exact
- ? __dist.first >= -__n
- : !__strict && __dist.first > 0;
- }
- else
- {
- std::pair<difference_type, _Distance_precision> __dist =
- _M_get_distance_to_end();
- return __dist.second == __dp_exact
- ? __dist.first >= __n
- : !__strict && __dist.first > 0;
- }
+ __n = -__n;
+
+ return __dist.second > __dp_sign
+ ? __dist.first >= __n
+ : !__strict && __dist.first > 0;
}
+ template<typename _Iterator, typename _Sequence, typename _Category>
+ template<typename _Diff>
+ bool
+ _Safe_iterator<_Iterator, _Sequence, _Category>::
+ _M_can_advance(const std::pair<_Diff, _Distance_precision>& __dist,
+ int __way) const
+ {
+ return __dist.second == __dp_exact
+ ? _M_can_advance(__way * __dist.first)
+ : _M_can_advance(__way * (__dist.first == 0
+ ? 0
+ : __dist.first < 0 ? -1 : 1));
+ }
+
template<typename _Iterator, typename _Sequence, typename _Category>
typename _Distance_traits<_Iterator>::__type
_Safe_iterator<_Iterator, _Sequence, _Category>::
/* Determine iterators order */
__dist = _M_get_distance_to(__rhs);
- switch (__dist.second)
+ if (__dist.second != __dp_equality)
{
- case __dp_equality:
- if (__dist.first == 0)
- return true;
- break;
-
- case __dp_sign:
- case __dp_exact:
// If range is not empty first iterator must be dereferenceable.
- if (__dist.first > 0)
- return !__check_dereferenceable || _M_dereferenceable();
- return __dist.first == 0;
+ return __dist.first == 0
+ || (__dist.first > 0
+ && (!__check_dereferenceable || _M_dereferenceable()));
}
// Assume that this is a valid range; we can't check anything else.
__dist = std::make_pair(__rhs.base() - this->base(), __dp_exact);
// If range is not empty first iterator must be dereferenceable.
- if (__dist.first > 0)
- return this->_M_dereferenceable();
- return __dist.first == 0;
+ return __dist.first == 0
+ || (__dist.first > 0 && this->_M_dereferenceable());
}
} // namespace __gnu_debug
{
typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
- __glibcxx_check_can_increment(__result, __dist.first);
+ __glibcxx_check_can_increment_dist(__result, __dist, 1);
if (__dist.second > ::__gnu_debug::__dp_equality)
return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
{
typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
- __glibcxx_check_can_increment(__result, __dist.first);
+ __glibcxx_check_can_increment_dist(__result, __dist, 1);
if (__dist.second > ::__gnu_debug::__dp_sign
&& __result._M_can_advance(__dist.first, true))
{
typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
- __glibcxx_check_can_increment(__result, __dist.first);
+ __glibcxx_check_can_increment_dist(__result, __dist, 1);
if (__dist.second > ::__gnu_debug::__dp_equality)
{
{
typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
- __glibcxx_check_can_increment(__result, -__dist.first);
+ __glibcxx_check_can_increment_dist(__result, __dist, -1);
if (__dist.second > ::__gnu_debug::__dp_equality)
return std::__copy_move_backward_a<_IsMove>(
{
typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
- __glibcxx_check_can_increment(__result, -__dist.first);
+ __glibcxx_check_can_increment_dist(__result, __dist, -1);
if (__dist.second > ::__gnu_debug::__dp_sign
&& __result._M_can_advance(-__dist.first, true))
{
typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
__glibcxx_check_valid_range2(__first, __last, __dist);
- __glibcxx_check_can_increment(__result, -__dist.first);
+ __glibcxx_check_can_increment_dist(__result, __dist, -1);
if (__dist.second > ::__gnu_debug::__dp_equality)
{
{
typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
__glibcxx_check_valid_range2(__first1, __last1, __dist);
- __glibcxx_check_can_increment(__first2, __dist.first);
+ __glibcxx_check_can_increment_dist(__first2, __dist, 1);
if (__dist.second > ::__gnu_debug::__dp_equality)
return std::__equal_aux(__first1.base(), __last1.base(), __first2);
{
typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
__glibcxx_check_valid_range2(__first1, __last1, __dist);
- __glibcxx_check_can_increment(__first2, __dist.first);
+ __glibcxx_check_can_increment_dist(__first2, __dist, 1);
if (__dist.second > ::__gnu_debug::__dp_sign
&& __first2._M_can_advance(__dist.first, true))
{
typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
__glibcxx_check_valid_range2(__first1, __last1, __dist);
- __glibcxx_check_can_increment(__first2, __dist.first);
+ __glibcxx_check_can_increment_dist(__first2, __dist, 1);
if (__dist.second > ::__gnu_debug::__dp_equality)
{
__can_advance(const std::reverse_iterator<_Iterator>& __it, _Size __n)
{ return __can_advance(__it.base(), -__n); }
+ template<typename _Iterator, typename _Diff>
+ inline bool
+ __can_advance(const std::reverse_iterator<_Iterator>& __it,
+ const std::pair<_Diff, _Distance_precision>& __dist,
+ int __way)
+ { return __can_advance(__it.base(), __dist, -__way); }
+
template<typename _Iterator, typename _Sequence>
inline std::reverse_iterator<_Iterator>
__base(const std::reverse_iterator<_Safe_iterator<
__can_advance(const std::move_iterator<_Iterator>& __it, _Size __n)
{ return __can_advance(__it.base(), __n); }
+ template<typename _Iterator, typename _Diff>
+ inline bool
+ __can_advance(const std::move_iterator<_Iterator>& __it,
+ const std::pair<_Diff, _Distance_precision>& __dist,
+ int __way)
+ { return __can_advance(__it.base(), __dist, __way); }
+
template<typename _Iterator>
inline auto
__unsafe(const std::move_iterator<_Iterator>& __it)