Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r65885 - in sandbox/chrono/boost/ratio: . detail
From: vicente.botet_at_[hidden]
Date: 2010-10-10 12:58:17


Author: viboes
Date: 2010-10-10 12:58:14 EDT (Sun, 10 Oct 2010)
New Revision: 65885
URL: http://svn.boost.org/trac/boost/changeset/65885

Log:
Ratio:
* Change detail namespace by ratio_detail
* Move helper to specific file
* Move general use metafunctions to StaticInteger lib
* Prefix intmax_t by boost::
* Define the variable ABS_N and ABS_D before asserting
* Provide ratio constructor and assignment from an equivalent ration conditionally
* Make ratio arithmetic operation inherit from ratio
* Remove #if 0
* Make public ratio_gcd as used by Boost.Chrono
Added:
   sandbox/chrono/boost/ratio/detail/
   sandbox/chrono/boost/ratio/detail/overflow_helpers.hpp (contents, props changed)
Text files modified:
   sandbox/chrono/boost/ratio/ratio.hpp | 412 +++------------------------------------
   1 files changed, 31 insertions(+), 381 deletions(-)

Added: sandbox/chrono/boost/ratio/detail/overflow_helpers.hpp
==============================================================================
--- (empty file)
+++ sandbox/chrono/boost/ratio/detail/overflow_helpers.hpp 2010-10-10 12:58:14 EDT (Sun, 10 Oct 2010)
@@ -0,0 +1,381 @@
+// ratio.hpp ---------------------------------------------------------------//
+
+// Copyright 2008 Howard Hinnant
+// Copyright 2008 Beman Dawes
+// Copyright 2009 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+
+This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
+Many thanks to Howard for making his code available under the Boost license.
+The original code was modified to conform to Boost conventions and to section
+20.4 Compile-time rational arithmetic [ratio], of the C++ committee working
+paper N2798.
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
+
+time2_demo contained this comment:
+
+ Much thanks to Andrei Alexandrescu,
+ Walter Brown,
+ Peter Dimov,
+ Jeff Garland,
+ Terry Golubiewski,
+ Daniel Krügler,
+ Anthony Williams.
+*/
+
+// The way overflow is managed for ratio_less is taken from llvm/libcxx/include/ratio
+
+#ifndef BOOST_RATIO_DETAIL_RATIO_OPERATIONS_HPP
+#define BOOST_RATIO_DETAIL_RATIO_OPERATIONS_HPP
+
+#include <boost/static_integer/static_abs.hpp>
+#include <boost/static_integer/static_sign.hpp>
+#include <boost/static_integer/static_lcm.hpp>
+#include <boost/static_integer/static_gcd.hpp>
+#include <cstdlib>
+#include <climits>
+#include <limits>
+#include <boost/cstdint.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/integer_traits.hpp>
+
+#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_RATIO_USES_MPL_ASSERT)
+#define BOOST_RATIO_OVERFLOW_IN_ADD "overflow in ratio add"
+#define BOOST_RATIO_OVERFLOW_IN_SUB "overflow in ratio sub"
+#define BOOST_RATIO_OVERFLOW_IN_MUL "overflow in ratio mul"
+#define BOOST_RATIO_OVERFLOW_IN_DIV "overflow in ratio div"
+#define BOOST_RATIO_RATIO_NUMERATOR_IS_OUT_OF_RANGE "ratio numerator is out of range"
+#define BOOST_RATIO_RATIO_DIVIDE_BY_0 "ratio divide by 0"
+#define BOOST_RATIO_RATIO_DENOMINATOR_IS_OUT_OF_RANGE "ratio denominator is out of range"
+#endif
+
+#ifndef BOOST_NO_STATIC_ASSERT
+#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG)
+#elif defined(BOOST_RATIO_USES_STATIC_ASSERT)
+#include <boost/static_assert.hpp>
+#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND)
+#elif defined(BOOST_RATIO_USES_MPL_ASSERT)
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) \
+ BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES)
+#else
+//~ #elif defined(BOOST_RATIO_USES_ARRAY_ASSERT)
+#define BOOST_RATIO_CONCAT(A,B) A##B
+#define BOOST_RATIO_NAME(A,B) BOOST_RATIO_CONCAT(A,B)
+#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_RATIO_NAME(__boost_ratio_test_,__LINE__)[(CND)?1:-1]
+//~ #define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES)
+#endif
+
+
+#ifdef INTMAX_C
+#define BOOST_INTMAX_C(a) INTMAX_C(a)
+#else
+#define BOOST_INTMAX_C(a) a##LL
+#endif
+//
+// We simply cannot include this header on gcc without getting copious warnings of the kind:
+//
+// boost/integer.hpp:77:30: warning: use of C99 long long integer constant
+//
+// And yet there is no other reasonable implementation, so we declare this a system header
+// to suppress these warnings.
+//
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#pragma GCC system_header
+#endif
+
+namespace boost
+{
+template <boost::intmax_t N, boost::intmax_t D = 1> class ratio;
+
+//----------------------------------------------------------------------------//
+// helpers //
+//----------------------------------------------------------------------------//
+
+namespace ratio_detail
+{
+
+ template <boost::intmax_t X, boost::intmax_t Y, boost::intmax_t = boost::integer::static_signed_sign<Y>::value>
+ class br_add;
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_add<X, Y, 1>
+ {
+ static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
+ static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
+
+ BOOST_RATIO_STATIC_ASSERT(X <= max - Y , BOOST_RATIO_OVERFLOW_IN_ADD, ());
+ public:
+ static const boost::intmax_t value = X + Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_add<X, Y, 0>
+ {
+ public:
+ static const boost::intmax_t value = X;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_add<X, Y, -1>
+ {
+ static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
+ static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
+
+ BOOST_RATIO_STATIC_ASSERT(min - Y <= X, BOOST_RATIO_OVERFLOW_IN_ADD, ());
+ public:
+ static const boost::intmax_t value = X + Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y, boost::intmax_t = boost::integer::static_signed_sign<Y>::value>
+ class br_sub;
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_sub<X, Y, 1>
+ {
+ static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
+ static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
+
+ BOOST_RATIO_STATIC_ASSERT(min + Y <= X, BOOST_RATIO_OVERFLOW_IN_SUB, ());
+ public:
+ static const boost::intmax_t value = X - Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_sub<X, Y, 0>
+ {
+ public:
+ static const boost::intmax_t value = X;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_sub<X, Y, -1>
+ {
+ static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
+ static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
+
+ BOOST_RATIO_STATIC_ASSERT(X <= max + Y, BOOST_RATIO_OVERFLOW_IN_SUB, ());
+ public:
+ static const boost::intmax_t value = X - Y;
+ };
+
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_mul
+ {
+ static const boost::intmax_t nan =
+ (BOOST_INTMAX_C(1) << (sizeof(boost::intmax_t) * CHAR_BIT - 1));
+ static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
+ static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
+
+ static const boost::intmax_t a_x = boost::integer::static_signed_abs<X>::value;
+ static const boost::intmax_t a_y = boost::integer::static_signed_abs<Y>::value;
+
+ BOOST_RATIO_STATIC_ASSERT(X != nan, BOOST_RATIO_OVERFLOW_IN_MUL, ());
+ BOOST_RATIO_STATIC_ASSERT(Y != nan, BOOST_RATIO_OVERFLOW_IN_MUL, ());
+ BOOST_RATIO_STATIC_ASSERT(a_x <= max / a_y, BOOST_RATIO_OVERFLOW_IN_MUL, ());
+ public:
+ static const boost::intmax_t value = X * Y;
+ };
+
+ template <boost::intmax_t Y>
+ class br_mul<0, Y>
+ {
+ public:
+ static const boost::intmax_t value = 0;
+ };
+
+ template <boost::intmax_t X>
+ class br_mul<X, 0>
+ {
+ public:
+ static const boost::intmax_t value = 0;
+ };
+
+ template <>
+ class br_mul<0, 0>
+ {
+ public:
+ static const boost::intmax_t value = 0;
+ };
+
+ // Not actually used but left here in case needed in future maintenance
+ template <boost::intmax_t X, boost::intmax_t Y>
+ class br_div
+ {
+ static const boost::intmax_t nan = (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1));
+ static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
+ static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
+
+ BOOST_RATIO_STATIC_ASSERT(X != nan, BOOST_RATIO_OVERFLOW_IN_DIV, ());
+ BOOST_RATIO_STATIC_ASSERT(Y != nan, BOOST_RATIO_OVERFLOW_IN_DIV, ());
+ BOOST_RATIO_STATIC_ASSERT(Y != 0, BOOST_RATIO_RATIO_DIVIDE_BY_0, ());
+ public:
+ static const boost::intmax_t value = X / Y;
+ };
+
+ // ratio arithmetic
+ template <class R1, class R2> struct ratio_add;
+ template <class R1, class R2> struct ratio_subtract;
+ template <class R1, class R2> struct ratio_multiply;
+ template <class R1, class R2> struct ratio_divide;
+
+ template <class R1, class R2>
+ struct ratio_add
+ {
+ //The nested typedef type shall be a synonym for ratio<T1, T2>::type where T1 has the value R1::num *
+ //R2::den + R2::num * R1::den and T2 has the value R1::den * R2::den.
+ // As the preceding doesn't works because of overflow on boost::intmax_t we need something more elaborated.
+ private:
+ static const boost::intmax_t gcd_n1_n2 = boost::integer::static_signed_gcd<R1::num, R2::num>::value;
+ static const boost::intmax_t gcd_d1_d2 = boost::integer::static_signed_gcd<R1::den, R2::den>::value;
+ public:
+ // No need to normalize as ratio_multiply is already normalized
+ typedef typename ratio_multiply
+ <
+ ratio<gcd_n1_n2, R1::den / gcd_d1_d2>,
+ ratio
+ <
+ boost::ratio_detail::br_add
+ <
+ boost::ratio_detail::br_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
+ boost::ratio_detail::br_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
+ >::value,
+ R2::den
+ >
+ >::type type;
+ };
+
+ template <class R1, class R2>
+ struct ratio_subtract
+ {
+ //The nested typedef type shall be a synonym for ratio<T1, T2>::type where T1 has the value
+ // R1::num *R2::den - R2::num * R1::den and T2 has the value R1::den * R2::den.
+ // As the preceding doesn't works because of overflow on boost::intmax_t we need something more elaborated.
+ private:
+ static const boost::intmax_t gcd_n1_n2 = boost::integer::static_signed_gcd<R1::num, R2::num>::value;
+ static const boost::intmax_t gcd_d1_d2 = boost::integer::static_signed_gcd<R1::den, R2::den>::value;
+ public:
+ // No need to normalize as ratio_multiply is already normalized
+ typedef typename ratio_multiply
+ <
+ ratio<gcd_n1_n2, R1::den / gcd_d1_d2>,
+ ratio
+ <
+ boost::ratio_detail::br_sub
+ <
+ boost::ratio_detail::br_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
+ boost::ratio_detail::br_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
+ >::value,
+ R2::den
+ >
+ >::type type;
+ };
+
+ template <class R1, class R2>
+ struct ratio_multiply
+ {
+ // The nested typedef type shall be a synonym for ratio<R1::num * R2::den - R2::num * R1::den, R1::den * R2::den>::type.
+ // As the preceding doesn't works because of overflow on boost::intmax_t we need something more elaborated.
+ private:
+ static const boost::intmax_t gcd_n1_d2 = boost::integer::static_signed_gcd<R1::num, R2::den>::value;
+ static const boost::intmax_t gcd_d1_n2 = boost::integer::static_signed_gcd<R1::den, R2::num>::value;
+ public:
+ typedef typename ratio
+ <
+ boost::ratio_detail::br_mul<R1::num / gcd_n1_d2, R2::num / gcd_d1_n2>::value,
+ boost::ratio_detail::br_mul<R2::den / gcd_n1_d2, R1::den / gcd_d1_n2>::value
+ >::type type;
+ };
+
+ template <class R1, class R2>
+ struct ratio_divide
+ {
+ // The nested typedef type shall be a synonym for ratio<R1::num * R2::den, R2::num * R1::den>::type.
+ // As the preceding doesn't works because of overflow on boost::intmax_t we need something more elaborated.
+ private:
+ static const boost::intmax_t gcd_n1_n2 = boost::integer::static_signed_gcd<R1::num, R2::num>::value;
+ static const boost::intmax_t gcd_d1_d2 = boost::integer::static_signed_gcd<R1::den, R2::den>::value;
+ public:
+ typedef typename ratio
+ <
+ boost::ratio_detail::br_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
+ boost::ratio_detail::br_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
+ >::type type;
+ };
+
+ template <class T>
+ struct is_ratio : public boost::false_type {};
+ template <boost::intmax_t N, boost::intmax_t D>
+ struct is_ratio<ratio<N, D> > : public boost::true_type {};
+ //template <class T>
+ // struct is_ratio : is_ratio<typename remove_cv<T>::type> {};
+
+ template <class R1, class R2,
+ boost::intmax_t Q1 = R1::num / R1::den, boost::intmax_t M1 = R1::num % R1::den,
+ boost::intmax_t Q2 = R2::num / R2::den, boost::intmax_t M2 = R2::num % R2::den>
+ struct ratio_less1
+ {
+ static const bool value = Q1 < Q2;
+ };
+
+ template <class R1, class R2, boost::intmax_t Q>
+ struct ratio_less1<R1, R2, Q, 0, Q, 0>
+ {
+ static const bool value = false;
+ };
+
+ template <class R1, class R2, boost::intmax_t Q, boost::intmax_t M2>
+ struct ratio_less1<R1, R2, Q, 0, Q, M2>
+ {
+ static const bool value = true;
+ };
+
+ template <class R1, class R2, boost::intmax_t Q, boost::intmax_t M1>
+ struct ratio_less1<R1, R2, Q, M1, Q, 0>
+ {
+ static const bool value = false;
+ };
+
+ template <class R1, class R2, boost::intmax_t Q, boost::intmax_t M1, boost::intmax_t M2>
+ struct ratio_less1<R1, R2, Q, M1, Q, M2>
+ {
+ static const bool value = ratio_less1<ratio<R2::den, M2>, ratio<R1::den, M1>
+ >::value;
+ };
+
+ template <
+ class R1,
+ class R2,
+ boost::intmax_t S1 = boost::integer::static_signed_sign<R1::num>::value,
+ boost::intmax_t S2 = boost::integer::static_signed_sign<R2::num>::value
+>
+ struct ratio_less
+ {
+ static const bool value = S1 < S2;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less<R1, R2, 1LL, 1LL>
+ {
+ static const bool value = ratio_less1<R1, R2>::value;
+ };
+
+ template <class R1, class R2>
+ struct ratio_less<R1, R2, -1LL, -1LL>
+ {
+ static const bool value = ratio_less1<ratio<-R2::num, R2::den>,
+ ratio<-R1::num, R1::den> >::value;
+ };
+
+
+} // namespace ratio_detail
+
+} // namespace boost
+
+#endif // BOOST_RATIO_HPP

Modified: sandbox/chrono/boost/ratio/ratio.hpp
==============================================================================
--- sandbox/chrono/boost/ratio/ratio.hpp (original)
+++ sandbox/chrono/boost/ratio/ratio.hpp 2010-10-10 12:58:14 EDT (Sun, 10 Oct 2010)
@@ -32,6 +32,10 @@
 #ifndef BOOST_RATIO_RATIO_HPP
 #define BOOST_RATIO_RATIO_HPP
 
+#include <boost/static_integer/static_abs.hpp>
+#include <boost/static_integer/static_sign.hpp>
+//#include <boost/static_integer/static_lcm.hpp>
+#include <boost/static_integer/static_gcd.hpp>
 #include <cstdlib>
 #include <climits>
 #include <limits>
@@ -39,40 +43,7 @@
 #include <boost/type_traits/integral_constant.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/integer_traits.hpp>
-
-#if !defined(BOOST_NO_STATIC_ASSERT) || !defined(BOOST_RATIO_USES_MPL_ASSERT)
-#define BOOST_RATIO_OVERFLOW_IN_ADD "overflow in ratio add"
-#define BOOST_RATIO_OVERFLOW_IN_SUB "overflow in ratio sub"
-#define BOOST_RATIO_OVERFLOW_IN_MUL "overflow in ratio mul"
-#define BOOST_RATIO_OVERFLOW_IN_DIV "overflow in ratio div"
-#define BOOST_RATIO_RATIO_NUMERATOR_IS_OUT_OF_RANGE "ratio numerator is out of range"
-#define BOOST_RATIO_RATIO_DIVIDE_BY_0 "ratio divide by 0"
-#define BOOST_RATIO_RATIO_DENOMINATOR_IS_OUT_OF_RANGE "ratio denominator is out of range"
-#endif
-
-#ifndef BOOST_NO_STATIC_ASSERT
-#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG)
-#elif defined(BOOST_RATIO_USES_STATIC_ASSERT)
-#include <boost/static_assert.hpp>
-#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND)
-#elif defined(BOOST_RATIO_USES_MPL_ASSERT)
-#include <boost/mpl/assert.hpp>
-#include <boost/mpl/bool.hpp>
-#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) \
- BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES)
-#else
-//~ #elif defined(BOOST_RATIO_USES_ARRAY_ASSERT)
-#define BOOST_RATIO_CONCAT(A,B) A##B
-#define BOOST_RATIO_NAME(A,B) BOOST_RATIO_CONCAT(A,B)
-#define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_RATIO_NAME(__boost_ratio_test_,__LINE__)[(CND)?1:-1]
-//~ #define BOOST_RATIO_STATIC_ASSERT(CND, MSG, TYPES)
-#endif
-
-#ifdef INTMAX_C
-#define BOOST_INTMAX_C(a) INTMAX_C(a)
-#else
-#define BOOST_INTMAX_C(a) a##LL
-#endif
+#include <boost/ratio/detail/overflow_helpers.hpp>
 
 //
 // We simply cannot include this header on gcc without getting copious warnings of the kind:
@@ -95,8 +66,6 @@
 // //
 //----------------------------------------------------------------------------//
 
-template <boost::intmax_t N, boost::intmax_t D = 1> class ratio;
-
 // ratio arithmetic
 template <class R1, class R2> struct ratio_add;
 template <class R1, class R2> struct ratio_subtract;
@@ -129,174 +98,6 @@
 typedef ratio< BOOST_INTMAX_C(1000000000000000), BOOST_INTMAX_C(1)> peta;
 typedef ratio<BOOST_INTMAX_C(1000000000000000000), BOOST_INTMAX_C(1)> exa;
 
-//----------------------------------------------------------------------------//
-// helpers //
-//----------------------------------------------------------------------------//
-
-namespace detail
-{
-
- // static_gcd
-
- template <boost::intmax_t X, boost::intmax_t Y>
- struct static_gcd
- {
- static const boost::intmax_t value = static_gcd<Y, X % Y>::value;
- };
-
- template <boost::intmax_t X>
- struct static_gcd<X, 0>
- {
- static const boost::intmax_t value = X;
- };
-
- // static_lcm
-
- template <boost::intmax_t X, boost::intmax_t Y>
- struct static_lcm
- {
- static const boost::intmax_t value = X / static_gcd<X, Y>::value * Y;
- };
-
- template <boost::intmax_t X>
- struct static_abs
- {
- static const boost::intmax_t value = X < 0 ? -X : X;
- };
-
- template <boost::intmax_t X>
- struct static_sign
- {
- static const boost::intmax_t value = X == 0 ? 0 : (X < 0 ? -1 : 1);
- };
-
- template <boost::intmax_t X, boost::intmax_t Y, boost::intmax_t = static_sign<Y>::value>
- class ll_add;
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_add<X, Y, 1>
- {
- static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
- static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
-
- BOOST_RATIO_STATIC_ASSERT(X <= max - Y , BOOST_RATIO_OVERFLOW_IN_ADD, ());
- public:
- static const boost::intmax_t value = X + Y;
- };
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_add<X, Y, 0>
- {
- public:
- static const boost::intmax_t value = X;
- };
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_add<X, Y, -1>
- {
- static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
- static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
-
- BOOST_RATIO_STATIC_ASSERT(min - Y <= X, BOOST_RATIO_OVERFLOW_IN_ADD, ());
- public:
- static const boost::intmax_t value = X + Y;
- };
-
- template <boost::intmax_t X, boost::intmax_t Y, boost::intmax_t = static_sign<Y>::value>
- class ll_sub;
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_sub<X, Y, 1>
- {
- static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
- static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
-
- BOOST_RATIO_STATIC_ASSERT(min + Y <= X, BOOST_RATIO_OVERFLOW_IN_SUB, ());
- public:
- static const boost::intmax_t value = X - Y;
- };
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_sub<X, Y, 0>
- {
- public:
- static const boost::intmax_t value = X;
- };
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_sub<X, Y, -1>
- {
- static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
- static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
-
- BOOST_RATIO_STATIC_ASSERT(X <= max + Y, BOOST_RATIO_OVERFLOW_IN_SUB, ());
- public:
- static const boost::intmax_t value = X - Y;
- };
-
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_mul
- {
- static const boost::intmax_t nan =
- (BOOST_INTMAX_C(1) << (sizeof(boost::intmax_t) * CHAR_BIT - 1));
- static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
- static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
-
- static const boost::intmax_t a_x = static_abs<X>::value;
- static const boost::intmax_t a_y = static_abs<Y>::value;
-
- BOOST_RATIO_STATIC_ASSERT(X != nan, BOOST_RATIO_OVERFLOW_IN_MUL, ());
- BOOST_RATIO_STATIC_ASSERT(Y != nan, BOOST_RATIO_OVERFLOW_IN_MUL, ());
- BOOST_RATIO_STATIC_ASSERT(a_x <= max / a_y, BOOST_RATIO_OVERFLOW_IN_MUL, ());
- public:
- static const boost::intmax_t value = X * Y;
- };
-
- template <boost::intmax_t Y>
- class ll_mul<0, Y>
- {
- public:
- static const boost::intmax_t value = 0;
- };
-
- template <boost::intmax_t X>
- class ll_mul<X, 0>
- {
- public:
- static const boost::intmax_t value = 0;
- };
-
- template <>
- class ll_mul<0, 0>
- {
- public:
- static const boost::intmax_t value = 0;
- };
-
- // Not actually used but left here in case needed in future maintenance
- template <boost::intmax_t X, boost::intmax_t Y>
- class ll_div
- {
- static const boost::intmax_t nan = (1LL << (sizeof(boost::intmax_t) * CHAR_BIT - 1));
- static const boost::intmax_t min = boost::integer_traits<boost::intmax_t>::const_min;
- static const boost::intmax_t max = boost::integer_traits<boost::intmax_t>::const_max;
-
- BOOST_RATIO_STATIC_ASSERT(X != nan, BOOST_RATIO_OVERFLOW_IN_DIV, ());
- BOOST_RATIO_STATIC_ASSERT(Y != nan, BOOST_RATIO_OVERFLOW_IN_DIV, ());
- BOOST_RATIO_STATIC_ASSERT(Y != 0, BOOST_RATIO_RATIO_DIVIDE_BY_0, ());
- public:
- static const boost::intmax_t value = X / Y;
- };
-
- template <class T>
- struct is_ratio : public boost::false_type {};
- template <intmax_t N, intmax_t D>
- struct is_ratio<ratio<N, D> > : public boost::true_type {};
- //template <class T>
- // struct is_ratio : is_ratio<typename remove_cv<T>::type> {};
-
-
-} // namespace detail
 
 //----------------------------------------------------------------------------//
 // //
@@ -307,21 +108,21 @@
 template <boost::intmax_t N, boost::intmax_t D>
 class ratio
 {
- BOOST_RATIO_STATIC_ASSERT(boost::detail::static_abs<N>::value >= 0, BOOST_RATIO_RATIO_NUMERATOR_IS_OUT_OF_RANGE, ());
- BOOST_RATIO_STATIC_ASSERT(boost::detail::static_abs<D>::value > 0, BOOST_RATIO_RATIO_DENOMINATOR_IS_OUT_OF_RANGE, ());
+ static const boost::intmax_t ABS_N = boost::integer::static_signed_abs<N>::value;
+ static const boost::intmax_t ABS_D = boost::integer::static_signed_abs<D>::value;
+ BOOST_RATIO_STATIC_ASSERT(ABS_N >= 0, BOOST_RATIO_RATIO_NUMERATOR_IS_OUT_OF_RANGE, ());
+ BOOST_RATIO_STATIC_ASSERT(ABS_D > 0, BOOST_RATIO_RATIO_DENOMINATOR_IS_OUT_OF_RANGE, ());
     BOOST_RATIO_STATIC_ASSERT(D != 0, BOOST_RATIO_RATIO_DIVIDE_BY_0 , ());
- static const boost::intmax_t m_na = boost::detail::static_abs<N>::value;
- static const boost::intmax_t m_da = boost::detail::static_abs<D>::value;
- static const boost::intmax_t m_s = boost::detail::static_sign<N>::value
- * boost::detail::static_sign<D>::value;
- static const boost::intmax_t m_gcd = boost::detail::static_gcd<m_na, m_da>::value;
+ static const boost::intmax_t SIGN = boost::integer::static_signed_sign<N>::value
+ * boost::integer::static_signed_sign<D>::value;
+ static const boost::intmax_t GCD = boost::integer::static_signed_gcd<ABS_N, ABS_D>::value;
 public:
- static const boost::intmax_t num = m_s * m_na / m_gcd;
- static const boost::intmax_t den = m_da / m_gcd;
+ static const boost::intmax_t num = SIGN * ABS_N / GCD;
+ static const boost::intmax_t den = ABS_D / GCD;
 
+#ifdef BOOST_RATIO_EXTENSIONS
     ratio() {}
-
- template <intmax_t _N2, intmax_t _D2>
+ template <intmax_t _N2, boost::intmax_t _D2>
     ratio(const ratio<_N2, _D2>&,
         typename enable_if_c
             <
@@ -329,7 +130,7 @@
                 ratio<_N2, _D2>::den == den)
>::type* = 0) {}
 
- template <intmax_t _N2, intmax_t _D2>
+ template <intmax_t _N2, boost::intmax_t _D2>
         typename enable_if_c
         <
             (ratio<_N2, _D2>::num == num &&
@@ -337,7 +138,7 @@
             ratio&
>::type
     operator=(const ratio<_N2, _D2>&) {return *this;}
-
+#endif
     typedef ratio<num, den> type;
 };
 
@@ -348,106 +149,27 @@
 //----------------------------------------------------------------------------//
 
 template <class R1, class R2>
-struct ratio_add
+struct ratio_add
+: boost::ratio_detail::ratio_add<R1, R2>::type
 {
-#if 0
-public:
- //The nested typedef type shall be a synonym for ratio<T1, T2>::type where T1 has the value R1::num *
- //R2::den + R2::num * R1::den and T2 has the value R1::den * R2::den.
- typedef typename ratio<R1::num * R2::den + R2::num * R1::den,R1::den * R2::den>::type type;
- // The preceding declaration doesn't works because of overflow on intmax_t.
-#else
-private:
- static const boost::intmax_t gcd_n1_n2 = boost::detail::static_gcd<R1::num, R2::num>::value;
- static const boost::intmax_t gcd_d1_d2 = boost::detail::static_gcd<R1::den, R2::den>::value;
-public:
- // No need to normalize as ratio_multiply is already normalized
- typedef typename ratio_multiply
- <
- ratio<gcd_n1_n2, R1::den / gcd_d1_d2>,
- ratio
- <
- boost::detail::ll_add
- <
- boost::detail::ll_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
- boost::detail::ll_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
- >::value,
- R2::den
- >
- >::type type;
-#endif
 };
 
 template <class R1, class R2>
 struct ratio_subtract
+: boost::ratio_detail::ratio_subtract<R1, R2>::type
 {
-#if 0
-public:
- //The nested typedef type shall be a synonym for ratio<T1, T2>::type where T1 has the value
- // R1::num *R2::den - R2::num * R1::den and T2 has the value R1::den * R2::den.
- typedef typename ratio<R1::num * R2::den - R2::num * R1::den, R1::den * R2::den>::type type;
- // The preceding declaration doesn't works because of overflow on intmax_t.
-#else
-private:
- static const boost::intmax_t gcd_n1_n2 = boost::detail::static_gcd<R1::num, R2::num>::value;
- static const boost::intmax_t gcd_d1_d2 = boost::detail::static_gcd<R1::den, R2::den>::value;
-public:
- // No need to normalize as ratio_multiply is already normalized
- typedef typename ratio_multiply
- <
- ratio<gcd_n1_n2, R1::den / gcd_d1_d2>,
- ratio
- <
- boost::detail::ll_sub
- <
- boost::detail::ll_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
- boost::detail::ll_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
- >::value,
- R2::den
- >
- >::type type;
-#endif
 };
 
 template <class R1, class R2>
 struct ratio_multiply
+: boost::ratio_detail::ratio_multiply<R1, R2>::type
 {
-#if 0
-public:
- // The nested typedef type shall be a synonym for ratio<R1::num * R2::den - R2::num * R1::den, R1::den * R2::den>::type.
- typedef typename ratio<R1::num * R2::num, R1::den * R2::den>::type type;
- // The preceding declaration doesn't works because of overflow on intmax_t.
-#else
-private:
- static const boost::intmax_t gcd_n1_d2 = boost::detail::static_gcd<R1::num, R2::den>::value;
- static const boost::intmax_t gcd_d1_n2 = boost::detail::static_gcd<R1::den, R2::num>::value;
-public:
- typedef typename ratio
- <
- boost::detail::ll_mul<R1::num / gcd_n1_d2, R2::num / gcd_d1_n2>::value,
- boost::detail::ll_mul<R2::den / gcd_n1_d2, R1::den / gcd_d1_n2>::value
- >::type type;
-#endif
 };
 
 template <class R1, class R2>
 struct ratio_divide
+: boost::ratio_detail::ratio_divide<R1, R2>::type
 {
-#if 0
-public:
- // The nested typedef type shall be a synonym for ratio<R1::num * R2::den, R2::num * R1::den>::type.
- typedef typename ratio<R1::num * R2::den, R1::den * R2::num>::type type;
-#else
-private:
- static const boost::intmax_t gcd_n1_n2 = boost::detail::static_gcd<R1::num, R2::num>::value;
- static const boost::intmax_t gcd_d1_d2 = boost::detail::static_gcd<R1::den, R2::den>::value;
-public:
- typedef typename ratio
- <
- boost::detail::ll_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
- boost::detail::ll_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
- >::type type;
-#endif
 };
 
 // ratio_equal
@@ -463,85 +185,9 @@
 
 // ratio_less
 
-
-//----------------------------------------------------------------------------//
-// more helpers //
-//----------------------------------------------------------------------------//
-
-namespace detail
-{
-
- template <class R1, class R2,
- intmax_t Q1 = R1::num / R1::den, intmax_t M1 = R1::num % R1::den,
- intmax_t Q2 = R2::num / R2::den, intmax_t M2 = R2::num % R2::den>
- struct ratio_less1
- {
- static const bool value = Q1 < Q2;
- };
-
- template <class R1, class R2, intmax_t Q>
- struct ratio_less1<R1, R2, Q, 0, Q, 0>
- {
- static const bool value = false;
- };
-
- template <class R1, class R2, intmax_t Q, intmax_t M2>
- struct ratio_less1<R1, R2, Q, 0, Q, M2>
- {
- static const bool value = true;
- };
-
- template <class R1, class R2, intmax_t Q, intmax_t M1>
- struct ratio_less1<R1, R2, Q, M1, Q, 0>
- {
- static const bool value = false;
- };
-
- template <class R1, class R2, intmax_t Q, intmax_t M1,
- intmax_t M2>
- struct ratio_less1<R1, R2, Q, M1, Q, M2>
- {
- static const bool value = ratio_less1<ratio<R2::den, M2>, ratio<R1::den, M1>
- >::value;
- };
-
- template <class R1, class R2, intmax_t S1 = static_sign<R1::num>::value,
- intmax_t S2 = static_sign<R2::num>::value>
- struct ratio_less
- {
- static const bool value = S1 < S2;
- };
-
- template <class R1, class R2>
- struct ratio_less<R1, R2, 1LL, 1LL>
- {
- static const bool value = ratio_less1<R1, R2>::value;
- };
-
- template <class R1, class R2>
- struct ratio_less<R1, R2, -1LL, -1LL>
- {
- static const bool value = ratio_less1<ratio<-R2::num, R2::den>,
- ratio<-R1::num, R1::den> >::value;
- };
-
- template <class R1, class R2>
- struct ratio_gcd
- {
- typedef ratio<boost::detail::static_gcd<R1::num, R2::num>::value,
- boost::detail::static_lcm<R1::den, R2::den>::value> type;
- };
-} // namespace detail
-
-//----------------------------------------------------------------------------//
-// //
-// more implementation //
-// //
-//----------------------------------------------------------------------------//
-
 template <class R1, class R2>
 struct ratio_less
- : boost::integral_constant<bool, boost::detail::ratio_less<R1, R2>::value> {};
+ : boost::integral_constant<bool, boost::ratio_detail::ratio_less<R1, R2>::value> {};
 
 template <class R1, class R2>
 struct ratio_less_equal
@@ -555,10 +201,14 @@
 struct ratio_greater_equal
     : boost::integral_constant<bool, !ratio_less<R1, R2>::value> {};
 
+template <class R1, class R2>
+struct ratio_gcd
+{
+ typedef ratio<boost::integer::static_signed_gcd<R1::num, R2::num>::value,
+ boost::integer::static_signed_lcm<R1::den, R2::den>::value> type;
+};
+
 } // namespace boost
 
-//~ #ifdef BOOST_RATIO_STATIC_ASSERT
-//~ #undef BOOST_RATIO_STATIC_ASSERT
-//~ #endif
 
 #endif // BOOST_RATIO_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk