# Boost :

From: Andy Little (andy_at_[hidden])
Date: 2005-03-07 15:57:41

Hi again,

The problem: For some Integral Constants values mpl::divides<A.,B> truncates.

The solution: A new operator... mpl::rational_divides<A,B> When it is desired
not to truncate, this form will preserve the fractional part by if necessary
converting to a rational number. With this operator in place it is also possible
to 'reduce' rationals to integers where possible and further to keep integral
constants as integral types by default, knowing that conversion will be
automatic if a fraction is required to prevent loss of precision.

No mpl::divides<A.,B> is available if A or B is a rational types, because it is
assumed that if you are using rationals you require the fraction preserving
behaviour. A numeric_cast to an integral type can be used to solve this where
necessary.

Errors of using divides<A,B> on rationals will show at compile time.

Thanks to Alexey Gurtovoy for the conversion mechanism

As an example:

int main()
{
// current division operator
typedef boost::mpl::divides<
boost::mpl::int_<2>,
boost::mpl::int_<3>
>::type int_div;

// error no mpl::divides allowed for rationals
/* typedef boost::mpl::divides<
boost::mpl::rational_c<int,2>,
boost::mpl::rational_c<int,3>
>::type XXX;*/

// when some type might be a rational and rational behaviour rather than
truncation is required:

typedef boost::mpl::rational_divides<
boost::mpl::rational_c<long,2>,
boost::mpl::int_<3>
>::type rat_div1;
//also works on int_'s etc...
typedef boost::mpl::rational_divides<
boost::mpl::int_<2>,
boost::mpl::int_<3>
>::type rat_div2;

typedef boost::mpl::rational_divides<
boost::mpl::rational_int<2>,
boost::mpl::rational_int<3>
>::type rat_div3;

// also 'promotes' to int_ where possible
typedef boost::mpl::rational_divides<
boost::mpl::rational_int<210>,
boost::mpl::rational_int<3>
>::type rat_div4;

// also 'promotes' to int_ where possible
typedef boost::mpl::rational_divides<
boost::mpl::int_<210>,
boost::mpl::integral_c<long,3>
>::type rat_div5;

std::ofstream os("output.txt");

os << typeid(int_div).name() <<'\n';
os << typeid(rat_div1).name() <<'\n';
os << typeid(rat_div2).name() <<'\n';
os << typeid(rat_div3).name() <<'\n';
os << typeid(rat_div4).name() <<'\n';
os << typeid(rat_div5).name() <<'\n';

}
output: (VC7.1)

struct boost::mpl::integral_c<int,0>
struct boost::mpl::rational_c<long,2,3>
struct boost::mpl::rational_c<int,2,3>
struct boost::mpl::rational_c<int,2,3>
struct boost::mpl::int_<70>
struct boost::mpl::long_<70>

regards
Andy Little