Boost logo

Boost :

From: Joel de Guzman (joel_at_[hidden])
Date: 2008-01-13 01:43:03


Tobias Schwinger wrote:
> Joel de Guzman wrote:
>> Joel de Guzman wrote:
>>
>>> I'll try to come up with a complete interface proposal that
>>> will encompass all use cases. It will be lightweight (no need
>>> for extra infrastructure) and efficient. I believe it can
>>> be done.
>> Ok, here's what I have for draft of the Case concept.
>> I believe this is most crucial in the design of the
>> switch_ as I proposed in a recent post. Comments,
>> feedback, suggestions welcome.
>
> AFAICT it looks very good. Here come some more thoughts:

Thank you! Appreciated. I also have some tweaks of my own.
I'll see if I can post an update from yours and Steven's
comments.

>> Case Concept:
>> Specialization of unary Polymorphic Function Object that,
>> in addition to the requirements defined in Polymorphic
>> Function Object, encodes a list of labels in its type
>> necessary for switch dispatch.
>>
>> Notation:
>>
>> c, c0, c1, ... cN Case objects
>> C A Case type
>> I An MPL Integral Constant type

Add:
         SI An MPL Sequence of MPL Integral Constants

>> i An MPL Integral Constant object
>> N, First, Last Integral constants
>> N0, N1, ...NN A list of integral constants
>> f A unary function
>> case_c, case_range_c,
>> case_, default Case factories
>>
>> Valid Expressions:
>>
>> Expression Semantics
>> ----------
>> --------------------------------------------------------
>> C::labels An MPL Sequence of Integral Constants
>
>
>> c(i) Function application
>
> seemingly equivalent to
>
> c(I()) Function application
>
> (note: constant encoded in type). Maybe should be
>
> c.template apply<ResultType>(I())
>
> instead (note: Passing in the result type).
>
>
>
>> case_<I>(f) Returns a Case object with supplied
>> MPL Sequence of Integral Constants.
>> forwarding to the encapsulated function object f.
>
> I think this one should be called 'cases' and 'case_' should take a
> single MPL constant, for consistency.

Good point. Fixes:

       case_<I>(f) Returns a Case object with supplied
                               Integral Constants. forwarding to the
                               encapsulated function object f.

       cases<SI>(f) Returns a Case object with supplied
                               MPL Sequence of Integral Constants.
                               forwarding to the encapsulated function object f.

>> case_c<N>(f) Returns a Case object with a single label N
>> forwarding to the encapsulated function object f.
>> Equivalent to: case_<mpl::vector_c<int, N> >(f)
>> case_c<
>> N0, N1, ...NN>(f) Returns a Case object with a list of labels
>> forwarding to the encapsulated function object f.
>> Equivalent to: case_<mpl::vector_c<
>> int, N0, N1, ...NN> >(f)

Following your logic, shouldn't this be:

       cases_c<
           N0, N1, ...NN>(f) Returns a Case object with a list of labels
                               forwarding to the encapsulated function object f.
                               Equivalent to: case_<mpl::vector_c<
                                 int, N0, N1, ...NN> >(f)
?

>> case_range_c<
>> First, Last>(f) Returns a Case object with a range of labels
>> forwarding to the encapsulated function object f.
>> Equivalent to: case_<mpl::range_c<
>> int, First, Last> >(f)
>
>> default_(f) Returns a Case object with an empty labels list.
>> forwarding to the encapsulated function object f.
>
>
>> c0, c1, ... cN Returns a fusion sequence of Case objects
>
> seemingly equivalent to
>
> (c0, c1, ... cN)
>
> (note: Application of comma operator ;-)).
>
>
> ?! Why doesn't it just return another (compound) Case object and leave
> the Sequence an unspecified implementation detail...

I'll reply to this later along with Steven's other post.

>> Notes:
>>
>> * While c0, c1, ... cN returns a fusion sequence, it does not
>> have to use Fusion. It can be a very simple cons list of
>> references to the actual arguments similar to the zero overhead
>> Proto expression tree. It must be compatible with Fusion though,
>> but that can be abstracted away.
>
> ...this way we'd have that abstraction specified, already.

Yes. Haven't tried, but perhaps we can do it with only forward
declarations of Fusion's extension protocol, and without having
to include any of Fusion? Is that possible?

>> * case_c and case_range_c are simple shortcuts. The type of
>> integral constant is int. The actual type can be casted to
>> the actual switch parameter. I think this is safe, but a
>> variation is to have case_c and case_range_c expect the
>> actual type (like mpl::vector_c and mpl::range_c.). E.g.:
>> case_c<int, N>.
>
> I prefer the former.

Same here.

>> * case_<I>(f) is equivalent to the original Steven interface.

Change:

    * cases<SI>(f) is equivalent to the original Steven interface.

> We could have this case swallow the index during function invocation, as
> for manual application we probably don't want to have it. I think it's
> typical and easy enough to just model the Case concept directly...

Forgive me, I think my headache is getting in the way and I can't
seem to parse this sentence properly. Could you please explain a
bit more?

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