diff options
author | François Dumont <fdumont@gcc.gnu.org> | 2019-10-04 20:22:11 +0000 |
---|---|---|
committer | François Dumont <fdumont@gcc.gnu.org> | 2019-10-04 20:22:11 +0000 |
commit | 36edf9cab1d4a444497c2aaf57c4ce61f7a67901 (patch) | |
tree | a88be7904712db89fc6c702cc4caf00bb41b371d | |
parent | 9af0d5ef3b14a9b3e4b0cb6aaaaba44ea722fb06 (diff) | |
download | gcc-36edf9cab1d4a444497c2aaf57c4ce61f7a67901.zip gcc-36edf9cab1d4a444497c2aaf57c4ce61f7a67901.tar.gz gcc-36edf9cab1d4a444497c2aaf57c4ce61f7a67901.tar.bz2 |
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
-rw-r--r-- | libstdc++-v3/ChangeLog | 15 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/forward_list | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/helper_functions.h | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/list | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/safe_iterator.tcc | 46 |
5 files changed, 54 insertions, 21 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4e822de..26d37d7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +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 diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index e30b000..f1756dd 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -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); } }; diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h index 475fdda..5a920bb 100644 --- a/libstdc++-v3/include/debug/helper_functions.h +++ b/libstdc++-v3/include/debug/helper_functions.h @@ -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; } diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index 5eb9a60..140546a 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -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 diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 581c51c..1750bc4 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -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); } |