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>
PR libstdc++/81091
......
......@@ -911,7 +911,7 @@ namespace __gnu_debug
_S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
{
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
*/
enum _Distance_precision
{
__dp_none, // Not even an iterator type
__dp_equality, //< Can compare iterator equality, only
__dp_sign, //< Can determine equality and ordering
__dp_exact //< Can determine distance precisely
__dp_none, // Not even an iterator type
__dp_equality, //< Can compare iterator equality, only
__dp_sign, //< Can determine equality and ordering
__dp_sign_max_size, //< __dp_sign and gives max range size
__dp_exact //< Can determine distance precisely
};
template<typename _Iterator,
......@@ -176,6 +177,7 @@ namespace __gnu_debug
return true;
break;
case __dp_sign:
case __dp_sign_max_size:
case __dp_exact:
return __dist.first >= 0;
}
......
......@@ -916,7 +916,7 @@ namespace __gnu_debug
_S_size(const std::__debug::list<_Tp, _Alloc>& __seq)
{
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
......
......@@ -113,18 +113,22 @@ namespace __gnu_debug
_Safe_iterator<_Iterator, _Sequence, _Category>::
_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;
if (this->base() == __rhs.base())
return std::make_pair(0, __dp_exact);
_Dist __base_dist = __get_distance(this->base(), __rhs.base());
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 (__rhs._M_is_begin())
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())
......@@ -133,30 +137,42 @@ namespace __gnu_debug
return std::make_pair(-1, __dp_exact);
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 (__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())
{
_Diff __diff = _SeqTraits::_S_size(*this->_M_get_sequence());
return std::make_pair(-__diff.first, __diff.second);
}
return std::make_pair(-__seq_dist.first, __seq_dist.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())
return std::make_pair(-1, __dp_sign);
if (__rhs._M_is_before_begin())
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())
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);
}
......
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