diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/std/ratio | 33 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc | 9 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc | 9 |
4 files changed, 42 insertions, 16 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 42db5964de8..8cd8bb2efdf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +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. + 2010-08-05 Paolo Carlini <paolo.carlini@oracle.com> * include/tr1_impl/utility (begin, end): Remove per GB 85. diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio index e169d79e8a5..74806c41d5a 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 diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc index f4354fe96bf..eb1bd212f5a 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc @@ -1,7 +1,7 @@ // { dg-options "-std=gnu++0x" } // { dg-require-cstdint "" } -// Copyright (C) 2008, 2009 Free Software Foundation +// Copyright (C) 2008, 2009, 2010 Free Software Foundation // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -45,7 +45,12 @@ test02() VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<1,4>>::value == 0) ); VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<-1,3>>::value == 0) ); - + + VERIFY( (std::ratio_less<std::ratio<-1,3>, std::ratio<-1,4>>::value == 1) ); + VERIFY( (std::ratio_less<std::ratio<0,4>, std::ratio<0,3>>::value == 0) ); + VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<0,3>>::value == 0) ); + VERIFY( (std::ratio_less<std::ratio<0,3>, std::ratio<-1,4>>::value == 0) ); + VERIFY( (std::ratio_less_equal<std::ratio<-1,3>, std::ratio<-1,3>>::value == 1) ); VERIFY( ( std::ratio_less_equal<std::ratio<1,4>, diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc index e741c143510..151dc64450e 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc @@ -1,7 +1,7 @@ // { dg-options "-std=gnu++0x" } // { dg-require-cstdint "" } -// Copyright (C) 2008, 2009 Free Software Foundation +// Copyright (C) 2008, 2009, 2010 Free Software Foundation // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -41,6 +41,13 @@ test01() VERIFY( (std::ratio_less<std::ratio<M - 1, M - 2>, std::ratio<-M, M - 1>>::value == 0) ); + + // No overflow + VERIFY( (std::ratio_less<std::ratio<M, M - 1>, + std::ratio<M, M - 2>>::value == 1) ); + + VERIFY( (std::ratio_less<std::ratio<-M, M - 1>, + std::ratio<-M, M - 2>>::value == 0) ); } int main() |