Boost logo

Boost :

From: Joel de Guzman (joel_at_[hidden])
Date: 2006-05-11 19:27:06


Tobias Schwinger wrote:
> Joel de Guzman wrote:
>> Tobias Schwinger wrote:
>>
>>> Tobias Schwinger wrote:
>>
>>>> I'm still playing with it and hope I can add some details here, soon.
>>>>
>>> I wanted to use Fusion to write something (well, at least half-way)
>>> real for review, so I chose to solve this problem:
>>>
>>> Call one of a heterogenous set of functors (their call operators might
>>> be templates) based on a runtime index with a complexity of O(log N)
>>> (basically what an n-ary tree structure of nested switch/case blocks
>>> does).
>>>
>>> The solution
>>> o handles unary functors only and doesn't bother with the result (simplicity),
>>> o contains numerous workarounds and is far away from being perfect,
>>> o requires an MPL-patch [ http://tinyurl.com/ljfdm] to compile, but
>>> o nevertheless documents my fight with the library, hopefully including
>>> lots of mistakes a new user is tempted to make, so it might work good to
>> inspire upcomnig examples.
>>
>>> http://tinyurl.com/l5bxl (source file in the vault)
>>
>> Very cool! That might be a good example for a tutorial if you are
>> willing to document and share it.
>
> Sure (that is, for the willingness-part).
>
> I'm not sure whether it qualifies for a good tutorial. There might be better ways
> to do things (I wanted to get my hands on the library quickly, so I didn't put too
> much time into planning, plus I still have some questions, below).

Right.

> Given that my implementation can not be radically simplified, it might also be too
> much code for a tutorial. Maybe a linear version for a tutorial and the logarithmic
> version for an inline-documented source code example would work better...
>
> BTW. implementation improvements, anyone? I'm all ear!

I was contemplating on something like the one you are doing.
The inputs are:

1) A runtime value (a primitive integer; e.g. char,int)
2) A tuple of functions
3) A tuple of args (usually tiers)

I was thinking of using the boost preprocessor instead to
generate actual switch code. Something like:

     template <int Size>
     struct switch_dispatch;

     template <>
     struct switch_dispatch<1>
     {
         template <typename RT, typename Int
             , typename Functions, typename Args>
         static RT
         call(int n, Functions const& dispatch, Args const& args)
         {
             return at_c<0>(dispatch)(args);
         }
     };

     template <>
     struct switch_dispatch<2>
     {
         template <typename RT, typename Int
             , typename Functions, typename Args>
         static RT
         call(int n, Functions const& dispatch, Args const& args)
         {
             if (n == 0)
                 return at_c<0>(dispatch)(args);
             else
                 return at_c<1>(dispatch)(args);
         }
     };

     template <>
     struct switch_dispatch<3>
     {
         template <typename RT, typename Int
             , typename Functions, typename Args>
         static RT
         call(int n, Functions const& dispatch, Args const& args)
         {
             switch (n)
             {
                 case 0: return at_c<0>(dispatch)(args);
                 case 1: return at_c<1>(dispatch)(args);
             }
         }
     };

++ A little change, we can use an mpl::vector_c to hold the cases.
Something like:

     case mpl::at_c<cases, 0>::value : return at_c<0>(dispatch)(args);
     case mpl::at_c<cases, 1>::value : return at_c<1>(dispatch)(args);

where "cases" is an mpl::vector_c. Such a utility will provide the
backbone for 1) Phoenix2's switch_ statement 2) Spirit's switch_p
3) Spirit-2's predictive parsing schemes, and all those stuff that
intends to optimize spirit's alternative.

++ Some more code to handle defaults; etc... see Phoenix2 switch
and Spirit switch_p for reference.

... More comments on your post later.

Regards,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

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