$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] [ratio] metafunction ratio_subtract
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-12-06 15:43:50
Hi Beman, Hi Howard,
With current implementation of the metafunction ratio_subtract I get the type from the test  ratio_test.cpp
    User1::Distance d( User1::mile(110) );
    User1::Time t( boost::chrono::hours(2) );
    
    typeof (d/t) is User1::quantity<boost::ratio<1,-1>, boost::ratio<1,1> >
So the following assignation do not works
   User1::Speed s = d / t;
as User1::Speed  is defined as 
typedef quantity<boost::ratio<1>, boost::ratio<0> >  Time;         // second
typedef quantity<boost::ratio<0>, boost::ratio<1> >  Distance;     // meter
typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed;        // meter/second
The code is a little bit triky, and I have not taken the time to understand why the resulting type is 
    User1::quantity<boost::ratio<1,-1>, boost::ratio<1,1> >
and not
<boost::ratio<-1,1>, boost::ratio<1,1> >    User1::quantity
I have replaced the type by
    typedef ratio<R1::num * R2::den - R2::num * R1::den,R1::den * R2::den> aux_type;
    typedef ratio<aux_type::num ,aux_type::den > type; // get normalized type
to follow the recommendation "The nested typedef type shall be a synonym for ratio<T1, T2> where T1 has the value R1::num *R2::den - R2::num * R1::den and T2 has the value R1::den * R2::den."
and every thing is OK (See below the replaced code)
I'm doing something wrong?
Best,
_____________________
Vicente Juan Botet Escribá
template <class R1, class R2>
struct ratio_subtract
{
private:
#if 1
    typedef ratio<R1::num * R2::den - R2::num * R1::den,R1::den * R2::den> aux_type;
#else
   static const boost::intmax_t gcd_n1_n2 = detail::static_gcd<R1::num, R2::num>::value;
   static const boost::intmax_t gcd_d1_d2 = detail::static_gcd<R1::den, R2::den>::value;#endif
public:
    //The nested typedef type shall be a synonym for ratio<T1, T2> where T1 has the value 
    // R1::num *R2::den - R2::num * R1::den and T2 has the value R1::den * R2::den.
#if 1
    typedef ratio<aux_type::num ,aux_type::den > type;
#else
    typedef typename ratio_multiply
       <
           ratio<gcd_n1_n2, R1::den / gcd_d1_d2>,
           ratio
           <
               detail::ll_sub
               <
                   detail::ll_mul<R1::num / gcd_n1_n2, R2::den / gcd_d1_d2>::value,
                   detail::ll_mul<R2::num / gcd_n1_n2, R1::den / gcd_d1_d2>::value
               >::value,
               R2::den
           >
       >::type type;
#endif
};