|
Boost Users : |
From: Andy Little (andy_at_[hidden])
Date: 2004-03-15 06:35:56
"Aleksey Gurtovoy" <agurtovoy_at_[hidden]> wrote in message
news:009d01c40a65$691f7360$6401a8c0_at_metacomm.com...
> Matt Calabrese wrote:
> > Okay, I decided before I continue with my other library, I'll fully
> > implement rational_c properly (and possibly fixed_c), however, doing
> > so without making the code horribly complex would require changes to
> > the current definitions of pretty much all of the operations (plus,
> > multiplies, etc. as well as the conditional operators).
> ^^^^^^^^^^^
> I suppose you meant "comparison", here and below.
>
> >
> > The problem is that those current functions take 5 parameters, making
> > specialization nearly impossible for the rational and fixed templates
> > as you'd have to account for when the 3rd, 4th, 5th, etc parameters
> > are not passed (and so the default integral 0 is used). That can't be
> > easily done (at least I don't see how) without having to specialize
> > each condition separately (one for 3 rational types, one for 4
> > rational types, etc ). Moreso, this applies to the conditional
> > operators as well, there is no easy way to account for using different
> > types in multiplies IE multiplying a rational and integral together,
> > or a fixed and rational, etc. Again, to account for these
> > possibilities you'd have to make an incredibly large amount of
> > specializations.
I have come up against the above problems.
My solution was to create a metafunction like so:
template<
typename A,
typename Op, // some type representing the op.
//I actually use template<typename> class Op
// with std::plus etc as the token
typename B
>
struct binary_operation{
typedef ... result_type; // works with result_of
};
notably compatible with mpl::plus (say);
(This is actually my standalone impl of mpl ops.
I dont use the extra params.
OTOH My impl is easy to replace with official version
namespace boost{namespace mpl{
template<
typename A,
typename B
>
struct plus<A,B> // unused params default aways
{
typedef typename binary_operation<
A, std::plus,B
>::result_type type;
};
}}
Actually definition for my rational_c op integral_c and vice versa is then:
(Assuming binary_operation<rational_c<..>,Op,Rational_c<..> > defined
// mpl::integral_c support
template<
typename IntegerType1,
IntegerType1 N1,
IntegerType1 D1,
template <typename> class Op,
typename IntegerType2,
IntegerType2 N2
>
struct binary_operation<
rational_c<IntegerType1,N1,D1>,
Op,
boost::mpl::integral_c<IntegerType2,N2>
>{
typedef typename arithmetic_promote<
IntegerType1,
IntegerType2
>::type promoted_type;
typedef typename binary_operation<
rational_c<promoted_type,N1,D1>,
Op,
rational_c<promoted_type,N2,1>
>::result_type result_type;
};
template<
typename IntegerType1,
IntegerType1 N1,
template <typename> class Op,
typename IntegerType2,
IntegerType2 N2,
IntegerType2 D2
>
struct binary_operation<
boost::mpl::integral_c<IntegerType1,N1>,
Op,
rational_c<IntegerType2,N2,D2>
>{
typedef typename meta::arithmetic_promote<
IntegerType1,
IntegerType2
>::type promoted_type;
typedef typename binary_operation<
rational_c<promoted_type,N1,1>,
Op,
rational_c<promoted_type,N2,D2>
>::result_type result_type;
}
which cuts down the work some :-)
regards
Andy Little
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net