diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2010-08-06 08:58:27 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2010-08-06 08:58:27 +0000 |
commit | cd6b4a4bca97657af9e08583ac92f1833f6191eb (patch) | |
tree | 857b8d6248d007126b20d033165a50c38c343781 /libstdc++-v3/include | |
parent | 0af2372948f7d3eec3b71e78acdecbaec8589926 (diff) | |
download | gcc-cd6b4a4bca97657af9e08583ac92f1833f6191eb.zip gcc-cd6b4a4bca97657af9e08583ac92f1833f6191eb.tar.gz gcc-cd6b4a4bca97657af9e08583ac92f1833f6191eb.tar.bz2 |
ratio (ratio_less): Improve, use ratio_divide to avoid more overflows.
2010-08-06 Paolo Carlini <paolo.carlini@oracle.com>
* include/std/ratio (ratio_less): Improve, use ratio_divide to avoid
more overflows.
* testsuite/20_util/ratio/comparisons/comp1.cc: Extend.
* testsuite/20_util/ratio/comparisons/comp2.cc: Likewise.
From-SVN: r162941
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/std/ratio | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio index e169d79..74806c4 100644 --- a/libstdc++-v3/include/std/ratio +++ b/libstdc++-v3/include/std/ratio @@ -233,23 +233,30 @@ namespace std struct ratio_not_equal : integral_constant<bool, !ratio_equal<_R1, _R2>::value> { }; - + + template<typename _R1> + struct __ratio_less_impl_1 + : integral_constant<bool, _R1::num < _R1::den> + { }; + + template<typename _R1, typename _R2, + bool = (_R1::num == 0 || _R2::num == 0 + || (__static_sign<_R1::num>::value + != __static_sign<_R2::num>::value)), + bool = (__static_sign<_R1::num>::value == -1 + && __static_sign<_R2::num>::value == -1)> + struct __ratio_less_impl + : __ratio_less_impl_1<typename ratio_divide<_R1, _R2>::type>::type + { }; + template<typename _R1, typename _R2> - struct __ratio_less_simple_impl - : integral_constant<bool, - (__safe_multiply<_R1::num, _R2::den>::value - < __safe_multiply<_R2::num, _R1::den>::value)> + struct __ratio_less_impl<_R1, _R2, true, false> + : integral_constant<bool, _R1::num < _R2::num> { }; - // If the denominators are equal or the signs differ, we can just compare - // numerators, otherwise fallback to the simple cross-multiply method. template<typename _R1, typename _R2> - struct __ratio_less_impl - : conditional<(_R1::den == _R2::den - || (__static_sign<_R1::num>::value - != __static_sign<_R2::num>::value)), - integral_constant<bool, (_R1::num < _R2::num)>, - __ratio_less_simple_impl<_R1, _R2>>::type + struct __ratio_less_impl<_R1, _R2, false, true> + : __ratio_less_impl_1<typename ratio_divide<_R2, _R1>::type>::type { }; /// ratio_less |