Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-09-20 06:36:04


>From: "Richard Crossley" <rdc_at_[hidden]>

> > > apply_if<some_condition,
> > > some_type_1,
> > > plus<some_type_2::type,some_number >
> > > >::type;
> > >
> > > Becomes,
> > >
> > > apply_if<some_condition,
> > > some_type_1,
> > > eva<plus<some_type_2,some_number> >
> > > >::type;
> >
> > (By the way, I assume there should be a ",", rather than "<",
> > after "plus" above, so I've changed that in the quote above)
>
> No, the original was correct. Note that eva is always specialised and
> only accepts a single parameter :-)

Ah, I missed that. I see how it works, now. I've changed the above code
back. Part of the reason I thought it was wrong, was that it was missing a
matching ">" at the end.

> > One advantage of this solution is that it works with MPL as it is.
>
> > Consider the "factorial" metafunction, again:
> >
> > template<class V>
> > struct factorial
> > {
> > typedef typename V::type Value;
> >
> > typedef typename apply_if<equal_to<Value,value<Value,0> >,
> > value<Value,1>,
> > mul<Value,factorial<prior<Value> > >
> > >::type type;
> > }
> >
> > Could you have shown how I could rewrite the above, using "eva"?
>
> In a sort of MPL psuedo-code :-) but I think you can see whats
> happening:

<snip>

Well, it was a clever solution. It does actually work.

However, how do you select between when to use "eva," and when not? In
expressions where only some parts are evaluated (like if_ or apply_if)?
Couldn't that lead to quite a lot of "eva"? [Addition: I see below here that
this may be minimised, by using another definition of "eval," which
recursively evalutes its arguments. It does start to look like the
metafunctions evalute their own arguments, that way, though. :) ] In your
experience, do you find it easy to find the points that need "eva," to work?

With the other solution, of having metafunctions evaluate their own
arguments, "eva" isn't needed. Why do you feel the "eva"-solution is better
(apart from it working on the current MPL. :) )? You mentioned the case
about the type traits, but are there other issues?

[Addition: I see in a later posting, that Aleksey point out some issues with
the solution of having metafunctions evaluate their arguments.]

Many questions, I know. :)

There's one implication with the "eva" solution, though: It requires partial
specialisation, so it doesn't work on MSVC, for example.

> > Unless there's something obvious I've missed, I think the
> > fact that it's hard to write one of the simplest
> > metafunctions, factorial, using "eva," could mean that it
> > could be hard to use this solution.
>
> Doesn't look difficult to me but that may just be familiarity with eva.

I see new that it's possible, after all, so it's ok.

> Taking it a bit further something like this could be used:
>
> template <typename T>
> struct id{typedef T type;};
>
> template <typename T>
> struct eval{typedef T::type type;};
>
> template <typename T>
> struct eval<id<T> > : id<T>{};
>
> template <template <typename> class F,typename A0>
> struct eval<F<A0> > : F<typename eval<A0>::type>{};
>
> template <template <typename,typename> class F,typename A0,typename A1>
> struct eval<F<A0,A1> > : F<typename eval<A0>::type,typename
> eval<A1>::type>{};
>
> Etc...
>
> template <typename N = _>
> struct factorial : apply_if<equal_to<N,int_c<1>
> >,N,eval<mul<factorial<prior<N> >,N> > >{};

Interesting.

Regards,

Terje


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk