Boost logo

Boost :

From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2008-05-31 11:56:17


vicente.botet wrote:

> > This reminds me of a discussion we had some time ago, namely
> overloading
> > operator&&() for futures allowing to achieve the same thing: waiting
> for all of the futures:
> >
> > future<int> f1;
> > future<double> f2;
> > future<fusion::vector<int, double> > f3 (f1 && f2);
> >
> > fusion::vector<int, double> result = f3.get(); // waits for f1
> and f2
> >
> > Similarly, overloading operator|| would allow to wait for the first
> future to finish only:
> >
> > future<int> f1;
> > future<double> f2;
> > future<variant<int, double> > f3 (f1 || f2);
> >
> > variant<int, double> result = f3.get(); // waits for first, f1
> or f2
>
> I think that the problem with the operator is not its implementation,
> but
> its definition. Your proposal seams natural for && and for || when the
> types are different. But when we have comon types things start to be
> more
> complicated for operator ||. When all are differents we can know via
> the type which future has finished the first. This information is lost
> otherwise.

Valid point. But this information can be retained easily by returning a pair
from the composed future (see below). The types in the list have to be
collapsed, for sure.

> Which type will have (f1 || f2) if
> future<string> f1;
> future<string> f2;
>
> If we don't mind which future has finished, future<string> should be
> good (does variant<string, string> work in this case?).

variant<string, string> will compile, but obviously doesn't make any sense.
If all future return types are identical the variant can be dropped
completely.

> If we mind a future<pair<unsigned, string> > . The first component give
> the index, and the second the result.
>
> The problem is that this do not scale to more that 2 futures. Which
> type will have (f1 || f2|| f3) if
> future<string> f1;
> future<string> f2;
> future<int> f3;
>
> future<variant<string, int> > f3 (f1 || f2 || f3);
> or future<pair<unsigned, <variant<string, int> > > f3 (f1 || f2 || f3);

I'ld suggest to use the latter one. The unsigned for the index of the
finished future and the variant holding all different possible return types
(or just the return type if all types are identical):

future<string> f1, f2;
future<int> f3;
future<pair<unsigned, variant<string, int> > > f4 (f1 || f2 || f3);
 
and

future<string> f1, f2, f3;
future<pair<unsigned, string> > f4 (f1 || f2 || f3);

which scales well for arbitrary numbers of parameters. Which shows another
advantage of this syntax: you don't have to provide N overloads for
wait_all/wait_any for N possible parameters, but only 2 or 3.

Regards Hartmut


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