From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2008-01-12 06:24:05


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:

>
> 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
> 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.

> 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)
> 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...

>
>
> 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.

>
> * 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.

>
> * case_<I>(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...

Regards,
Tobias