Boost logo

Boost :

From: Joel de Guzman (joel_at_[hidden])
Date: 2008-07-15 06:49:12


Stjepan Rajko wrote:
> Hello,
>
> I recently ran into a need to initialize a fusion vector with a single
> argument which is then used to construct all of the vector elements.
> For example, something that would allow:
>
> fusion::vector<int, float, double> ones(initialize_all_with(),1);
>
> // at_c<0>(ones) == 1
> // at_c<1>(ones) == 1.0f
> // at_c<2>(ones) == 1.0;
>
> I hacked fusion::vector so that the above works. Is this addition of
> interest to anyone else?

Definitely. I'm not sure about the interface though. It seems
there could be a more generic "lazy-construction" scheme that
can have a more general appeal.

After thinking about it, we don't even have to do anything
-- fusion already supports it, but we haven't taken advantage
of it yet.

As you know, *all* fusion containers can be initialized
from arbitrary fusion sequences. For example:

     vector<int, double> v(std::pair<char, short>(1, 2));

schematically:

     C c(s);

where C is a fusion container, s in a fusion sequence.

Now...

If we have a /lazy-sequence/ s, that generates the ones for you,
then you can use that for s:

     vector<int, float, double> ones(all_ones);

all_ones is a lazy-sequence. It generates the ones every time
the iterator is dereferenced.

A nice strategy is to write a function adaptor that creates
a fusion sequence. Example:

     int one() {return 1}

...

     vector<int, float, double> ones(fusion::make_lazy_sequence(&one));

make_lazy_sequence can take in a function pointer or a function
object -anything callable. It simply calls /one/ each time its
iterator is dereferenced.

> There is another (perhaps more elegant) solution in implementing a new
> fusion "array" Sequence (one where all element types are identical)
> which can construct all elements from a single constructor argument,
> and then using that sequence to do the above initialization. E.g.,
>
> fusion::vector<int, float, double> ones(fusion::array<int, 3>(1));
>
> ... or (another solution) a make_array function that returns a fusion::vector:
>
> fusion::vector<int, float, double> ones(fusion::make_array<3>(1));
>
> It would be great if one of these solutions (or a different solution)
> were added to fusion. I can take a stab at putting something together,
> if any of them are acceptable. That is, unless this is already
> possible in some way that I can't see at the moment :-)

How about hacking on the /lazy_sequence/ idea? Thoughts?

Regards,

-- 
Joel de Guzman
http://www.boostpro.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