Commit 36edf9ca by François Dumont

Improve _GLIBCXX_DEBUG safe iterator range size computation.

	* include/debug/forward_list
	(_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign
	distance when not empty.
	* include/debug/list (_Sequence_traits<__debug::list<>>::_S_size):
	Likewise.
	* include/debug/helper_functions.h (__dp_sign_max_size): New
	_Distance_precision enum entry.
	(__valid_range_aux(_IIte, _IIte, _Distance_traits<>::__type,
	__false_type)): Adapt.
	* include/debug/safe_iterator.tcc
	(_Safe_iterator<>::_M_get_distance_to(const _Safe_iterator&)): Review
	distance computation.

From-SVN: r276600
parent 9af0d5ef
2019-10-04 François Dumont <fdumont@gcc.gnu.org>
* include/debug/forward_list
(_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign
distance when not empty.
* include/debug/list (_Sequence_traits<__debug::list<>>::_S_size):
Likewise.
* include/debug/helper_functions.h (__dp_sign_max_size): New
_Distance_precision enum entry.
(__valid_range_aux(_IIte, _IIte, _Distance_traits<>::__type,
__false_type)): Adapt.
* include/debug/safe_iterator.tcc
(_Safe_iterator<>::_M_get_distance_to(const _Safe_iterator&)): Review
distance computation.
2019-10-04 Jonathan Wakely <jwakely@redhat.com> 2019-10-04 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/81091 PR libstdc++/81091
......
...@@ -911,7 +911,7 @@ namespace __gnu_debug ...@@ -911,7 +911,7 @@ namespace __gnu_debug
_S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq) _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
{ {
return __seq.empty() return __seq.empty()
? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality); ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
} }
}; };
......
...@@ -50,10 +50,11 @@ namespace __gnu_debug ...@@ -50,10 +50,11 @@ namespace __gnu_debug
*/ */
enum _Distance_precision enum _Distance_precision
{ {
__dp_none, // Not even an iterator type __dp_none, // Not even an iterator type
__dp_equality, //< Can compare iterator equality, only __dp_equality, //< Can compare iterator equality, only
__dp_sign, //< Can determine equality and ordering __dp_sign, //< Can determine equality and ordering
__dp_exact //< Can determine distance precisely __dp_sign_max_size, //< __dp_sign and gives max range size
__dp_exact //< Can determine distance precisely
}; };
template<typename _Iterator, template<typename _Iterator,
...@@ -176,6 +177,7 @@ namespace __gnu_debug ...@@ -176,6 +177,7 @@ namespace __gnu_debug
return true; return true;
break; break;
case __dp_sign: case __dp_sign:
case __dp_sign_max_size:
case __dp_exact: case __dp_exact:
return __dist.first >= 0; return __dist.first >= 0;
} }
......
...@@ -916,7 +916,7 @@ namespace __gnu_debug ...@@ -916,7 +916,7 @@ namespace __gnu_debug
_S_size(const std::__debug::list<_Tp, _Alloc>& __seq) _S_size(const std::__debug::list<_Tp, _Alloc>& __seq)
{ {
return __seq.empty() return __seq.empty()
? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality); ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
} }
}; };
#endif #endif
......
...@@ -113,18 +113,22 @@ namespace __gnu_debug ...@@ -113,18 +113,22 @@ namespace __gnu_debug
_Safe_iterator<_Iterator, _Sequence, _Category>:: _Safe_iterator<_Iterator, _Sequence, _Category>::
_M_get_distance_to(const _Safe_iterator& __rhs) const _M_get_distance_to(const _Safe_iterator& __rhs) const
{ {
typedef typename _Distance_traits<_Iterator>::__type _Diff; typedef typename _Distance_traits<_Iterator>::__type _Dist;
typedef _Sequence_traits<_Sequence> _SeqTraits; typedef _Sequence_traits<_Sequence> _SeqTraits;
if (this->base() == __rhs.base()) _Dist __base_dist = __get_distance(this->base(), __rhs.base());
return std::make_pair(0, __dp_exact); if (__base_dist.second == __dp_exact)
return __base_dist;
_Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
if (this->_M_is_before_begin()) if (this->_M_is_before_begin())
{ {
if (__rhs._M_is_begin()) if (__rhs._M_is_begin())
return std::make_pair(1, __dp_exact); return std::make_pair(1, __dp_exact);
return std::make_pair(1, __dp_sign); return __seq_dist.second == __dp_exact
? std::make_pair(__seq_dist.first + 1, __dp_exact)
: __seq_dist;
} }
if (this->_M_is_begin()) if (this->_M_is_begin())
...@@ -133,30 +137,42 @@ namespace __gnu_debug ...@@ -133,30 +137,42 @@ namespace __gnu_debug
return std::make_pair(-1, __dp_exact); return std::make_pair(-1, __dp_exact);
if (__rhs._M_is_end()) if (__rhs._M_is_end())
return _SeqTraits::_S_size(*this->_M_get_sequence()); return __seq_dist;
return std::make_pair(1, __dp_sign); return std::make_pair(__seq_dist.first,
__seq_dist.second == __dp_exact
? __dp_sign_max_size : __seq_dist.second);
} }
if (this->_M_is_end()) if (this->_M_is_end())
{ {
if (__rhs._M_is_before_begin()) if (__rhs._M_is_before_begin())
return std::make_pair(-1, __dp_exact); return __seq_dist.second == __dp_exact
? std::make_pair(-__seq_dist.first - 1, __dp_exact)
: std::make_pair(-__seq_dist.first, __dp_sign);
if (__rhs._M_is_begin()) if (__rhs._M_is_begin())
{ return std::make_pair(-__seq_dist.first, __seq_dist.second);
_Diff __diff = _SeqTraits::_S_size(*this->_M_get_sequence());
return std::make_pair(-__diff.first, __diff.second);
}
return std::make_pair(-1, __dp_sign); return std::make_pair(-__seq_dist.first,
__seq_dist.second == __dp_exact
? __dp_sign_max_size : __seq_dist.second);
} }
if (__rhs._M_is_before_begin() || __rhs._M_is_begin()) if (__rhs._M_is_before_begin())
return std::make_pair(-1, __dp_sign); return __seq_dist.second == __dp_exact
? std::make_pair(__seq_dist.first - 1, __dp_exact)
: std::make_pair(-__seq_dist.first, __dp_sign);
if (__rhs._M_is_begin())
return std::make_pair(-__seq_dist.first,
__seq_dist.second == __dp_exact
? __dp_sign_max_size : __seq_dist.second);
if (__rhs._M_is_end()) if (__rhs._M_is_end())
return std::make_pair(1, __dp_sign); return std::make_pair(__seq_dist.first,
__seq_dist.second == __dp_exact
? __dp_sign_max_size : __seq_dist.second);
return std::make_pair(1, __dp_equality); return std::make_pair(1, __dp_equality);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment