Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-02-10 09:08:08


David Abrahams wrote:
> "Peter Dimov" <pdimov_at_[hidden]> writes:
>
>> I am not saying that this is never useful, but syntax should target
>> the typical scenario, not corner cases.
>
> Agreed. I suppose that you'll say it doesn't target the typical
> scenario because of its confusability. I wouldn't argue. Any other
> reasons?
>
> What about:
>
> result(f)

Unqualified? ;-)

>> It makes a lot more sense (to me) to reserve operator() for the
>> Runnable concept, since that's what Boost.Threads currently uses.
>
> And prevent any other concepts from using operator()? Surely you
> don't mean that.

No, I meant in that particular case.

We have three concepts: Runnable, Executor (executes Runnables), and
HasResult (for lack of a better name.) The AsyncCall concept I had in mind
is both Runnable and HasResult, so it can't use operator() for both.
x.result() or result(x) are both fine for HasResult.

Here's some compilable code, to put things in perspective:

#include <boost/detail/lightweight_mutex.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <stdexcept>
#include <string>
#include <iostream>

template<class R> class async_call
{
public:

    template<class F> explicit async_call(F f): f_(f), ready_(false)
    {
    }

    void operator()()
    {
        mutex_type::scoped_lock lock(mutex_);
        new(result_) R(f_());
        ready_ = true;
    }

    R result() const
    {
        mutex_type::scoped_lock lock(mutex_);
        if(ready_) return reinterpret_cast<R const &>(result_);
        throw std::logic_error("async_call not completed");
    }

private:

    typedef boost::detail::lightweight_mutex mutex_type;

    mutable mutex_type mutex_;
    boost::function<R ()> f_;
    char result_[sizeof(R)];
    bool ready_;
};

int f(int x)
{
    return x * 2;
}

int main()
{
    // step 1: construct an async_call
    async_call<int> call( boost::bind(f, 3) );

    // 1a: attempt to obtain result before execution
    try
    {
        std::cout << call.result() << std::endl;
    }
    catch(std::exception const & x)
    {
        std::cout << x.what() << std::endl;
    }

    // step 2: execute an async_call
    call();

    // step 3: obtain result
    try
    {
        std::cout << call.result() << std::endl;
    }
    catch(std::exception const & x)
    {
        std::cout << x.what() << std::endl;
    }
}


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