Commit cd6b4a4b by Paolo Carlini Committed by Paolo Carlini

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
parent 0af23729
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> 2010-08-05 Paolo Carlini <paolo.carlini@oracle.com>
* include/tr1_impl/utility (begin, end): Remove per GB 85. * include/tr1_impl/utility (begin, end): Remove per GB 85.
......
...@@ -233,23 +233,30 @@ namespace std ...@@ -233,23 +233,30 @@ namespace std
struct ratio_not_equal struct ratio_not_equal
: integral_constant<bool, !ratio_equal<_R1, _R2>::value> : 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> template<typename _R1, typename _R2>
struct __ratio_less_simple_impl struct __ratio_less_impl<_R1, _R2, true, false>
: integral_constant<bool, : integral_constant<bool, _R1::num < _R2::num>
(__safe_multiply<_R1::num, _R2::den>::value
< __safe_multiply<_R2::num, _R1::den>::value)>
{ }; { };
// 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> template<typename _R1, typename _R2>
struct __ratio_less_impl struct __ratio_less_impl<_R1, _R2, false, true>
: conditional<(_R1::den == _R2::den : __ratio_less_impl_1<typename ratio_divide<_R2, _R1>::type>::type
|| (__static_sign<_R1::num>::value
!= __static_sign<_R2::num>::value)),
integral_constant<bool, (_R1::num < _R2::num)>,
__ratio_less_simple_impl<_R1, _R2>>::type
{ }; { };
/// ratio_less /// ratio_less
......
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" } // { 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 // 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 // software; you can redistribute it and/or modify it under the
...@@ -45,7 +45,12 @@ test02() ...@@ -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,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,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>, VERIFY( (std::ratio_less_equal<std::ratio<-1,3>,
std::ratio<-1,3>>::value == 1) ); std::ratio<-1,3>>::value == 1) );
VERIFY( ( std::ratio_less_equal<std::ratio<1,4>, VERIFY( ( std::ratio_less_equal<std::ratio<1,4>,
......
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" } // { 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 // 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 // software; you can redistribute it and/or modify it under the
...@@ -41,6 +41,13 @@ test01() ...@@ -41,6 +41,13 @@ test01()
VERIFY( (std::ratio_less<std::ratio<M - 1, M - 2>, VERIFY( (std::ratio_less<std::ratio<M - 1, M - 2>,
std::ratio<-M, M - 1>>::value == 0) ); 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() int main()
......
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