Boost logo

Boost :

From: Larry Evans (cppljevans_at_[hidden])
Date: 2004-12-13 17:52:25

Thanks for your responses, David.

On 12/12/2004 08:16 PM, David Abrahams wrote:
> Larry Evans wrote:

>>I believe is much simpler to understand and doesn't use
>>any preprocessor macros.

> Yes, but it is much less efficient for some applications.

OK. I was under the (probably mistaken) assumption that
speed of access to the elements was essentially the only
speed createria, and I couldn't imagine anything faster than:


where Index the enumeration index (an element of Indices in template <
Indices, TypeMap<Indices> product; ) and factor<...,Index> is the
Index-th superclass of the product. When I tried to see how fusion
tuples did it, I couldn't easily because of the boost/preprocessor
macro use. However, since your earlier post said it was a "flat"
structure, I assumed the fusion tuple has instance variables:

   T0 my_0; T1 my_1; ... Tn my_n;

generated by macros, and that access methods were generated similarly,
i.e. a get<I,tuple> general template and a preprocessor generator of
specializations. OOPS, that means the tuple size would have to be
available for the preprocessor. So, I looked at tuple.hpp then at
tuple_builder.hpp, then at get_tuple_n<n> ... then I gave up :(

> The fusion design was carefully refined for both runtime and
> compile-time speed. It is a complete hybrid compile-time/runtime
> framework just like the MPL is a complete compile-time framework,
> and it integrates well with MPL (every fusion sequence is also an
> MPL sequence).

This is probably one place where indexed_types break down wrt MPL
because I didn't consider making each product an MPL sequence.

> This wasn't just done lightly; it's the result of a careful and
> comprehensive design process.

As I and everyone else expected. Could you remember or have a record
of the reason's why the non-flat structure and use of indexed
supertypes was less than optimal?

>>I'm guessing that the "flatness" of fusion tuples is done by
>>simply creating different field names with corresponding types
>>by means of preprocessing macros.
> Understanding the implementation of fusion isn't important, except to
> its maintainer.

It might more easily reveal the reasons why the flat implementation is
more optimal than ae non-flat one.

>>However, in addition, if variant (i.e. sum) is thrown onto the
>>scales, then I believe easier undestanding wins.

> Maybe you're not the best judge of easy understanding.

I completely agree. I believe it's pretty typical that the coder
initially believes his code is easier to understand than reviewers
would say.

However, I'd guess that one attempting to understand product would
simply look at the project<Index> code, then at the factor<,, Index>
superclass to find my_field of type TypeMap<Index>::type and
understand product. OTOH, as reflected in my previous response
terminated with :( , understanding how tuple accessed the selected
fields seemed much harder, at least to me. Maybe you could give a
brief description of the thought process you went through in
understanding product.

> What does variant have to do with sum? It's completely non-obvious
> to me.

Well, maybe that's part of the problem. Are you assuming sum has
something to do with numbers. I'd meant it to mean disjoint sum
applied to types, and of course variant does model disjoint sum. Is
that the reason for the disconnect (of our mutual understanding) ?

>>In addition, I think sum can be modified by adding:
>> term<...Index>::accept(visitor&a_viz)
>> {
>> if(index() == Index)
>> { a_viz(mpl::int_c<Index>(), project<Index>());}
>> else
>> { term<...,Index-1>::accept(a_viz);}
>> }
>>which is essentially the visitor pattern.
> You've lost me completely.

Well, I had assumed you'd looked at sum.hpp and could see that
term<...Index> was one of the sum superclass's representing the
Index-th possible type of the disjoint sum. The accept corresponds to
the concrete version of the virtual accept in the Element participant
in the visitor pattern. However, there is a typo above which
contributed to the confusion, I'm sure. The line:

       { a_viz(mpl::int_c<Index>(), project<Index>());}

should really be:

       { a_viz.visit(mpl::int_c<Index>(), project<Index>());}

i.e. the Visitor participant visits the concrete element by using it's
visit member function tailored to the concrete Element type argument,
which is supplied by the concrete Elements accept method. IOW, The
abstract Element participant corresponds to the sum in sum.hpp. The
ConcreateElement participants correspond to the various "terms" in the
disjoint sum and

I got a working version now. I'll upload to sand-box if you'd think
that might help.

>>What I'm also searching for is something that satisfies:
>> list<T> == sum<null_type, product<T,list<T>*>
>>like or similar to the way the disjoint sum and cartesion
>>product are used in textbooks to define a linked list.
> still lost.

I was trying to convey something similar to the line:



where Unit corresponds null_type (i.e. void* AFAICT ) and + is
disjoint sum operator and * is the cartesian product operator.



Boost list run by bdawes at, gregod at, cpdaniel at, john at