Boost logo

Boost :

Subject: Re: [boost] [proto] switch_ with a policy
From: Eric Niebler (eric_at_[hidden])
Date: 2009-03-25 13:28:55


troy d. straszheim wrote:
> In some situations you're limited by the fact that proto::switch_
> matches on tag type. For instance, if you have a bunch of these things:
>
> namespace tag {
> struct exp {};
> struct log {};
> // lots more, say 50 of them
> }
>
> Expression<terminal<tag::exp>::type> const exp = {{}};
> Expression<terminal<tag::log>::type> const log = {{}};
> // 50 more
>
> And you try to write a transform with switch_ that handles theses,
> you're stymied by the fact that switch_ will only tell you the tag of
> what has matched. Here's an attempt at the switch:
>
> struct UnaryFunctionCases
> {
> template <typename Tag, int i=0>
> struct case_ : not_<_> { };
>
> template <int i>
> struct case_<VEY, i>
> : when<proto::function<...>, DoSomethingClever(...)>
> { };
>
> };
>
> struct UnaryFunctionSwitch : proto::switch_<UnaryFunctionCases> { };
>
> the VEY above is going to be proto::tag::function for all of these
> terminals if you're trying to transform an expression like
>
> exp(7);
>
> (If I remember correctly... I havent looked at this code in a while).
>
> You can add a policy to the stock switch_ that makes this easy to handle
<snip>

First, I agree that switch_ could be made more general, but I am not
overjoyed with the extra policy you suggest. Not sure why yet, just a
vague Ick. I'll think about it.

There is a deeper problem, which is that the matching primitives form a
closed set. There is no way to define your own matching primitives (like
switch_) and have proto::matches<> use it. There should be.

To solve your immediate problem, I suggest you define exp and log to be
actual function templates instead of proto terminals, as follows (untested):

template<class T>
typename proto::result_of::make_expr<
   exp_tag,
   T const &
>::type
exp(T const &t)
{
   return proto::make_expr<exp_tag>(proto::ref(t));
}

Now you can use the stock proto::switch_ because all your functions will
create expressions with unique tag types. There have also been some
recent performance benchmarks that show this approach (function
templates vs. proto terminals) to be much faster at compile-time.

HTH,

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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